Reputation: 30074
I was testing browser-based websockets using the slightly adapted (extra try
) code from the documentation:
(backend)
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()
(frontend)
<!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>
When starting the backend and opening the frontend .html
file in a browser (Chrome), I get the expected
new connection
on the backend output, and the browser is filled in with timestamps.
After reloading the page (F5
), I get again a new connection
, followed by ongoing connection closed
:
new connection
new connection
connection closed
connection closed
connection closed
connection closed
connection closed
At the same time, the browser acts as expected, being filled in with timestamps.
What is happening? Why would the connection be stable the first time, and the unstable after reloading the page? Is the connection to the websocket recreated automatically (looks so, since the browser activity is OK) - but in that case what causes it to be closed in the first place?
Upvotes: 1
Views: 4076
Reputation: 38992
You catch websockets.exceptions.ConnectionClosed
exception which is how websockets
knows to unregister a closed connection.
The closed connection is never unregistered because of this. Messages keep being sent through it.
You can get past this by doing any of the following:
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])
Upvotes: 3
Reputation: 110746
Because you create a new WebSocket object on each browser reload. WebSockets can be persistent, but only if the object representing them is kept alive both on server and client sides - you do nothing to preserve your Javascript websocket upon page reload and it can't be ordinarily done - you have to use other mechanisms than full page reload to communicate. On page reload, the browser just creates a new connection to the server as a new WebSockect.
Upvotes: 2