Tornado 为一个请求推送多个响应

Posted

技术标签:

【中文标题】Tornado 为一个请求推送多个响应【英文标题】:Tornado to push multiple responses for one request 【发布时间】:2016-12-13 11:16:12 【问题描述】:

我需要为来自客户端的每个请求推送多个响应。我通过 websockets 使用龙卷风来达到这个目的。

根据我的理解,我对龙卷风比较陌生。

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
import socket

class WSHandler(tornado.websocket.WebSocketHandler):
    def open(self):
      print 'new connection'

    def on_message(self, message):
      print 'message received:  %s' % message
      # Reverse Message and send it back
      print 'sending back message: %s' % message[::-1]
      self.write_message('%s:%s' % (i,message[::-1]))

    def on_close(self):
      print 'connection closed'

    def check_origin(self, origin):
      return True

application = tornado.web.Application([
  (r'/ws', WSHandler),
])

如何让 on_message 函数推送多个请求。

我使用的html代码,

<!doctype html>
<html>
  <head>
    <title>WebSockets Hello World</title>
    <meta charset="utf-8" />
    <style type="text/css">
      body 
        text-align: center;
        min-width: 500px;
      
    </style>
    <script src="http://code.jquery.com/jquery.min.js"></script>
    <script>

      // log function
      log = function(data)
        $("div#terminal").prepend("</br>" +data);
        console.log(data);
      ;

      $(document).ready(function () 
        $("div#message_details").hide()

        var ws;

        $("#open").click(function(evt) 
          evt.preventDefault();

          var host = $("#host").val();
          var port = $("#port").val();
          var uri = $("#uri").val();

          // create websocket instance
          ws = new WebSocket("ws://" + host + ":" + port + uri);

          // Handle incoming websocket message callback
          ws.onmessage = function(evt) 
            log("Message Received: " + evt.data)
            alert("message received: " + evt.data);
            ;

          // Close Websocket callback
          ws.onclose = function(evt) 
            log("***Connection Closed***");
            alert("Connection close");
            $("#host").css("background", "#ff0000"); 
            $("#port").css("background", "#ff0000"); 
            $("#uri").css("background",  "#ff0000");
            $("div#message_details").empty();

            ;

          // Open Websocket callback
          ws.onopen = function(evt)  
            $("#host").css("background", "#00ff00"); 
            $("#port").css("background", "#00ff00"); 
            $("#uri").css("background", "#00ff00");
            $("div#message_details").show();
            log("***Connection Opened***");
          ;
        );

        // Send websocket message function
        $("#send").click(function(evt) 
            log("Sending Message: "+$("#message").val());
            ws.send($("#message").val());
        );

      );
    </script>
  </head>

  <body>
    <h1>WebSockets Hello World</h1>
    <div id="connection_details">
      <label for="host">host:</label>
      <input type="text" id="host" value="localhost" style="background:#ff0000;"/><br />
      <label for="port">port:</label>
      <input type="text" id="port" value="8888" style="background:#ff0000;"/><br />
      <label for="uri">uri:</label>
      <input type="text" id="uri" value="/ws" style="background:#ff0000;"/><br />
      <input type="submit" id="open" value="open" />
    </div>
    <div id="message_details">
        </br></br>
        <label for="message">message:</label>
        <input type="text" id="message" value="Hello World!"/><br />
        <input type="submit" id="send" value="send" />
    </div>
    <div id="terminal">

    </div>
  </body>
</html>

【问题讨论】:

【参考方案1】:

您可以多次拨打write_message

例如

def on_message(self, message):
    self.write_message("Message one")
    self.write_message("Message two")

【讨论】:

你能发布那个代码和错误吗?以上对我有用 我已经添加了我使用的 html 代码..我没有收到任何错误,我只是收到了第一个 send_message 的警报框。 它对我有用。您也可以发布您的确切服务器代码 工作正常,不知道为什么它最初失败但现在工作正常。谢谢。【参考方案2】:

在您的代码中,您打开一个 WebSocket,然后请求对该打开的 WebSocket 的多个响应。要获得多个回复,您可以按照 Henry Heath 的建议多次致电write_message

但是,如果您想为多个 WebSocket 实现多个响应,您可以遵循以下方法。

clients = [] # list of opened WebSocket clients
class WSHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        clients.append(self) # append a newly opened WebSocket client
        print 'new connection'

    def on_message(self, message):
        print 'message received:  %s' % message
        # loop over the opened WebSocket clients and send a message
        for client in clients:
            # Reverse Message and send it back
            print 'sending back message: %s' % message[::-1]
            client.write_message('%s' % (message[::-1]))

    def on_close(self):
        clients.remove(self) # remove a newly closed WebSocket client
        print 'connection closed'

    def check_origin(self, origin):
        return True

在您的模板(index.html)上,您只需单击按钮打开几次以打开几个新的WebSocktes,然后单击按钮发送 您将看到您将收到多个响应,与您打开的 WebSocket 的数量一样多。

这对于需要向多个客户端广播消息的应用程序(例如实时聊天)非常方便。

还要确保检查official excellent Tornado documentation for WebSockets。

【讨论】:

我不同意 - 您可以向单个连接发送多条消息。为每条消息打开一个新的 websocket 连接是不必要的,并且首先会破坏具有连接的点 是的,你是对的。您的建议有效 - 我已经编辑了我的回复。

以上是关于Tornado 为一个请求推送多个响应的主要内容,如果未能解决你的问题,请参考以下文章

2.tornado请求与响应

Tornado 6.1 非阻塞请求

Tornado实战

Tornado WebSocketHandler 不会响应 SSL 请求

tornado基本使用一

python tornado获得多个异步httprequest的响应