2013-08-19 12 views
9

Sto usando Flask insieme gevent-socketio:gevent-socketio non usando il mio @ app.route endpoint per socketio

$ cat requirements.txt 
Flask==0.10.1 
Jinja2==2.7.1 
MarkupSafe==0.18 
Werkzeug==0.9.3 
argparse==1.2.1 
gevent==0.13.8 
gevent-socketio==0.3.5-rc2 
gevent-websocket==0.3.6 
greenlet==0.4.1 
itsdangerous==0.23 
wsgiref==0.1.2 

sto usando una configurazione piuttosto standard per avviare il server:

#Called from __main__ 
def run_dev_server(): 
    app.debug = True 
    port = 5000 
    dapp = werkzeug.debug.DebuggedApplication(app, evalex = True) 
    SocketIOServer(('', port), dapp, resource="socket.io").serve_forever() 

e un gancio abbastanza standard per la mia SocketIO namespace:

@app.route('/socket.io/<path:rest>') 
def push_stream(rest): 
    print 'ws connect', rest 
    try: 
     socketio.socketio_manage(request.environ, {'/join_notification': JoinsNamespace}, request) 
    except Exception as e: 
     app.logger.error("Exception while handling socketio connection", exc_info=True) 
    return flask.Response() 

Tuttavia, sto avendo problemi in cui 'connect' ancora Non vengono licenziate sul client. Dopo un po 'di scavo, mi sono reso conto che anche se ricevevo i messaggi 127.0.0.1 - - [2013-08-19 12:53:57] "GET /socket.io/1/websocket/170191232666 HTTP/1.1" 101 - - nell'output, non ricevevo il messaggio ws connect (mentre altre dichiarazioni di stampa nel codice funzionavano correttamente). Ho commentato quell'endpoint, e abbastanza sicuro che non è nemmeno stato chiamato. Questo spiegherebbe perché il mio spazio dei nomi non viene utilizzato. Ma perché? Sto registrando il mio spazio dei nomi sbagliato?

print app.url_map rendimenti:

Map([<Rule '/' (HEAD, OPTIONS, GET) -> root>, 
<Rule '/socket.io/<rest>' (HEAD, OPTIONS, GET) -> push_stream>, 
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>]) 

quindi nulla di straordinario.

Edit: Il codice client:

socket = io.connect('/join_notification') 
console.log(socket) 

socket.on('connect', function() { 
    console.log('connected to websocket') 
    socket.emit('login', {'name': data['name']}) 
}) 

socket.on('disconnect', function() { 
    console.log('d/c\'d from websocket') 
}) 

socket.on('join_error', function() { 
    ... 
}) 

socket.on('join_success', function(data){ 
    ... 
}) 

socket.on('join', function(data) { 
    ... 
}) 
+0

Inviare il codice client pure – leon

+0

Aggiunto il codice client. – Rotten194

+0

Se ricevi un /socket.io/1/ quando chiami Connetti, stai facendo qualcosa di sbagliato. Connect dovrebbe essere chiamato con un POST a /socket.io/1/. Omettendo il segmento successivo stai iniziando una nuova connessione.Quindi, ti sei collegato e riceverai una risposta con "roba" alla fine, il che significa che ha funzionato, oppure stai iniziando la connessione sbagliata. Ora, se funziona e non chiama il tuo codice, sei sicuro di aver inizializzato correttamente il tuo spazio dei nomi? https://gevent-socketio.readthedocs.org/en/latest/namespace.html – blakev

risposta

1

Il comportamento bizzarro è a causa di questa linea:

dapp = werkzeug.debug.DebuggedApplication(app, evalex = True) 

Socketio e il debugger werkzeug non lavorano insieme. C'è già un problema aperto a questo riguardo: https://github.com/abourget/gevent-socketio/issues/114

Ma puoi aggirare il problema creando una classe debugger personalizzata.

from werkzeug.debug import DebuggedApplication 
class MyDebuggedApplication(DebuggedApplication): 
    def __call__(self, environ, start_response): 
     # check if websocket call 
     if "wsgi.websocket" in environ and not environ["wsgi.websocket"] is None: 
      # a websocket call, no debugger ;) 
      return self.app(environ, start_response) 
     # else go on with debugger 
     return DebuggedApplication.__call__(self, environ, start_response) 

# remember to call the overwritten debugger in your run_dev_server() function 
dapp = MyDebuggedApplication(app, evalex = True) 

La patch si basa sulla wsgi.websocket ambiente-chiave, che sembra solo di essere presenti nelle chiamate websocket. Stai attento, non ci ho pensato molto, ci potrebbero essere altri problemi.

+0

Grazie! Pensavo di averlo provato, ma credo di aver sbagliato perché funzionava questa volta. – Rotten194

1

ho messo un po ', ma sembra che ho risolto, godere:

https://github.com/Aldanor/SocketIO-Flask-Debug

In poche parole:

  • è necessario estrarre in modo esplicito i valori dal generatore restituito da werkzeug.debug.DebuggedApplication ogni volta che viene individuata una richiesta socket.io, ciò consente di stabilire correttamente la connessione socket
  • socket.io i gestori dello spazio dei nomi non saranno coperti da wer kzeug per impostazione predefinita, quindi è necessario inserire il proprio try try, salvare il traceback se viene rilevata un'eccezione e quindi controrilanciare da qualche parte all'interno di un contesto di richiesta
+0

Non rispondere con il link. Spiega come risolvere il problema qui. Leggi le domande frequenti per ulteriori informazioni. –

+0

Volevo solo aiutare altre persone se non altro (visto quanto ho lottato da solo con questo problema). Il link sopra contiene un esempio funzionante con codice completamente documentato, cosa c'è di sbagliato in esso? Ad ogni modo, ha aggiornato la risposta. – aldanor

Problemi correlati