【问题标题】:node.js + socket.io broadcast from server, rather than from a specific client?node.js + socket.io 从服务器广播,而不是从特定客户端广播?
【发布时间】:2012-01-25 05:02:52
【问题描述】:

我正在使用 node.js + socket.io 构建一个简单的系统,例如实时新闻提要。

由于这是一个“只读”系统,客户端连接并接收数据,但客户端实际上从不发送自己的任何数据。服务器生成需要发送给所有客户端的消息,没有客户端生成任何消息;但我确实需要广播。

documentation for socket.io's broadcast(页尾)说

要广播,只需将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 });
});

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

【问题讨论】:

    标签: node.js socket.io


    【解决方案1】:

    由于您只在服务器端发出事件,您应该为您的服务器创建一个自定义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() 确实是更适合

    【讨论】:

    • 啊,我之前做过非常相似的事情,虽然更多的是传统的观察者设计模式(这是我第一天使用节点),但我担心循环效率低下。新消息每 7 秒向大约 10,000 个客户广播一次。
    • 我假设广播使用了一种高效的算法,但也许它只是一种抽象。我会试试你的方法;)
    • 有点离题,但我需要处理断开连接,还是 socket.io/node 会为我处理它?似乎我最终会遇到死事件观察者。
    • 你不需要处理断开连接。
    【解决方案2】:

    为什么不像下面那样做呢?

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

    【讨论】:

    • 当我尝试时,我得到一个错误,io.sockets.emit 不是一个定义的函数。
    • 嗯,看来我真的试过io.sockets.broadcast.emit(),我的错,这似乎有效!
    • 我会更改选择的答案,因为这更简单,谢谢。
    • 如果您确实有一些简单的东西可以工作,如果您需要遍历套接字并且仅在满足特定条件时才发送消息,那么我的解决方案更通用。
    • 从 v1.0.4 开始,我可以简单地编写 io.emit('hello',{msg:'abc'}),它也可以正常工作。
    猜你喜欢
    • 2016-07-21
    • 2020-03-12
    • 1970-01-01
    • 2012-01-04
    • 2012-07-18
    • 2017-09-08
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多