Skip to main content
 首页 » 编程设计

python之为什么 websockets 连接在浏览器重新加载时不断关闭

2025年05月04日64thcjp

我正在使用稍微修改过的(额外的 try)代码测试基于浏览器的 websockets from the documentation :

(后端)

import asyncio 
import datetime 
import random 
import websockets 
 
async def time(websocket, path): 
    print("new connection") 
    while True: 
        now = datetime.datetime.utcnow().isoformat() + 'Z' 
        try: 
            await websocket.send(now) 
        except websockets.exceptions.ConnectionClosed: 
            print("connection closed") 
        await asyncio.sleep(random.random() * 3) 
 
start_server = websockets.serve(time, '127.0.0.1', 5678) 
 
asyncio.get_event_loop().run_until_complete(start_server) 
asyncio.get_event_loop().run_forever() 

(前端)

<!DOCTYPE html> 
<html> 
    <head> 
        <title>WebSocket demo</title> 
    </head> 
    <body> 
        <script> 
            var ws = new WebSocket("ws://127.0.0.1:5678/"), 
                messages = document.createElement('ul'); 
            ws.onmessage = function (event) { 
                var messages = document.getElementsByTagName('ul')[0], 
                    message = document.createElement('li'), 
                    content = document.createTextNode(event.data); 
                message.appendChild(content); 
                messages.appendChild(message); 
            }; 
            document.body.appendChild(messages); 
        </script> 
    </body> 
</html> 

当启动后端并在浏览器 (Chrome) 中打开前端 .html 文件时,我得到了预期的

new connection 

在后端输出上,浏览器填充了时间戳。

重新加载页面 (F5) 后,我再次获得一个新连接,然后是正在进行的连接关闭:

new connection 
new connection 
connection closed 
connection closed 
connection closed 
connection closed 
connection closed 

与此同时,浏览器按预期运行,填充了时间戳。

这是怎么回事? 为什么第一次连接稳定,重新加载页面后连接不稳定?是否自动重新创建了与 websocket 的连接(看起来如此,因为浏览器事件正常)——但在那种情况下,是什么导致它首先被关闭?

请您参考如下方法:

您捕捉到 websockets.exceptions.ConnectionClosed 异常,这就是 websockets 知道注销已关闭连接的方式。 因此,关闭的连接永远不会取消注册。消息不断通过它发送。

您可以通过执行以下任一操作来克服此问题:

  1. 没有捕捉到异常。
  2. 通过连接的套接字发送消息
 
if websocket.open: 
    websocket.send(now) 
# this doesn't unregister the closed socket connection. 
  1. 从 websocket 服务器显式注销已关闭的套接字连接
 
websocket.ws_server.unregister(websocket)  
# This raises an exception as well 
  1. 在内存中维护已连接客户端的列表,向此列表中的连接发送消息,并在捕获到异常时从此列表中删除已关闭的连接。

 
connect.append() 
await asyncio.wait([ws.send("Hello!") for ws in connected]) 

引用