正在捕获客户端断开连接的事件!-Gevent/Python

正在捕获客户端断开连接的事件!-Gevent/Python,python,django,long-polling,gevent,Python,Django,Long Polling,Gevent,我正在使用长轮询与gevent聊天。我正在使用Event.wait()等待在聊天室中发布新消息 我想使用一些功能处理客户端断开连接的情况: e、 g.将“客户端已断开连接”作为消息返回给其他聊天用户 这可能吗?=) 这是一个彻头彻尾的冒险,因为我从未使用过gevent,但当套接字关闭时,客户端断开连接不是简单的。所以,也许像这样的方法会奏效: if not Event.wait(): # Client has disconnected, do your magic here!

我正在使用长轮询与gevent聊天。我正在使用Event.wait()等待在聊天室中发布新消息


我想使用一些功能处理客户端断开连接的情况:

e、 g.将“客户端已断开连接”
作为消息返回给其他聊天用户



这可能吗?=)

这是一个彻头彻尾的冒险,因为我从未使用过gevent,但当套接字关闭时,客户端断开连接不是简单的。所以,也许像这样的方法会奏效:

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

这取决于您使用的WSGI服务器。当客户端关闭连接时,AFAIK gevent.wsgi不会以任何方式通知处理程序,因为libevent http不会这样做。但是,使用gevent.pywsgi应该是可能的。您可能需要启动一个额外的greenlet来监视套接字条件,并以某种方式通知运行处理程序的greenlet,例如通过终止它。不过,我可能错过了一个更简单的方法。

根据,如果你的应用程序返回一个带有close()方法的迭代器,服务器应该在请求结束时调用该迭代器。下面是一个例子:

"""
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's 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()
但是,Python的wsgiref实现(以及从其继承的Django dev服务器)中存在一个漏洞,它可以防止在中流客户端断开连接时调用close()。因此,在这种情况下避免使用wsgiref和Django-dev服务器


还请注意,当客户端断开连接时,不会立即触发close()。当您尝试向客户端写入一些消息时,会发生这种情况,但由于连接已不存在而失败。

您可能已经用这种刺杀击中了一个忍者,让我检查一下=D谢谢你!非常感谢你的想法,我真的很感激。这是我非常想知道的事情!=)#最近freenode上的gevent似乎很安静。。。谢谢你的回复,丹尼斯!我想知道,如果客户机断开连接,在WSGI应用程序中异步引发一些异常会是一个糟糕的想法吗?