【问题标题】:Socket.IO room featureSocket.IO 房间功能
【发布时间】:2011-12-02 16:49:06
【问题描述】:

我有两个单独的文件,一个是服务器端 JS。

另一种是动态生成的客户端PHP。

这两个文件可以通过 Socket.IO 成功地相互通信。

我知道我可以使用 .of() 来限制命名空间,但不能使用

处理动态创建的聊天室。

所以我决定两个都用

.of('/chat') 

房间特色

.join('room name') 

我可以找到服务器端示例,但找不到客户端示例。

下面是来自Socket.IO github的唯一给定的服务器端代码sn-p

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
    socket.join('justin bieber fans');
    socket.broadcast.to('justin bieber fans').emit('new fan');
    io.sockets.in('rammstein fans').emit('new non-fan');
});

1) 我无法理解以下部分。

socket.broadcast.to('justin bieber fans').emit('new fan');
io.sockets.in('rammstein fans').emit('new non-fan');

这两者有什么区别?

2) 为什么不使用

socket.to('room name').emit('event')

而不是

io.sockets.in('room name').emit('new non-fan');

3) 最后,我找到了一些使用的文档

.send()

而不是

.emit()

有点 .send() 对我不起作用,我想知道这两者之间的区别。

谢谢,对于关于 Socket.IO 的多个问题,我深表歉意。

【问题讨论】:

  • 一个很好的问题,显示了 socket.io 文档的糟糕状态。

标签: node.js socket.io


【解决方案1】:

1)-

i) io.sockets.in().emit():它向 x 房间中的所有人发出/分派自定义事件。例如;

/* Send message to the room1. It broadcasts the data to all 
   the socket clients which are connected to the room1 */

io.sockets.in('room1').emit('function', {foo:bar
});

ii) socket.broadcast.to().emit():我向除 x 房间中的发件人之外的所有人发出/分派自定义事件。例如;

io.sockets.on('connection', function (socket) {
    socket.on('function', function(data){

        /* Broadcast to room1 except the sender. In other word, 
            It broadcast all the socket clients which are connected 
            to the room1 except the sender */
        socket.broadcast.to('room1').emit('function', {foo:bar});

    }
}

2)- 第一个,您向单个客户端(套接字一)发出/分派自定义事件。 第二个,您向 x 房间中的所有客户端发出/分派自定义事件。

3)- emit() 和 send() 的区别;

socket.emit(): 是一个函数,它向您想要的任何客户发出/分派带有数据的自定义事件。 socket.emit() 至少需要两个参数,第一个是自定义事件名称,第二个是您要传递的数据,依此类推。例如;

socket.emit('addUser',{nickname:'John'});

您可能需要使用 socket.on() 注册和监听这个自定义事件。例如:

socket.on('addUser',function(data){
    console.log(data.nickname); // it will return 'John'
}

socket.send(): 与 socket.emit() 几乎相同,只是这次它使用默认事件名称“消息”。所以它只需要一个参数,你想要传递的数据。例如:

socket.send('hi');

而这一次你注册并监听'message'事件名称;

socket.on('message', function (data) {
  console.log(data);  // it will return 'hi'
})

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    我已经很久没用过Socket.IO了,但是

    1.) 正如文档所述:“广播意味着向除启动它的套接字之外的其他所有人发送消息。” 在搜索了 Socket.IO 代码之后,您可以查看 /lib/socket.js 中的 Socket.prototye.packet。

    当您第一次打电话时,您将用户设置到“贾斯汀·比伯粉丝”房间,并为除套接字之外的所有人广播“新粉丝”。 在第二种情况下,您正在为“rammstein 粉丝”中的每个人广播以发送“新非粉丝”。

    2.) 在第一次通话中,您只为单个用户发出“事件”,并将消息发送到该单个房间。

    在第二次通话中,您正在为该房间中的每个人发送消息。

    3.) 再次查看源代码,它们看起来都非常相似,除了 socket.io 协议接受3 different kind of messages: "event", "json", "message"。 使用 .send,您可以发送 json 字符串或消息。 使用 .emit,您将向客户端发送事件。 这并没有太大区别,它们在内部的处理方式几乎相同,但您应该使用最适合您需求的那个。

    【讨论】:

    • 我决定在 socket.io 中实现我自己的“房间”方式。不过谢谢你的信息。
    • 同意你的观点,房间系统不是很清楚,似乎超出了我想让Socket.IO做的范围。
    • 现在,它工作得非常好。有时手动方式,自己实现更好:)
    【解决方案3】:

    我在 RedisStore 中很好地使用了房间功能。

    正如您在 Socket.io 源文件中看到的那样。

    房间功能(Redis 的订阅和取消订阅用于实现该功能)似乎

    仅在使用 RedisStore 时可用,但在默认 memoryStore 时不可用。

    我找到了

    {}
    

    joinleave 在 memoryStore 上的空源。

    所以我推荐使用想要集群 Socket.io 连接的 RedisStore

    多进程和多服务器之间

    也是为了成功使用Socket.io的房间功能

    【讨论】:

    • 奇怪。看起来它使用默认内存存储对我有用
    猜你喜欢
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    相关资源
    最近更新 更多