【问题标题】:Can I broadcast to all WebSocket clients我可以向所有 WebSocket 客户端广播吗
【发布时间】:2011-03-10 11:46:41
【问题描述】:

我假设这是不可能的,但想问一下以防万一。如果我想提供一个状态信息网页,我想使用 WebSockets 将数据从服务器推送到浏览器。但我担心的是大量浏览器会对服务器产生影响。我可以向所有客户端广播而不是向每个客户端发送离散消息吗?

【问题讨论】:

    标签: javascript node.js websocket


    【解决方案1】:

    WebSockets 使用 TCP,点对点,不提供广播支持。

    【讨论】:

    • 那么即使使用一些脚本语言,广播的执行速度是否与逐个发送消息的速度相同?
    • Websocket 框架可能使“广播”变得容易,但它会在后台发送离散的消息。这就是大多数服务器和主机限制连接客户端数量的原因(Heroku 限制曾经是每个 Dyno 600 个客户端)。
    • 我知道这是旧的,但我今天发现它显然仍然可见。现在有很多选项可以“广播”到所有连接的 websocket。如果您使用节点服务器,您可以使用“npm i ws”之类的库并循环遍历每个客户端并发送数据。
    • 循环遍历每个客户端并不是一种有效的方法,比如当您拥有大量客户端时。它会延迟到您循环中的最后一个客户端。那么,还有什么可以替代的呢?
    【解决方案2】:

    不确定您的客户端/服务器设置如何,但您始终可以在服务器中保留所有已连接客户端的集合 - 然后遍历每个客户端并发送消息。

    使用 Node 的 Websocket 库的简单示例:

    服务器代码

    var WebSocketServer = require('websocket').server;
    
    var clients = [];
    var socket = new WebSocketServer({
      httpServer: server,
      autoAcceptConnections: false
    });
    
    socket.on('request', function(request) {
      var connection = request.accept('any-protocol', request.origin);
      clients.push(connection);
    
      connection.on('message', function(message) {
        //broadcast the message to all the clients
        clients.forEach(function(client) {
          client.send(message.utf8Data);
        });
      });
    });
    

    【讨论】:

    • 因为 send 只是到套接字缓冲区的本机副本,所以这应该非常快,但会占用大量内存。由于这个原因,大多数浏览器将并发 websocket 的数量限制在 256 以下。
    • send() 将在客户端断开连接时抛出异常,因此您需要侦听“关闭”事件以删除断开连接的客户端。
    【解决方案3】:

    正如其他答案中所述,WebSockets 不支持多播,但看起来“ws”模块为您维护了一个已连接客户端的列表,因此很容易遍历它们。来自the docs

    const WebSocketServer = require('ws').Server;
    const wss = new WebSocketServer({ port: 8080 });
    
    wss.broadcast = function(data) {
      wss.clients.forEach(client => client.send(data));
    };
    

    【讨论】:

    • 但是为了避免看到有 10000 个用户连接,我需要将它们全部循环吗?其耗时。有什么技术可以向部分用户广播
    • @mandaputtra "WebSockets 不支持多播" - 您还需要什么信息?
    【解决方案4】:

    是的,可以向多个客户端广播消息。

    在 Java 中,

      @OnMessage
      public void onMessage(String m, Session s) throws IOException {
      for (Session session : s.getOpenSessions()) {
        session.getBasicRemote().sendText(m);
       }
    }
    

    这里解释一下。 https://blogs.oracle.com/PavelBucek/entry/optimized_websocket_broadcast.

    【讨论】:

      【解决方案5】:

      这真的取决于服务器端。下面是一个使用Tomcat7 的示例:

      Tomcat 7 Chat Websockets Servlet Example

      以及它是如何构造的解释here

      【讨论】:

        【解决方案6】:

        是的,您可以,并且有许多使用各种脚本语言编写的套接字服务器正在执行此操作。

        【讨论】:

          【解决方案7】:

          Microsoft.Web.WebSockets 命名空间有一个具有广播功能的 WebSocketCollection。在 Nuget 中查找程序集。名称是 Microsoft.WebSockets。

          【讨论】:

            猜你喜欢
            • 2019-12-01
            • 2015-07-04
            • 2019-04-01
            • 2019-05-05
            • 2019-09-20
            • 2017-05-26
            • 2018-11-14
            • 2015-07-03
            相关资源
            最近更新 更多