Capture client disconnect events! - Gevent / Python

I use a long poll to talk with gevent. I use Event.wait (), waiting for new chat messages to appear.


I would like to handle the case when the client disconnects using some functions:

eg. Return "client disconnected" as a message to other chat users


Is it possible? =)

+7
python django long-polling gevent
source share
3 answers

It depends on which WSGI server you are using. AFAIK gevent.wsgi will not notify your handler in any way when the client closes the connection because libevent-http does not. However, with gevent.pywsgi this should be possible. You will probably need to run an extra green eye to monitor the status of the socket and somehow notify the greenery that launches the handler, for example. killing him. I could have skipped an easier way to do this, though.

+1
source share

According to WSGI PEP , if your application returns an iterator using the close () method, the server should call this at the end of the request. Here is an example:

""" Run this script with 'python sleepy_app.py'. Then try connecting to the server with curl: curl -N http://localhost:8000/ You should see a counter printed in your terminal, incrementing once every second. Hit Ctrl-C on the curl window to disconnect the client. Then watch the server output. If running with a WSGI-compliant server, you should see "SLEEPY CONNECTION CLOSE" printed to the terminal. """ class SleepyApp(object): def __init__(self, environ, start_response): self.environ = environ self.start_response = start_response def __iter__(self): self.start_response('200 OK', [('Content-type', 'text/plain')]) # print out one number every 10 seconds. import time # imported late for easier gevent patching counter = 0 while True: print "SLEEPY", counter yield str(counter) + '\n' counter += 1 time.sleep(1) def close(self): print "SLEEPY CONNECTION CLOSE" def run_gevent(): from gevent.monkey import patch_all patch_all() from gevent.pywsgi import WSGIServer server = WSGIServer(('0.0.0.0', 8000), SleepyApp) print "Server running on port 0.0.0.0:8000. Ctrl+C to quit" server.serve_forever() if __name__ == '__main__': run_gevent() 

However, there is an error in the Python implementation of wsgiref (and on the Django dev server, which inherits from it), which prevents close () caused by disconnecting the middle-stream client. Therefore, avoid wsgiref and the Django dev server for this case.

Note also that close () will not be triggered immediately when the client disconnects. This will happen when you try to write some message to the client and fail because there is no connection anymore.

+3
source share

This is a complete blow in the dark, as I would never use gevent, but would not disconnect the client, just when the socket is closed. Perhaps something like this will work:

 if not Event.wait(): # Client has disconnected, do your magic here! return Chat({'status': 'client x has disconnected'}) 
+1
source share

All Articles