【问题标题】:How to send server message to specific client in tornado websocket如何在龙卷风 websocket 中向特定客户端发送服务器消息
【发布时间】:2017-10-19 11:44:40
【问题描述】:

嘿,我是 python 新手,这是 tornado 中的 Websocket 服务器代码

import tornado.ioloop
import tornado.web
import tornado.websocket
import tornado.template

class MainHandler(tornado.web.RequestHandler):
  def get(self):
    loader = tornado.template.Loader(".")
    self.write(loader.load("index.html").generate())

class WSHandler(tornado.websocket.WebSocketHandler):
  def open(self):
    print 'connection opened...'
    self.write_message("The server says: 'Hello'. Connection was accepted.")

  def on_message(self, message):
    self.write_message("The server says: " + message + " back at you")
    print 'received:', message

  def on_close(self):
    print 'connection closed...'

application = tornado.web.Application([
  (r'/ws', WSHandler),
  (r'/', MainHandler),
  (r"/(.*)", tornado.web.StaticFileHandler, {"path": "./resources"}),
])

if __name__ == "__main__":
  application.listen(9090)
  tornado.ioloop.IOLoop.instance().start()

它工作正常并在服务器上接收我的消息(客户端消息),但遗憾的是它没有向我发送其他客户端消息。就像我有这个 html

<!DOCTYPE html>
<html>
<head>
  <title>WebSockets Client</title>  
  <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body>
Enter text to send to the websocket server:
<div id="send">
    <input type="text" id="data" size="100"/><br>
    <input type="button" id="sendtext" value="send text"/>
</div>
<div id="output"></div>
</body>
</html>
<script>

jQuery(function($){

  if (!("WebSocket" in window)) {
    alert("Your browser does not support web sockets");
  }else{
    setup();
  }


  function setup(){

    // Note: You have to change the host var 
    // if your client runs on a different machine than the websocket server

    var host = "ws://localhost:9090/ws";
    var socket = new WebSocket(host);
    console.log("socket status: " + socket.readyState);   

    var $txt = $("#data");
    var $btnSend = $("#sendtext");

    $txt.focus();

    // event handlers for UI
    $btnSend.on('click',function(){
      var text = $txt.val();
      if(text == ""){
        return;
      }
      socket.send(text);
      $txt.val("");    
    });

    $txt.keypress(function(evt){
      if(evt.which == 13){
        $btnSend.click();
      }
    });

    // event handlers for websocket
    if(socket){

      socket.onopen = function(){
        //alert("connection opened....");
      }

      socket.onmessage = function(msg){
        showServerResponse(msg.data);
      }

      socket.onclose = function(){
        //alert("connection closed....");
        showServerResponse("The connection has been closed.");
      }

    }else{
      console.log("invalid socket");
    }

    function showServerResponse(txt){
      var p = document.createElement('p');
      p.innerHTML = txt;
      document.getElementById('output').appendChild(p); 
    }   


  }





});

</script>

当我从客户端(使用上面的 html)点击发送按钮时,它会将我的消息发送到服务器,但我想将我的消息发送到其他客户端。如何像任何所需的客户端一样将我的消息从服务器发送到其他客户端。 评论中给出的链接为我提供了一种方式 (创建一个全局列表变量,在其中添加每个客户端,然后在消息事件中循环并发送消息) 将我的消息发送给所有客户端,但我也想要我的给特定客户的消息。

【问题讨论】:

标签: python websocket tornado


【解决方案1】:

您需要一些外部系统来执行此操作。正如 Ben Darnell 所说,其他问题解释了一些原始的方法来聚集客户。

您需要在初始化时收集每个客户端的某种 ID。这可能是您系统中的一个帐户,或者您可以为每个新连接生成一个新帐户:

import uuid

clients = {}

class WSHandler(tornado.websocket.WebSocketHandler):
    def __init__(self, application, request, **kwargs):
        super(WSHandler, self).__init__(application, request, **kwargs)
        self.client_id = str(uuid.uuid4())

    def open(self):
        print 'connection for client {0} opened...'.format(self.client_id)
        clients[self.client_id] = self
        self.write_message("The server says: 'Hello'. Connection was accepted.")

    def on_message(self, message):
        self.write_message("The server says: " + message + " back at you")
        print 'received:', message

    def on_close(self):
        clients.pop(self.client_id, None)
        print 'connection closed...'

稍后,您可以使用这个完全编造的client_id 告诉其他客户端具有该ID 的客户端存在。稍后您可以使用

向他发送消息
clients[<id>].write_message("Hello!")

不过,附带说明一下,这种方法无法很好地扩展。事实上,您只能处理连接到当前龙卷风实例的客户端。如果您需要多个实例以及联系任何客户端的方法,请参阅 rabbitmq 等消息代理。

【讨论】:

    猜你喜欢
    • 2022-01-27
    • 1970-01-01
    • 2022-07-15
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    相关资源
    最近更新 更多