Skip to content

Commit

Permalink
feat(sync): Check for websocket connectivity and retry if not connected.
Browse files Browse the repository at this point in the history
Because the WebSockets do not offer a way to know when they failed to
connect, use a delay and check the state of the connection.
  • Loading branch information
almet committed Oct 25, 2024
1 parent 4f575f2 commit 9fdb83f
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 3 deletions.
1 change: 1 addition & 0 deletions umap/static/umap/js/modules/sync/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class SyncEngine {
* Authenticate with the server and start the transport layer.
*/
async authenticate() {
console.log("authenticating")
const [response, _, error] = await this._server.get(this._websocketTokenURI)
if (!error) {
this.start(response.token)
Expand Down
8 changes: 8 additions & 0 deletions umap/static/umap/js/modules/sync/websocket.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const PONG_TIMEOUT = 5000;
const PING_INTERVAL = 30000;
const FIRST_CONNECTION_TIMEOUT = 2000;

export class WebSocketTransport {
constructor(webSocketURI, authToken, messagesReceiver) {
Expand All @@ -21,6 +22,13 @@ export class WebSocketTransport {
}
}

this.ensureOpen = setInterval(() => {
if (this.websocket.readyState !== WebSocket.OPEN) {
this.websocket.close()
clearInterval(this.ensureOpen)
}
}, FIRST_CONNECTION_TIMEOUT)

// To ensure the connection is still alive, we send ping and expect pong back.
// Websocket provides a `ping` method to keep the connection alive, but it's
// unfortunately not possible to access it from the WebSocket object.
Expand Down
6 changes: 4 additions & 2 deletions umap/static/umap/js/umap.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,14 @@ U.Map = L.Map.extend({
},

render: function (fields) {
console.log("sync.websocketConnected", this.sync.websocketConnected)
console.log("options.syncEnabled", this.options.syncEnabled)
if (this.options.syncEnabled === true) {
if (!this.sync.websocketConnected) {
if (this.sync.websocketConnected !== true) {
const template = `
<h3><i class="icon icon-16"></i><span>${L._('Disconnected')}</span></h3>
<p>
${L._('This map has enabled real-time synchronization with other users, but you are currently disconnected. It will automatically reconnect when ready.')}
${L._('This map has enabled real-time synchronization with other users, but you are currently disconnected.It will automatically reconnect when ready.')}
</p>
`
this.dialog.open({
Expand Down
5 changes: 4 additions & 1 deletion umap/websocket_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,7 @@ async def _serve():
logging.debug(f"Waiting for connections on {host}:{port}")
await asyncio.Future() # run forever

asyncio.run(_serve())
try:
asyncio.run(_serve())
except KeyboardInterrupt:
print("Closing WebSocket server")

0 comments on commit 9fdb83f

Please sign in to comment.