7

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


我想处理客户端与某些功能断开连接的情况:

例如返回“客户端已断开连接”作为其他聊天用户的消息


这可能吗?=)

4

3 回答 3

3

根据WSGI PEP,如果您的应用程序返回一个带有 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 开发服务器中)存在一个错误,该错误会阻止在中间流客户端断开连接时调用 close()。所以在这种情况下避免使用 wsgiref 和 Django 开发服务器。

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

于 2012-10-15T02:25:46.163 回答
1

这完全是在黑暗中刺伤,因为我从未使用过 gevent,但客户端不会在套接字关闭时断开连接。所以也许这样的事情会起作用:

if not Event.wait():
    # Client has disconnected, do your magic here!
    return Chat({'status': 'client x has disconnected'})
于 2010-07-26T13:02:58.243 回答
1

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

于 2010-07-26T20:55:49.620 回答