9

私は gevent-socketio と一緒に Flask を使用しています:

$ 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

私はかなり標準的なセットアップを使用してサーバーを起動しています:

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

そして、私の SocketIO 名前空間のかなり標準的なフック:

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

ただし、「接続」イベントがクライアントで発生しないという問題があります。少し掘り下げた後、127.0.0.1 - - [2013-08-19 12:53:57] "GET /socket.io/1/websocket/170191232666 HTTP/1.1" 101 - -出力にメッセージが表示されていても、メッセージが表示されていないことに気付きws connectました (コード内の他の print ステートメントは正常に機能していました)。そのエンドポイントをコメントアウトしましたが、確かにそれは呼び出されていません。それは、私の名前空間が使用されていない理由を説明します。しかし、なぜ?名前空間の登録が間違っていますか?

print app.url_map収量:

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

だから何も異常なことはありません。

編集:クライアントコード:

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) {
    ...
})
4

2 に答える 2

1

しばらく時間がかかりましたが、解決したようです。お楽しみください:

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

手短に:

  • socket.io リクエストが検出されるたびに、werkzeug.debug.DebuggedApplication によって返されるジェネレーターから値を明示的に抽出する必要があります。これにより、ソケット接続を適切に確立できます。
  • socket.io 名前空間ハンドラーは、デフォルトでは werkzeug によってカバーされないため、独自の try catch を挿入し、例外がキャッチされた場合はトレースバックを保存してから、リクエスト コンテキスト内のどこかでそれを再発生させる必要があります。
于 2013-09-29T14:44:18.463 に答える