2013-02-17 16 views
6

Używam gevent-websocket z bottle.py do obsługi plików dziennika. Jak mogę wykryć, że połączenie websocket jest zamknięte od strony klienta?Gevent-Websocket Wykrywanie zamkniętego połączenia

W tej chwili jestem po prostu pisanie dopóki nie dostanę złamaną błąd rurze:

return sock.send(data, flags) 
error: [Errno 32] Broken pipe 

Ale chciałbym poprawnie wykryć na serwerze, jeśli klient zamknął połączenie websocket.

Mój kod wygląda następująco:

from geventwebsocket.handler import WebSocketHandler 
from gevent.pywsgi import WSGIServer 
import gevent.monkey 
gevent.monkey.patch_all() 
from bottle import route, Bottle, view, request, static_file 
import json 
import os 
import time 

app = Bottle() 

# Other code 

@app.route('/websocket/<filename>') 
def ws_logfile(filename): 
    if request.environ.get('wsgi.websocket'): 
     ws = request.environ['wsgi.websocket'] 
     try: 
      filename = os.path.join(os.getcwd(), "logfiles", filename) 
      logfile = file(filename) 
      lines = logfile.readlines() 
      for line in lines: 
       ws.send(json.dumps({'output': line})) 

      while True: 
       line = logfile.readline() 
       if line: 
        # Here detect if connection is closed 
        # form client then break out of the while loop 
        ws.send(json.dumps({'output': line})) 
       else: 
        time.sleep(1) 
      ws.close() 

     except geventwebsocket.WebSocketError, ex: 
      print "connection closed" 
      print '%s: %s' % (ex.__class__.__name__, ex) 

if __name__ == '__main__': 
    http_server = WSGIServer(('127.0.0.1', 8000), app, handler_class=WebSocketHandler) 
    http_server.serve_forever() 

i odpowiedni klient kod javascript:

jQuery(document).ready(function(){ 
     ws = $.gracefulWebSocket("ws://" + document.location.host + "/websocket" + document.location.pathname); 

     ws.onmessage = function (msg) { 
     var message = JSON.parse(msg.data); 
     $("#log").append(message.output + "<br>"); 
     }; 

     window.onbeforeunload = function() { 
     ws.onclose = function() {console.log('unlodad')}; 
     ws.close() 
     }; 
}); 

Wszelkie inne ulepszenia mojego kodu lub rozwiązania są mile widziane.

Odpowiedz

7

Spróbuj przetestować pod kątem if ws.socket is not None: przed wysłaniem danych na gniazdo.

+3

Lepiej prosić o przebaczenie niż o pozwolenie. Nadal istnieje stan wyścigu. – warvariuc

Powiązane problemy