2010-07-26 3 views
7

gevent와의 채팅에 긴 폴링을 사용하고 있습니다. 새 메시지가 채팅에 게시 될 때까지 기다릴 때 Event.wait()을 사용하고 있습니다.클라이언트 연결 끊김 이벤트 캡처 중! - Gevent/Python


나는 클라이언트가 어떤 기능을을 끊 계기를 처리 싶습니다 :

예를 들어, 다른 채팅 사용자


이 가능에 대한 메시지로 "클라이언트가 연결하고있다"을 반환? =)

답변

1

사용하는 WSGI 서버에 따라 다릅니다. AFAIK gevent.wsgi는 libevent-http가 그렇게하지 않기 때문에 클라이언트가 연결을 닫을 때 어떤 방식 으로든 핸들러에 알리지 않습니다. 그러나 gevent.pywsgi를 사용하는 것이 가능해야합니다. 소켓 상태를 모니터링하고 처리기를 실행하는 greenlet에게 어떻게 든 알리기 위해 추가로 greenlet을 시작해야 할 것입니다. 그것을 죽임으로써. 나는 이것을하는 더 쉬운 방법을 놓칠 수 있었다.

+0

고맙습니다. 정말 고맙습니다. 이것은 내가 정말로 알고 싶어하는 것입니다! =) # 요즘 freenode에 요즘 꽤 침묵 것 같습니다 ... 귀하의 회신 denis 주셔서 감사합니다! – RadiantHex

+0

클라이언트가 연결이 끊어진 경우 비동기 적으로 WSGI 응용 프로그램에서 예외를 발생시키는 것은 끔찍한 생각일까요? –

1

이것은 어두운 곳에서의 총 찌르기입니다. 나는 결코 gevent를 사용하지 않았지만 소켓이 닫혀있을 때 단순히 클라이언트 연결을 끊지 않을 것입니다. 이렇게하면 다음과 같이 작동합니다.

+0

당신은 그 찌르는 닌자를 때렸을 것입니다. = D 고마워! – RadiantHex

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() 

그러나, 파이썬의 wsgiref 구현에 a bug있다 (그리고 그것에서 상속 장고 dev에 서버) 확대 방지() 중간 스트림 클라이언트 연결을 끊에서 호출되는 예를 들면 다음과 같습니다이다. 따라서 wsgiref와 Django dev 서버는이 경우에 사용하지 마십시오.

클라이언트가 연결을 끊으면 즉시 close()가 실행되지 않습니다. 클라이언트에 메시지를 쓰려고 할 때 연결이 더 이상 존재하지 않기 때문에 오류가 발생합니다.