Reputation: 19278
I want to create rooms dynamically (based on what request comes in from the front end). I followed this gist.
I want a particular room to listen for events and broadcast out to the other members in the room. I'm not sure why the following code isn't doing that. In particular, why the second log statement never happens.
io.sockets.on('connection', function (socket) {
socket.on('joinRoom', function (roomName) {
socket.join(roomName, function () {
console.log('joined ' + roomName); // logs properly
io.sockets.in(roomName).on('setVideoOnServer', function (inputUrl) {
console.log('setVideoOnServer: ', inputUrl); // not hitting here
io.sockets.in(roomName).emit('setVideoOnClient', inputUrl); // broadcast instead
});
});
});
});
Upvotes: 0
Views: 832
Reputation: 708126
Per my comment, I don't think io.sockets.in(roomName).on(...)
does what you think it does.
io.sockets.in()
returns a Namespace
object that derives from eventEmitter
. There's no override for .on()
in the namespace object so all you're doing is adding a listener to the namespace object itself, not to any given socket or group of sockets (as best as I can tell by looking at the socket.io code).
There is an override for .emit()
in the Namespace object which is why io.sockets.in(xxx).emit(...)
works.
FYI, code for the namespace object is here: https://github.com/socketio/socket.io/blob/master/lib/namespace.js
And, even if it did what you thought, you'd be adding duplicate event handlers every time a new socket joined that room which would also probably be a problem since you'd be re-adding an event listener for every socket already in a room every time somebody new joined the room.
I think you can accomplish what you want with this:
io.sockets.on('connection', function (socket) {
socket.on('joinRoom', function (roomName) {
socket.join(roomName, function () {
console.log('joined ' + roomName); // logs properly
socket.on('setVideoOnServer', function (inputUrl) {
console.log('setVideoOnServer: ', inputUrl); // not hitting here
io.sockets.in(roomName).emit('setVideoOnClient', inputUrl); // broadcast instead
});
});
});
});
Each time a socket is joined to the room, it will get registered for the setVideoOnServer
event. So, all sockets in a room will be registered for that event.
Note: If you are ever joining a socket to multiple rooms, you will need to make sure this is doing what you want because you will be setting multiple listeners for the setVideoOnServer
event, each of which will broadcast setVideoOnClient
to all the other sockets.
And, if you ever leave this room, you will have to remove the event listener too.
Upvotes: 1