Socket.IO房间功能

12

我有两个不同的文件,其中一个是服务器端JS,另一个是动态生成的客户端PHP。

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

我知道可以使用.of()来限制命名空间,但无法用于处理动态创建的聊天室。

因此,我决定同时使用两个文件。

.of('/chat') 

并且房间特性

.join('room name') 

我能找到服务器端的示例,但找不到与之对应的客户端示例。

以下是来自Socket.IO github仓库中唯一已有的服务器端代码片段。

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 的多个问题而道歉。


5
一个好问题,展示了socket.io文档的质量不佳。 - vsync
3个回答

10

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)- 首先,您向单个客户端(socket one)发出/分派自定义事件。其次,您向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()基本相同,只是它使用默认事件名称“message”。因此,它只需要一个参数,即您要传递的数据。例如:

socket.send('hi');

这次您需要注册并监听 "message" 事件名称;

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

希望这可以帮助到您!


7

我已经有一段时间没有使用Socket.IO了,但是

1.) 正如文档所述:“广播指的是向除开始它的套接字之外的所有人发送消息。”通过对Socket.IO代码进行一些搜索,您可以查看/lib/socket.js中的Socket.prototye.packet。

当您进行第一个调用时,您将用户设置为“justin bieber fans”房间,并向每个套接字之外的所有人广播“new fan”。 在第二种情况下,您正在广播'rammstein fans'中的每个人都发送'new non-fan'。

2.) 在第一个调用中,您仅为单个用户和该单个房间发出“event”消息。

在第二次调用中,您为该房间中的每个人发送信息。

3.) 再次查看源代码,它们看起来非常相似,只是socket.io协议接受3种不同类型的消息:“event”、“json”、“message”。 使用.send,您可以发送json字符串或消息。 使用.emit,您将向客户端发送事件。 它们在内部几乎以相同的方式处理,但您应该使用最适合您需求的那一个。


2
我决定在socket.io中实现自己的“房间”方式。非常感谢你提供的信息。 - jwchang
1
我同意你的观点,房间系统并不是很清晰,而且似乎超出了我想要 Socket.IO 做的范围。 - Nican
现在它运行得非常好。有时候手动方式,自己实现会更好 :) - jwchang

1

我正在使用RedisStore的房间功能。

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

房间功能(使用Redis的订阅和取消订阅来实现该功能)似乎只能在使用RedisStore时才可用,而不能在默认的memoryStore中使用。

我已经找到了。

{}

在memoryStore上,joinleave的源为空。

因此,我建议使用RedisStore来集群Socket.io连接

在多个进程和多个服务器之间,并且成功使用Socket.io的room功能。


奇怪。使用默认内存存储,它似乎对我有效。 - Christopher Tarquini

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