我使用略微调整的(try
}代码from the documentation来测试基于浏览器的websockets:
(后端)
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
,然后继续connection closed
:
new connection
new connection
connection closed
connection closed
connection closed
connection closed
connection closed
同时,浏览器按预期运行,并填入时间戳。
发生了什么事?为什么连接第一次稳定,重新加载页面后不稳定?是否自动重新创建了websocket的连接(看起来如此,因为浏览器活动正常) - 但在这种情况下是什么导致它首先被关闭?
答案 0 :(得分:3)
您捕获websockets.exceptions.ConnectionClosed
异常,这是websockets
知道取消注册已关闭连接的方式。
因此,封闭连接永远不会注册。邮件不断通过它发送。
您可以通过执行以下任何操作来解决此问题:
if websocket.open:
websocket.send(now)
# this doesn't unregister the closed socket connection.
websocket.ws_server.unregister(websocket)
# This raises an exception as well
connect.append()
await asyncio.wait([ws.send("Hello!") for ws in connected])
答案 1 :(得分:2)
因为您在每次浏览器重新加载时都创建了一个新的WebSocket对象。 WebSockets可以是持久的,但只有当代表它们的对象在服务器端和客户端都保持活动状态时 - 在页面重新加载时你没有做任何事情来保留你的Javascript websocket并且它通常不能完成 - 你必须使用其他机制比完整页面重新加载进行通信。在页面重新加载时,浏览器只是作为新的WebSockect创建与服务器的新连接。