Socket.io 切换命名空间

4

我目前正在使用socket.io开发一个简单的聊天应用程序。基础功能已经实现,但现在我正在尝试实现两个不同的命名空间。我希望客户端能够通过点击按钮从一个命名空间(support-chat)切换到另一个命名空间(friends-chat)。

服务端

//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);
    });
});

客户端

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));
            });
        });

我认为交换机本身是正常工作的,因为连接和断开事件按照预期触发。但是当涉及到向同一命名空间中的每个人发出客户端已经接收到的消息时,它就不起作用了。
这难道不是在特定命名空间中发射的服务器端调用吗?
io.of('namespace').emit();

我是否误解了命名空间的用法?我想在支持和朋友的两个主要聊天室的命名空间“分离”之后立即实现房间。 或者我在服务器端实现命名空间时是否出错了?我认为io.on(..),io.of('/support')。on(..)和io.of('/friends')。on(..)都以相同的方式工作,并捕获其自己命名空间客户端的事件。
非常感谢任何帮助!我觉得命名空间在其“基本用法”文档中被忽视了。
1个回答

12
你无法在现有连接上“切换”命名空间。连接建立时需要连接到特定的命名空间,一旦建立,就无法更改。如果要更改命名空间,则可以断开当前连接并通过新连接连接到新的命名空间。但是,根据您的应用程序,如果您想要切换命名空间,则误用了命名空间的概念,应该使用房间代替。
对于房间,客户端可以向服务器发送请求以切换房间,然后服务器可以将用户从现有房间中删除并添加到新房间中。然后,从服务器端,您可以轻松地向给定房间中的所有连接广播消息。实际上,房间是围绕聊天概念发明的(尽管它们有许多其他用途),因此它们非常适合您希望实现的聊天室。
与房间相比,命名空间是一种更重量级的部分。连接建立时必须连接到特定的命名空间,并且在连接期间无法更改。
另一方面,房间更加灵活。服务器可以随时将给定连接添加或从房间中删除,并且一个连接甚至可以在多个房间中。
房间和命名空间都支持向该集合中的所有用户广播消息。
我认为命名空间更像是功能通道。因此,我想连接到“价格”更改命名空间以获取价格更改的通知,或者我将连接到“系统”命名空间以获取有关发生在系统中的事情的警报或发送消息以管理系统中的事物。
而房间则是有兴趣共享信息的用户的任意集合,我可能会在多个房间中。

这是一个很棒的答案,正是我需要知道的!非常感谢! - ExaMa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接