Flask server sent events socket exception

痴心易碎 提交于 2019-12-04 08:52:12

You could use either onBeforeUnload or jQuery's window.unload() to make an Ajax call to some tear down method that closes the handle. Something like:

$(window).unload(
    function() {
        $.ajax(type: 'POST',
               async: false,
               url: 'foo.com/client_teardown')
    }
}

There are some inconsistencies with how the unload()/onBeforeUnload() are handled, so you may have some more work to do in something like Chrome.

I have no better answer, but I don't think the above ajax request to server is good.

In flask, SSE use streaming in a Response object, if there is a way to detect the disconnect or pipe broken event in Response, that would be better to handle socket events and release other resources allocated.

msiemens

I found a dirty (includes mokey patching), but working solution.

Because there is an exception in SocketServer.StreamRequestHandler.finish when the connection drops, we can patch it to catch the exception and handle it as we like:

import socket
import SocketServer

def patched_finish(self):
    try:
        if not self.wfile.closed:
            self.wfile.flush()
            self.wfile.close()
    except socket.error:
        # Remove this code, if you don't need access to the Request object
        if _request_ctx_stack.top is not None:
            request = _request_ctx_stack.top.request
            # More cleanup code...
    self.rfile.close()

SocketServer.StreamRequestHandler.finish = patched_finish

If you need access to the corresponding Request object, you additionally need to wrap the event stream with flask.stream_with_context, in my case:

@app.route(url)
def method(host):
    return Response(stream_with_context(event_stream()),
                    mimetype='text/event-stream')

Again, this is a very dirty solution and propably won't work if you don't use the builtin WSGI server.

Do not use Flask inner dev wsgi server in the prod env. Consider about using uwsgi which could handle this socket error elegantly.

Meanwhile think about use python3 which also catch this sockrt broken well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!