Someone posted something very similar to the following code on a thread about resources that I can no longer locate:
$scope.logout = function(){
var outRes = $resource("/admin/logout");
outRes.save({},
function () {
$scope.userObject.lastActivity_type = "Log out";
$rootScope.isLoggedIn = false;
$location.path("/login-register");
},
function errorHandling(err) {
console.log("Not cool, error");
});
}
It was super helpful for me on my assignment and seemed fairly recent so I was hoping to ask: could someone explain how to rewrite this with a broadcast method to let other users/every part of architecture know a user has logged out? The assignment's over and everything, I'm just curious
Assuming this is for Angular 1, broadcasting an event makes it visible to all child scopes of the scope in which it is broadcast. If you want it to be visible to all scopes, you should broadcast it in the root scope, as in this example:
$rootScope.broadcast('my-event');
Documentation is here if you want some more information.
EDIT: I note that you also asked about broadcasting to other users. That's a very different kettle of fish!
Angular is purely a front-end framework so it can't broadcast a message to another client. If you wanted something like a chat or notification system whereby users received notification of changes made by other users in real time, you'd probably want to use websockets via a library like Socket.io. You'd send some kind of notification to the server, either via websockets or an AJAX request, and then on the server that would trigger broadcasting the message to those connected clients that should receive it. You can then use the method described above to trigger a corresponding event in the root scope of your Angular code. I won't go into the details for this as there's loads of tutorials on doing this with Socket.io.
Related
So ive been looking for a way to integrate webRTC into a site im making, but i want to do it on shared hosting. I came across this repo on GitHub by nielsbaloe and it has been a huge help in getting a basic connection.
This is the code i believe is responsible for adding the peer: ( index.html in the repo, line )
function icecandidate(localStream) {
pc = new RTCPeerConnection(configuration);
pc.onicecandidate = function (event) {
if (event.candidate) {
publish('client-candidate', event.candidate);
}
};
try {
pc.addStream(localStream);
}catch(e){
var tracks = localStream.getTracks();
for(var i=0;i<tracks.length;i++){
pc.addTrack(tracks[i], localStream);
}
}
pc.ontrack = function (e) {
document.getElementById('remoteVideo').style.display="block";
document.getElementById('localVideo').style.display="none";
remoteVideo.srcObject = e.streams[0];
};
}
Now the struggle im facing is adding room functionality, and maybe the ability to have more than two concurrent peers present at the same time. I did some experimenting, but in vain. I know that for room functionality id have to tinker around in the php, so at least id like to figure out how to make more than 1 peer possible.
As far as I know, there is no way to re-use the same RTCPeerConnection for multiple peers, so you'll have to do the same thing as 1-on-1 but between every single peerĀ in a group.
As far as signalling, it's pretty simple, goes kind of like this:
Client A -> [Offer] -> Server -> [Offer] -> Client B -> [Answer] -> Server -> [Answer] -> Client A
A nicer explanation at MDN
There isn't necessarily a need for NodeJS or WebSocket. The reason most people go for it it is because the last link in this chain (Server -> Client A) requires server-initiated connection. But that can be substituted with alternative techniques such as (long-)polling. Or, in case of PHP, you might use websocket implementations such as Bloatless or Aerys
To implement the room functionality, you'll have to implement the following:
Variant A (using polling):
An endpoint to throw offers at, e.g. POST /rooms/{id}
An endpoint to regularly check for new offers from, e.g. GET /rooms/{id}
Variant B (with websockets)
Create a broadcast rooms, for example, by dynamically creating HTTP endpoints and websocket server instances. Or by having a single websocket instance but sending whatever room you're intending to join right inside after establishing a connection. From there, it's only a matter of sending correct offers and answers to correct users.
In both cases, you might want to either create multiple offers in advance to pool from the server, or to dynamically create new ones, but, most importantly, make sure you're not connecting the same peers twice, otherwise you will end up with a loop. To prevent it, just provide each user with a randomly generated string to identify themself and send it among offers.
There are turnkey solutions available if you don't want to go this route, but be careful and check whether you can use your own TURN servers with them. A common trend I have noticed is that there are a lot of WebRTC solution providers out there that lure you with their simplicity but then lock you in with their own TURN servers for which you might have to pay a quite hefty bill later on.
I want to integrate a simple notification system in my react application. I want to notify for example:
- new post (when the user post the system need time to transcode the media attached and the publication)
- missing settings (the user need to compile some information)
- interesting posts etc..
There is a simple way to add a websocket, like socket.io, to a reactjs app with an aws lambda backend?
All the notification not need to be read in real time, maybe an ajax call every 2 minutes can solve my problem, but, in this case, someone can help me avoid ajax call if the app isn't used(like if the app remain opened in a foreground tab...)
componentDidMount() {
this.liveUpdate()
setInterval(this.liveUpdate, 120000);
}
liveUpdate() {
axios.get(endpoint.posts+'/live/', cfg)
.then(res => {
// ...
});
}
This code is in the footer component, the call happen every 120 seconds, but the call will still happen also if a user leave the application opened in the browser and not use it, this on a lambda backend mean a waste of money.
There are 3 main ways of notifying that I can think of at the moment...
Long polling (using ajax etc)
Websocket
Push Notification
Push (though) requires permission from the user
I am trying to set up a simple presentation using three computers synchronized by a central server, and I figured node would be the ideal tool.
I was wondering if there's any way to have all three computers connect to the server via the browser, and if I could control the server to push changes to each?
For example:
Computer-1 visits 10.0.0.1?comp=1?slide=1
Computer-2 visits 10.0.0.1?comp=2?slide=1
Computer-3 visits 10.0.0.1?comp=3?slide=1
Then from the server commandline, I would like to be able to trigger a change so the clients will each be redirected accordingly like so:
Computer-1 visits 10.0.0.1?comp=1?slide=2
Computer-2 visits 10.0.0.1?comp=2?slide=2
Computer-3 visits 10.0.0.1?comp=3?slide=2
I'm new to node, so I'm not even sure if this is the ideal platform, but was wondering what terminology I should be researching to be able to build something like this?
Thank you for your responses, I ended up looking into socket.io and managed to write this system in one evening! Node + socket.io and express is a pretty amazing tool with the socket emit events.
Thank you for pointing me in the right direction, this is exactly the tool I was looking for.
Just in case it may help anyone, in my client/jade template, I have something like:
socket.on('slideUpdate', function (data) {
// Do things with the data
}
and on the server app.js:
io.on('connection', function (socket) {
socket.on('slideChange', function (data) {
// logic for setting slide data
io.sockets.emit('slideUpdate', { example: exampleData ... });
});
});
where a slideChange event is triggered via a button on the client-side template.
For such a presentation I would use the most simple solution, i.e. not websockets, not server-sent events and not long-polling.
Just do a short poll, i.e. every client calls the server every 100ms for updates. The server then responds with a status update (if there is one).
I'm building a simple real-time chat app to learn how to use websockets with RoR and I don't think I'm understanding how channels work because they're not doing what I expect. I can successfully send a message to my Rails app using the dispatcher.trigger() method, and use my websocket controller to broadcast a message to all clients that subscribe to the channel. That all works fine. What does NOT work is using a channel (via the channel.trigger() method) to send a message to other clients. The websocket-rails wiki says...
Channel events currently happen outside of the Event Router flow. They
are meant for broadcasting events to a group of connected clients
simultaneously. If you wish to handle events with actions on the
server, trigger the event on the main dispatcher and specify which
controller action should handle it using the Event Router.
If I understand this correctly, I should be able to user the channel.trigger() method to broadcast a message to clients connected to the channel, without the message being routed through my RoR app, but it should still reach the other connected clients. So here's my code...
var dispatcher = new WebSocketRails('localhost:3000/websocket');
var channel = dispatcher.subscribe('channel_name');
channel.bind('channel_message', function(data) {
alert(data.message);
});
$("#send_message_button").click(function() {
obj = {message: "test"};
channel.trigger('channel_message', obj);
});
With the code listed above, I would expect that when I click the button, it sends a channel message using channel.trigger() and the channel_message binding should be executed on all clients, displaying an alert that reads "test". That doesn't happen. I'm using Chrome tools to inspect the websocket traffic and it shows the message being sent...
["channel_message",{"id":113458,"channel":'channel_name',"data":{"message":"test"},"token":"96fd4f51-6321-4309-941f-38110635f86f"}]
...but no message is received. My questions are...
Am I misunderstanding how channel-based websockets work with the websocket-rails gem?
If not, what am I doing wrong?
Thanks in advance for all your wisdom!
I was able to reproduce a working copy based on an off-the-shelf solution from the wiki along with your very own code.
I've packaged the whole thing here. The files you might be interested are home_controller.rb, application.js and home/index.html.erb.
It seems your understanding of channel-based websockets is correct. About the code, make sure to load the websocket javascript files and to enclose your code inside a document.ready. I had the exact same problem you're having without the latter.
//= require websocket_rails/main
$(function() {
// your code here...
});
Let me know if it works. Best Luck!
I have a Geddy app that has some realtime models (I remember using -rt to generate some models), and I'd like to revisit the realtime-ness of my Geddy app.
I don't need my models to be updated automatically (I'm not sharing models with the client; I am using Geddy only as a REST backend)
But I would like to explicitly emit events through socket.io and use its room functionality in my controllers, and I'll handle those events in the client side appropriately.
So, my questions are: 1. how do I clean up my existing code in that I don't want realtime models in my app 2. what would I need to do in order to explicitly events from my controllers?
I tried doing the following in after_start.js as shown here: https://github.com/geddy/geddy/wiki/Realtime-and-MVC in "Realtime for existing projects" section, but none of the messages get logged...
console.log('Here 1');
geddy.io.sockets.on('connection', function(socket) {
console.log('Here 2');
socket.emit('hello', {message: "world"});
socket.on('message', function(message) {
console.log('Message!');
});
});
Any help is much appreciated. Thanks!
Just found out that the after_start.js was a workaround for the lack of events from the application to know when the server had actually started (so you would know when you could attach Socket.io). Now the geddy object in the worker process emits a 'started' event you can use:
http://geddyjs.org/reference#global
So set a listener in your init.js for that event, and set your RT code up in there.