Closed emike922 closed 1 year ago
I do not know why this happens, but it is probably due to the Gevent WSGI server not having direct support for WebSocket. For a regular HTTP request, the server will send a response on the socket after the application's handler returns. In the case of a WebSocket connection, no response needs to be sent. I'm not sure this is the problem here, but it is a possibility. Have you tried using Gevent with the Gunicorn server? Maybe that works more reliably.
Good call! The Gunicorn server using Gevent worker doesn't raise any such exception from what I can tell. Unfortunately, I am stuck with the regular Gevent WSGIServer for at least a while longer yet..
It appears as though by adding a simple app.config['SOCK_SERVER_OPTIONS'] = {'ping_interval': 25}
, the exception is not produced either. Can you make any sense of why that would be?
Many thanks for the prompt support! :)
@emike922 I'm looking into this. I continue to think this is an issue that occurs due to gevent's WSGI server expecting all requests end with a standard HTTP response and getting confused when the request's socket is hijacked and used for a WebSocket connection.
But while looking at their source code I've found that if the socket is closed then they exit the request silently regardless of any failures. Your sleep allowed the client time to receive the close packet that you sent, reply with its own close packet to acknowledge, and finally close the socket. Using a ping_interval
changes the way socket reads are issued in the server, so this must also indirectly contribute to getting the socket closed sooner.
So basically, the goal is to figure out a way to have the socket closed before control goes back to gevent. At the same time, whatever I do to achieve this should not affect the other servers, so I have to test this well (or else make this happen conditionally only for the gevent web server, which I would prefer to avoid).
I am actually content with using ping_interval
. As long as this successfully mitigates the error without an arbitrary sleep, and it looks like it does, I will be happy to consider this a known limitation affecting the Gevent WSGIServer.
Unless this is an itch that now must be scratched, feel free to close this issue.. And thanks again!
When running a WS server with the gevent WSGIServer and sending a closing frame from within the route, gevent raises a ConcurrentObjectUseError for the socket. Adding a brief sleep before returning from the route seems to act as a workaround/mitigation.
Do you know why this occurs? Will 0.1 seconds sleep time be sufficient in all cases? Is there a more robust logic that I might employ? Is this something that might be solved from library side?
Example:
Output w/o final
gevent.sleep(0.1)
: