I am using RxPY to enable sending push based events via websockets. I am using flask-sockets in a Flask server with gevent. The events class contains an rx.subject.BehaviorSubject that acts as an event publisher, while the websocket clients subscribe to changes.
I want to be able to detect when a client is disconnected so I could properly dispose the resources. The problem is when the socket is disconnected and ws.send
throws an exception but it's inside the lambda.
Is there a way to pass the exception to the parent function instead?
An alternative solution would be to detect the websocket disconnect without calling ws.send
and that could be checked outside the lambda, though I could not find such method in the flask-sockets library.
@sockets.route('/ws/events')
def wsEvents(ws):
sub = None
disp = None
try:
print("socket opened")
def update_fn(x):
print(x)
ws.send(json.dumps(x))
sub = events.get_sub(None)
if sub is not None:
disp = sub.subscribe(lambda x: update_fn(x))
else:
raise Exception('Undefined sub')
while not ws.closed:
gevent.sleep(1)
pass
except Exception as e:
print(e)
finally:
print("socket closed")
if disp is not None:
disp.dispose()
I have found a workaround, detecting the socket disconnect event using a gevent timeout method like this:
while not ws.closed:
gevent.sleep(0.1)
try:
data = gevent.with_timeout(0.1, ws.receive, timeout_value="")
if data is None:
raise Exception("socket closed")
except:
break
Now it's possible to dispose the resources as the method returns None
on socket disconnected event.