Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

socket.io switching namespaces

I am currently working on a simple chat with socket.io. The basics are already working , but now I am trying to implement 2 different namespaces. I want the client to be able to toggle from one namespace (support-chat) to the other (friends-chat) by a buttonclick.

Serverside

//default namespace
io.on('connection', function(socket){
    console.log('a user connected to the chat');

    socket.on('disconnect', function(){
        console.log('user disconnected');
    });

    socket.on('client message', function(msg){
        io.emit('server_message', msg);
    });
});

//namespace /support
var sup = io.of('/support');
sup.on('connection', function(socket){
    console.log('someone entered the support-chat');

    socket.on('disconnect', function(){
        console.log('user disconnected from support-chat');
    });

    //recieving and emitting message to all clients in namespace /support
    socket.on('client message', function(msg){
        console.log('message received: ' + msg);
        io.of('/support').emit('server_message', msg);
    });
});

//namespace /friends
var frnd = io.of('/friends');
frnd.on('connection', function(socket){
    console.log('someone entered the friends-chat');

    socket.on('disconnect', function(){
        console.log('user disconnected from friends-chat');
    });

    //recieving and emitting message to all clients in namespace /friends
    socket.on('client message', function(msg){
        console.log('message received: ' + msg);
        io.of('/friends').emit('server_message', msg);
    });
});

Clientside

var socket = io.connect();
//toggle namespace
            $("#support_button").click(function(){
                socket.disconnect();
                socket = io('/support');
                $('#messages').append($('<li>').text("You entered the Support-Chat"));
            });
//toggle namespace
            $("#friends_button").click(function(){
                socket.disconnect();
                socket = io('/friends');
                $('#messages').append($('<li>').text("You entered the Friends-Chat"));
            });
//sending message on submit
            $('form').submit(function(){
                socket.emit('client message', $('#m').val());
                $('#m').val('');
                return false;
            });
//recieving message and display
            socket.on('server_message', function(msg){
                $('#messages').append($('<li>').text(msg));
            });
        });

I think the switch itself is working, because the connection- and disconnect-events are triggering like they should. But when it comes to emitting the message (the server already recieved from the client) to everyone in the same namespace, it is not working.

Isnt this the serversided call for emitting in a specific namespace?:

io.of('namespace').emit();

Do I misunderstand the usage of namespaces? I wanted to implement rooms right after the namespace-"split" of the 2 mainchats for support and friends. Or did I implement the namespaces wrong on the serverside? I thought io.on(..), io.of('/support').on(..) and io.of('/friends').on(..) are all working the same way and catch the events of their own namespaces-clients.

Any help is highly appreciated! I feel like namespaces have been kind of neglected in there "basic-usage" documentations.

like image 608
ExaMa Avatar asked Dec 19 '22 02:12

ExaMa


1 Answers

You can't "switch" namespaces on an existing connection. You connect to a specific namespace when the connection is made and once made, it can't be changed.

You could drop the current connection and connect to a new namespace with a new connection. But, given your application, you're misusing the concept of namespaces if you want to switch namespaces and should be using rooms instead.

For rooms, the client can send the server a request to switch rooms and the server can then remove the user from an existing room and add them to a new room. Then, from the server, you can easily broadcast to all connections in a given room.

In fact, rooms were invented around the concept of chat (though they have many other uses) so they are perfectly suited for the chat rooms that you wish to implement.

Namespaces are a heavier weight division than rooms. A connection must connect to a specific namespace when the connection is made and that cannot be changed during the connection.

Rooms on the other hand are a lot more flexible. The server can put a given connection add or remove a connection from a room at any time and a connection can even be in more than one room.

Both rooms and namespaces support broadcasting to all users in that collection.

I think of namespaces more like channels of functionality. So, I'd like to connect to the "price" change namespace in order to get notifications of price changes or I'd connect to the "system" namespace in order to get alerts about things happening in the system or to send messages to manage things in the system.

Whereas rooms are arbitrary collections of users interested in sharing information and I may be in more than one room.

like image 81
jfriend00 Avatar answered Dec 20 '22 18:12

jfriend00