【问题标题】:How to reconnect to a Web Socket when I refresh the client web page刷新客户端网页时如何重新连接到 Web Socket
【发布时间】:2019-05-24 08:21:51
【问题描述】:

当我刷新客户端网页时,我停止从龙卷风套接字服务器接收数据。如何重新连接到流?

我尝试将连接对象附加到列表中,然后在关闭时从列表中删除连接,但事实证明,当您刷新页面时,连接永远不会关闭,它根据服务器保持活动状态,但它客户端也不再接收数据:(

这是我的龙卷风服务器

# python 3
from tornado import web, httpserver, ioloop, websocket, options
from time import time, sleep


class ChannelHandler(websocket.WebSocketHandler):
    """Handler that handles a websocket channel"""
    connections = list()

    @classmethod
    def urls(cls):
        return [(r'/websocket', cls, {})]

    def initialize(self):
        self.channel = None

    def open(self):
        # When Client opens a websocket
        # add the new connnection to connections
        self.connections.append(self)

    def on_message(self, message):
        # Message received on channel
        # keep sending all connected clients the time info
        while True:
            [client.write_message({'time()': str(time())}) for client in self.connections]
            sleep(1)
            print('still sending')

    def on_close(self):
        # Channel is closed
        # delete client from active connections if they close connection
        self.connections.remove(self)
        print('CLOSED connection?')

    def check_origin(self, origin):
        # Override the origin check if needed
        return True


def main():
    # Create tornado application and supply URL routes
    app = web.Application(ChannelHandler.urls())
    # Setup HTTP Server
    http_server = httpserver.HTTPServer(app)
    http_server.listen(8000, 'localhost')
    # Start IO/Event loop
    ioloop.IOLoop.instance().start()


if __name__ == '__main__':
    main()

而socket客户端是

<script type="text/javascript">
    var ws = new WebSocket("ws://localhost:8000/websocket");
    ws.onopen = function () {
        ws.send("Hello, world");
    };
    ws.onmessage = function (evt) {
        console.log(evt.data);
    };
</script>

那么,当我刷新客户端网页时,如何继续从套接字服务器接收数据?

【问题讨论】:

  • on_message 内部有一个无限的while 循环。由于 Tornado 使用单个线程,因此您基本上完全阻塞了整个服务器。什么都不会发生。永远不要运行无限的while 循环。也不要在on_message 处理程序中运行定期任务。您需要一个后台异步作业。
  • @freakish Inifinite while 如果循环内的代码使用yieldawait 语法以使循环暂停并且IOLoop 可以运行其他任务,则循环不是问题。然而,在这种情况下,缺少yield/await 会导致问题。

标签: javascript python websocket socket.io tornado


【解决方案1】:

while 循环阻塞了整个服务器。您在循环中添加了一个 sleep(1) 调用以暂停循环一秒钟,但 time.sleep 是一个阻塞函数,因此也没有任何帮助。

您需要使用time.sleep 的异步替代方案——Tornado 的gen.sleep

您还需要将on_message 函数转换为协程。

例子:

from tornado import gen


async def on_message(...):
    ...
    while True:
        ...
        await gen.sleep(1)
        ...

作为附加提示,请使用 set() 而不是 list() 来存储您的连接,以免意外添加重复的连接。

在这种情况下,您还需要稍微修改您的代码。 set 没有 append 方法,而是有一个 add 方法。

connections = set()
...
self.connections.add(self) # to add connection
...
self.connections.remove(self) # to remove connetion

【讨论】:

  • 谢谢@xyres。解决了我的挑战。
猜你喜欢
  • 1970-01-01
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
相关资源
最近更新 更多