1
votes

I'm using the gevent-websocket module with Bottle Python framework.

When a client closes the browser, this code

$(window).on('beforeunload', function() { ws.close(); });

helps to close the websocket connection properly.

But if the client's network connection is interrupted, no "close" information can be sent to the server.

Then, often, even 1 minute later, the server still believes the client is connected, and the websocket is still open on the server.

Question: How to detect properly that a websocket is closed because the client is disconnected from network?

Is there a websocket KeepAlive feature available in Python/Bottle/gevent-websocket?


One answer from Web Socket: cannot detect client connection on internet disconnect suggests to use a heartbeat/ping packet every x seconds to tell the server "I'm still alive". The other answer suggests using a setKeepAlive(true). feature. Would this feature be available in gevent-websocket?


Example server code, taken from here:

from bottle import get, template, run
from bottle.ext.websocket import GeventWebSocketServer
from bottle.ext.websocket import websocket

users = set()

@get('/')
def index():
    return template('index')

@get('/websocket', apply=[websocket])
def chat(ws):
    users.add(ws)
    while True:
        msg = ws.receive()
        if msg is not None:
            for u in users:
                u.send(msg)
        else:
            break
    users.remove(ws)

run(host='127.0.0.1', port=8080, server=GeventWebSocketServer)
1

1 Answers

0
votes

First you need to add a timeout to the receive() method.

with gevent.Timeout(1.0, False):
    msg = ws.receive()

Then the loop will not block, if you send even an empty packet and the client doesn't respond, WebsocketError will be thrown and you can close the socket.