【问题标题】:Tornado coroutine with websockets not working with python3带有 websockets 的 Tornado 协程不适用于 python3
【发布时间】:2018-07-27 09:12:29
【问题描述】:

HandlerWebsockets 工作正常,只是回复目前通过messageToSockets(msg) 发送的内容。但是,两者都尝试从 Web 应用程序的协程向 Websocket 发送消息都不起作用。看起来一切都被这些尝试阻止了......

class webApplication(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r'/', HandlerIndexPage),
            (r'/websocket', HandlerWebSocket, dict(msg='start')),
        ]

        settings = {
            'template_path': 'templates'
        }
        tornado.web.Application.__init__(self, handlers, **settings)

    @gen.coroutine
    def generateMessageToSockets(self):
        while True:
            msg = str(randint(0, 100))
            print ('new messageToCon: ', msg)
            yield [con.write_message(msg) for con in HandlerWebSocket.connections]
            yield gen.sleep(1.0)

if __name__ == '__main__':

    ws_app = webApplication()
    server = tornado.httpserver.HTTPServer(ws_app)
    port = 9090
    print('Listening on port:' + str(port))
    server.listen(port)
    IOLoop.current().spawn_callback(webApplication.generateMessageToSockets)
    IOLoop.current().set_blocking_log_threshold(0.5)
    IOLoop.instance().start()

这里是 WebSockets 处理程序

class HandlerWebSocket(tornado.websocket.WebSocketHandler):
    connections = set()

    def initialize(self, msg):
        print('HWS:' + msg)

    def messageToSockets(self, msg):
        print ('return message: ', msg)
        [con.write_message(msg) for con in self.connections]

    def open(self):
            self.connections.add(self)
            print ('new connection was opened')
            pass

    def on_message(self, message):
            print ('from WebSocket: ', message)
            self.messageToSockets(message)

    def on_close(self):
            self.connections.remove(self)
            print ('connection closed')
            pass

我对示例、此处的问题、文档等有点迷失。因此,非常感谢任何提示如何正确启动连续调用 websocket 例程

【问题讨论】:

    标签: python-3.x tornado


    【解决方案1】:

    generateMessageToSockets 将无限循环,尽可能快地生成消息,而无需等待这些消息被发送。由于它首先启动并且从不让步,因此 HTTPServer 将永远无法真正接受连接。

    如果你真的想尽可能快地发送消息,那么没有阻塞的最小解决方案是

    yield [con.write_message(msg) for con in HandlerWebSocket.connections]
    yield gen.moment
    

    但最好使用gen.sleep 定期发送消息,而不是“尽可能快”。

    【讨论】:

    • 感谢您的回复。这只是一个简化的示例 hello world 之类的示例。生产代码只会发送很少的更新。相应地更改了代码/发布。不幸的是,仍然看不到命令​​行上的任何打印或通过例程生成的回复
    • 最后我要道歉,实际上你的建议确实适用于 python 3.6.5 和 tornado 5.1.. 抱歉,我必须经常更改平台
    【解决方案2】:

    不幸的是,所有的 gen.routines 尝试都对我不起作用。移回线程

    def generateMessageToSockets():
        while True:
            msg = str(randint(0, 100))
            print ('new messageToCon: ', msg)
            [con.write_message(msg) for con in HandlerWebSocket.connections]
            sleep(1.0)
    
    
    class WebApplication(tornado.web.Application):
        def __init__(self):
            handlers = [
                (r'/', HandlerIndexPage),
                (r'/websocket', HandlerWebSocket, dict(msg='start')),
            ]
    
            settings = {
                'template_path': 'templates'
            }
            tornado.web.Application.__init__(self, handlers, **settings)
    
    if __name__ == '__main__':
        tGenarate =  threading.Thread(target=generateMessageToSockets)
        tGenarate.start()
        ws_app = WebApplication()
        server = tornado.httpserver.HTTPServer(ws_app)
        port = 9090
        print('Listening on port:' + str(port))
        server.listen(port)
        ioloop.IOLoop.instance().start()
    

    哪个有效

    【讨论】:

    • 对于那些后来看到它确实适用于 Python 3.5.4 / Tornado 4.5.1 而不是 python 3.6.5 / tornado 5.1...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 2014-04-08
    相关资源
    最近更新 更多