socket.io emit to everyone except for some certain clients - javascript

In my Node.js server, I have an array of client IDs, and I have a socket that I want to send to all connected clients except for the clients I have in that array, so I want to emit to all clients excluding some clients that i have defined by id, is that possible?

Answering my own question after some research.
One thing you could do is to add the clients you want to exclude inside of a Scoket.io room and then emit to everyone except for that room, like shown below:
io.except("room1").emit(/* ... */); // to all clients except the ones in "room1"
Note that this feature was implemented in version socket.io#4.0.0.
here is documentation for it

Related

statusCallback in twilio not firing

I am creating a twilio video room using the rest api and setting up a statusCallback:
classroomRouter.route('/room/:id')
.get(function (req, res) {
client.video.rooms
.create({
uniqueName: req.params.id,
statusCallback: 'localhost:3000/classrooms/listen'
})
.then(function (room) {
console.log('room.sid');
console.log(room.sid);
});
});
Twilio will be sending requests to the statusCallback whenever an event happens in the room right? To the best of my knowledge, refreshing the window on which the room is rendered constitutes a participantdisconnected and participantConnected event.
But the route I setup(localhost:3000/classrooms/listen) didnt recieve any requests when i refreshed the window. Why is this?
I have a few other queries too:
Q1: Can two rooms have the same uniqueName?
(The twilio docs say that you can query a list of rooms using their uniquename. If the names are unique, how can it be a 'list' of rooms?)
Q2: If the names are indeed unique, what happens if a room already exists with uniquename I provide? Will it return the already existing room?
Q3: How can I issue this command only if the room doesnt exist?
Twilio developer evangelist here.
Twilio can't reach localhost:3000 on your machine as that is not a public address. When developing Twilio apps, we recommend you use a tool like ngrok that can tunnel into your machine and expose your application. I wrote a blog post up a while back on why I like using ngrok.
Q1: Can two rooms have the same uniqueName? (The twilio docs say that
you can query a list of rooms using their uniquename. If the names are
unique, how can it be a 'list' of rooms?)
Two rooms cannot have the same uniqueName. If you filter a list response by uniqueName then you will still get a list returned, it will just contain one room.
Q2: If the names are indeed unique, what happens if a room already
exists with uniquename I provide? Will it return the already existing
room?
If you are creating a room with a uniqueName that already exists, you will receive an error which you should handle with a catch function on your Promise.
Q3: How can I issue this command only if the room doesnt exist?
You could query the API for the room by the uniqueName first, and then decide to create it based on whether you get a response. Or you can catch the error after you try to create it and handle it that way instead.

Cyclical reference in chat program

I wrote a chat program in Node.js. The server manages a list of rooms in a class called RoomManager with an object this.rooms. Whenever a command is sent to the server from a client, it goes into a router. Most of the commands deal with rooms (sending messages to rooms, joining rooms, creating rooms..). The command message must always have a room ID in it. The server must always try and find the room first:
roomManagerGetRoom(roomName){
return this.rooms[roomName] || null;
}
Since the rooms object will eventually get large, I figured the clients should keep their own references to what rooms they are in. That way, the server could first try and find the room from the client's own list which would be much smaller, 1-4 rooms on average.
However, this creates a cyclical loop
RoomManager requies Room requires ClientManager requires Client requires RoomManager requies Room requires ClientManager requires Client ...
So 1.5 questions:
How much speed would I be gaining by first looking through Client's own list?
If it's significant, how do I avoid the cyclical issue?

socket.io without using default namespace/room feature

I found it's easier to just setup own custom path for multiple endpoints like this
server side:
io.on('connection', function(client) {
var username = client.handshake.headers.users[0].username;
client.on(username+'_con1', function(data) {
io.emit(username+'_con1',data);
});
client.on(username+'_con2', function(data) {
io.emit(username+'_con2',data);
});
}
Is above approach correct? at least I'm able to make it work.
Depending on what you mean by correct. This will create multiple events for the client.
Its hard to say if this is the best/correct way without any context. But you should look into namespaces and rooms and decide for yourself! http://socket.io/docs/rooms-and-namespaces/
Creating unique message names for each client makes it seem like you plan on sending a message to all clients and only some clients will be listening for the message directed at them. This is not a very efficient way to do things.
Rooms in socket.io are designed such that you can have a common message name (no need for a unique message name for each client) and then send that message only to the clients that it is intended for. That's a lot more efficient scheme.
Now, of course, you could create the unique message name for each client and then only send it to the desired client, but why bother with the extra complication of the unique message name. You don't need it if you're only sending the message to the intended client.
So, you could certainly make your scheme work, but it does not seem like it's the simplest way to do things and, depending upon other details of your implementation, it may not be the most efficient way to do things either.
A namespace is more like connecting to a particular channel. The client decides what channel they want to connect to. The server then decides which namespace to send a given message to.
A room is a something a server subscribes a client to in order to make it easy to send a specific set of clients the same messages or in some cases to share incoming messages from one client with all the other clients in a room (like in chat).

Changing a Meteor collection subscription for all clients

I am developing a webapp in which I'd need one client, associated with the admin, to trigger an event (e.g., a new value selected in a dropdown list) which in turns will tell all the other connected clients to change the subscription, possibly using a parameter, i.e., the new selected value.
Something along the lines of
Template.bid.events
"change .roles": (e, tpl) ->
e.preventDefault()
role = tpl.$("select[name='role']").val()
Meteor.subscribe role
Of course this works for the current client only.
One way I thought would be keeping a separate collection that points a the current collection to be used, so the clients can programmatically act on that. It feels cumbersome, thou.
Is there a Meteor-way to achieve this?
Thanks
In meteor, whenever you have a problem that sounds like: "I need to synchronize data across clients", you should use a collection. I realize it seems like overkill just to send one piece of data, but I assure you it's currently the path of least resistance.
There are ways you can expose pseudo-collections which don't actually write to mongo, but for your use case that really sounds like overkill - new Mongo.Collection is the way to go.
You can use streams to setup a simple line of communication between connected clients and the server. It doesn't store data in MongoDB. Just let all connected clients listen to a stream and switch subscriptions when a new message comes in with the subscription name. Make sure only your client associated to your admin can push messages to the stream.
Available package: https://atmospherejs.com/lepozepo/streams
Examples: http://arunoda.github.io/meteor-streams/

Run different instances in nowjs

I create a server using nowjs. How can I serve clients grouped under an URL.
It's a wague way of putting the question. I ll give an example.
I run my server(with nowjs) in mysite.com which contains many chat rooms.
Users can join one of the chat rooms and start chatting. Real time sync happens - all handled by nowjs.
Now coming to my problem, I'm not able to differentiate between the chat rooms. Whatever chatroom user joins, since I'm using the everyone object, every user gets a message (independent of which chat room he is in).
use a group object.
I solved this issue by using
everyone.now.distributeMessage = function(message,groupname){
group = nowjs.getGroup(groupname);
group.now.receiveMessage(this.now.name, message, groupname);
}
everyone has access to that function, and by passing the groupname, only those who are members of that group get the message.

Categories

Resources