【问题标题】:Is it possible to send a message to all active WebSocket connections? Using either node.js or python tornado websockets是否可以向所有活动的 WebSocket 连接发送消息?使用 node.js 或 python tornado websockets
【发布时间】:2011-07-08 10:21:42
【问题描述】:

我正在尝试构建一个基于 websocket 的应用程序。

我想知道是否可以向所有活动连接发送消息,因为它们是持久的。

假设我正在运行一个实时拍卖网站,并且我有多个用户正在观看拍卖页面,每个用户都通过套接字连接到我的服务器。现在假设一位用户提高了出价。我想向所有连接的客户端发送消息。最简单的方法是让客户端每秒通过套接字轮询服务器,但我认为 websockets 的想法是实现真正的双向通信。

如何做到这一点?

提前致谢,

罗特姆

【问题讨论】:

  • 我也有这个确切的问题。谁能说我怎么能在使用tomcat服务器的servlet中做到这一点。我按照这个例子创建了一个 WebSocketServlet。 - gist.github.com/chitan/3063774

标签: node.js websocket tornado


【解决方案1】:

socket.io解决方案:

// note, io.listen() will create a http server for you
var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  io.sockets.emit('this', { will: 'be received by everyone' });

  socket.on('private message', function (msg) {
    console.log('I received a private message from ', socket.id, ' saying ', msg);
    // Echo private message only to the client who sent it
    socket.emit('private message', msg);
  });

  socket.on('disconnect', function () {
    // This will be received by all connected clients
    io.sockets.emit('user disconnected');
  });
});

all_active_connections = {};

webocket server(有many),手动操作:

  var ws = require("ws");

  global_counter = 0;
  all_active_connections = {};

  ws.createServer(function (websocket) 
  {
      websocket.on('connect', function() 
      {
          var id = global_counter++;
          all_active_connections[id] = websocket;
          websocket.id = id; 
      }).on('data', function (data) {
          if (data == 'broadcast me!')
          {
              for (conn in all_active_connections)
                 all_active_connections[conn].write(data);
          }       
      }
    }).on('close', function() {
        delete all_active_connections[websocket.id];
    });
  }).listen(8080);

【讨论】:

  • 你能解释一下如何在servlet中做到这一点。
  • 什么叫servlet?
【解决方案2】:

对于基于 tornado/tornadio 的解决方案,您的 SocketConnection 类需要在类级别维护一个连接列表。您的 on_connect 处理程序会将连接添加到此列表,而 on_close 将删除它。有关示例伪代码,请参阅 Serge S. Koval 的 this post。代码复制如下:

声明你的 TornadIO 连接类:

class MyConnection(SocketConnection):
    participants = set()

    @classmethod
    def broadcast(cls, msg):
        for p in cls.participants:
            p.send(msg)

    @classmethod
    def controller_msg(cls, msg):
        cls.broadcast(msg)

在您的设备轮询线程中,执行以下操作:

while True: 
    datum = file.readline() 
    if len(datum) > 2: 
        t = json.loads(datum) 
        ...
        def callback():
            MyConnection.controller_msg(t)

        io_loop.add_callback(callback)

另外,gevent-socketio 支持消息广播,但它基于 gevent,而不是 tornado。

更新:

tornadio2 已经维护了一个活动会话列表,所以您需要做的就是:

class MyConnection(SocketConnection):
    def broadcast(self, event, message):
        for session_id, session in self.session.server._sessions._items.iteritems():
            session.conn.emit(event, message)

这是因为每个连接实例都有一个对其会话的引用,该会话引用了用于创建应用程序的全局路由器(存储为server),它在SessionContainer 对象中维护会话列表_sessions。现在,每当您想在连接类中广播消息时,只需执行以下操作:

self.broadcast('my_custom_event', 'my_event_args')

【讨论】:

    【解决方案3】:

    这个redis + websockets (on tornado) 示例应该对您有所帮助。基本上,您有一个应该通知的听众列表,一旦收到消息,就会遍历该列表并通知他们。

    【讨论】:

    • 更新到另一个
    猜你喜欢
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    相关资源
    最近更新 更多