服务器如何广播 node.js + socket.io,而不是从特定的客户端广播?

16

我正在构建一个简单的系统,类似实时新闻订阅,使用node.js + socket.io。

因为这是一个"只读"系统,客户端连接并接收数据,但客户端从未发送其自己的任何数据。服务器生成需要发送到所有客户端的消息,没有客户端生成任何消息; 然而我需要进行广播。

socket.io广播的文档(页面底部)说:

要进行广播,只需将broadcast标志添加到emitsend方法调用中。广播意味着向除了启动它的套接字之外的所有其他人发送消息。

所以我目前捕获最近连接的客户端,并将emit()到该套接字 broadcast.emit()到该套接字,使得这个新客户端获取新的数据所有其他客户端。但感觉客户端在这里的作用仅仅是对我本来认为socket.io已经支持的问题进行了解决。

是否有一种方式可以基于由服务器发起的事件将数据发送到所有客户端?

我的当前方法大致是:

var socket;

io.sockets.on("connection", function (s) {
  socket = s;
});

/* bunch of real logic, yadda yadda ... */

myServerSideNewsFeed.onNewEntry(function (msg) {
  socket.emit("msg", { "msg" : msg });
  socket.broadcast.emit("msg", { "msg" : msg });
});

基本上,导致数据需要发送到客户端的事件都是在服务器端发生的,而不是在客户端。

2个回答

21

为什么不像以下这样做呢?

io.sockets.emit('hello',{msg:'abc'});

当我尝试这样做时,出现了一个错误,提示io.sockets.emit不是一个已定义的函数。 - d11wtq
2
哦,看起来我实际上尝试了io.sockets.broadcast.emit(),我的错,这似乎可以工作! - d11wtq
@alessioalex,谢谢,我很感激你的解决方案;我学到了新东西。然而,在这种情况下,我特别想避免迭代的需要。这是一个非常简单的系统,但需要尽可能地扩展,因为它在整个网站上都是可见的,并且每7秒钟更新一次。 - d11wtq
当然,io.sockets.broadcast.emit 是最适合的选择。 - alessioalex
1
从v1.0.4开始,我可以简单地编写“io.emit('hello',{msg:'abc'})”,它同样有效。 - Lucio Paiva
显示剩余2条评论

5

由于您仅在服务器端发出事件,因此应为您的服务器创建自定义EventEmitter

var io = require('socket.io').listen(80);
    events = require('events'),
    serverEmitter = new events.EventEmitter();

io.sockets.on('connection', function (socket) {
  // here you handle what happens on the 'newFeed' event
  // which will be triggered by the server later on
  serverEmitter.on('newFeed', function (data) {
    // this message will be sent to all connected users
    socket.emit(data);
  });
});

// sometime in the future the server will emit one or more newFeed events
serverEmitter.emit('newFeed', data);

注意: newFeed 只是一个事件示例,您可以拥有尽可能多的事件。
重要提示:
上述解决方案更好,因为将来您可能需要仅向某些客户端发出特定消息,而不是全部(因此需要条件)。对于更简单的情况(无论如何都向所有客户端发出消息),io.sockets.broadcast.emit()确实更合适。

啊,我之前也在做类似的事情,尽管使用了更传统的观察者设计模式(这是我第一天使用node),但我担心循环效率不高。新消息每7秒广播给大约10,000个客户端。 - d11wtq
我原以为广播使用了高效的算法,但也许它只是一种抽象。我会尝试你的方法 ;) - d11wtq
有点离题,但我需要处理断开连接吗,还是socket.io/node会为我处理?看起来我最终会得到死事件观察者。 - d11wtq
你不需要处理断开连接。 - alessioalex

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