答案 0 :(得分: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 dev服务器)中有a bug,可防止在中间客户端断开连接时调用close()。因此,请避免使用wsgiref和Django dev服务器。
另请注意,当客户端断开连接时,不会立即触发close()。当你尝试向客户端写一些消息并因为连接不再存在而失败时,就会发生这种情况。
答案 1 :(得分:1)
答案 2 :(得分:1)
这取决于您使用的WSGI服务器。当客户端关闭连接时,AFAIK gevent.wsgi不会以任何方式通知您的处理程序,因为libevent-http不会这样做。但是,使用gevent.pywsgi应该是可能的。您可能需要启动一个额外的greenlet来监视套接字条件,并以某种方式通知运行处理程序的greenlet,例如通过杀死它。我可能会错过一个更简单的方法来做到这一点。