問題を要約する
python-socketio
作成中の Web ベースのゲームのサーバーとしてパッケージを使用しています。python-socketio[client]
私は当初、デバッグ目的でクライアントを Python で ( を使用して) 実装し、Server.call()
開発中にこのメソッドを広範囲に使用しました。これは、Python で実行されているすべてのものと完全に連携し、クライアント側の関数の戻り値をサーバーに送信する前に、ユーザーの入力を待ちます。
しかし、JavaScriptに切り替えようとすると、Server.call()
何をしてもタイムアウトしてしまいます。既に実装されているプログラムを完全にバラバラにすることなく切り替えることができる代替手段についてはよく知りませんが、提案は受け付けています。
あなたが試したことを説明してください
私は Python クライアント コードを JavaScript で再実装しようとしましたが、最初に書かれたとおりに多かれ少なかれ正確です。Server.call()
上で述べたように、使用するたびにタイムアウトする(または設定すると無期限にハングする)ため、これは失敗でしたtimeout=None
。
Server.call()
さらに、コールバックを使用Server.emit()
してグローバル変数を設定し、使用して設定されるまでブロックすることから切り替えようとしましServer.sleep()
たが、これも機能しないようです。
コードを表示する
この問題を示す最小限の例を次に示します。サーバーは両方のユースケースで同じであり、Python クライアントと JavaScript クライアントは実質的に同じですが、Python クライアントを使用している場合にのみ機能します。
python-socketio
Python で記述され、モジュールを使用するサーバーは次のとおりです。
# server.py
from socketio import Server, WSGIApp
socketio = Server(async_mode='eventlet', async_handlers=True, cors_allowed_origins='*')
@socketio.on('start')
def start(sid):
name = socketio.call('get name', to=sid)
print(name)
if __name__ == '__main__':
app = WSGIApp(socketio)
import eventlet
eventlet.wsgi.server(eventlet.listen(('0.0.0.0', 5000)), app)
動作中の Python クライアントは次のとおりです。
# client.py
import socketio
sio = socketio.Client()
@sio.event
def connect():
sio.emit('start')
@sio.on('get name')
def get_name():
print('Sending name')
return 'Hermione Granger'
if __name__ == '__main__':
sio.connect('http://localhost:5000', transports=['websocket'])
これは、動作しない JavaScript クライアントとそれに対応する HTML です。
// client.js
var socket = io.connect('http://localhost:5000');
socket.on('connect', function () {
socket.emit('start');
});
socket.on('get name', function () {
console.log('Sending name');
return 'Hermione Granger';
});
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script src="client.js"></script>
</body>
</html>
なぜこれが機能しないのかを理解するのを手伝ってくれる人がいる場合 (または簡単な代替案を推奨する場合)、私はあなたに大いに感謝します! :)
サーバーからのログ出力
JavaScript クライアントを実行しようとしたときのサーバー ログは次のとおりです。
Server initialized for eventlet.
(16261) wsgi starting up on http://0.0.0.0:5000
(16261) accepted ('127.0.0.1', 63733)
2bff7607e60548e5ba70b2dcabb6131d: Sending packet OPEN data {'sid': '2bff7607e60548e5ba70b2dcabb6131d', 'upgrades': [], 'pingTimeout': 60000, 'pingInterval': 25000}
2bff7607e60548e5ba70b2dcabb6131d: Sending packet MESSAGE data 0
2bff7607e60548e5ba70b2dcabb6131d: Received request to upgrade to websocket
2bff7607e60548e5ba70b2dcabb6131d: Upgrade to websocket successful
2bff7607e60548e5ba70b2dcabb6131d: Received packet MESSAGE data 2["start"]
received event "start" from 2bff7607e60548e5ba70b2dcabb6131d [/]
emitting event "get name" to 2bff7607e60548e5ba70b2dcabb6131d [/]
2bff7607e60548e5ba70b2dcabb6131d: Sending packet MESSAGE data 21["get name"]
2bff7607e60548e5ba70b2dcabb6131d: Received packet PING data None
2bff7607e60548e5ba70b2dcabb6131d: Sending packet PONG data None
2bff7607e60548e5ba70b2dcabb6131d: Received packet PING data None
2bff7607e60548e5ba70b2dcabb6131d: Sending packet PONG data None
Exception in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/mnt/c/Users/eshap/Documents/GitHub/dominion-game/venv/lib/python3.8/site-packages/socketio/server.py", line 685, in _handle_event_internal
r = server._trigger_event(data[0], namespace, sid, *data[1:])
File "/mnt/c/Users/eshap/Documents/GitHub/dominion-game/venv/lib/python3.8/site-packages/socketio/server.py", line 714, in _trigger_event
return self.handlers[namespace][event](*args)
File "server.py", line 7, in start
name = socketio.call('get name', to=sid)
File "/mnt/c/Users/eshap/Documents/GitHub/dominion-game/venv/lib/python3.8/site-packages/socketio/server.py", line 386, in call
raise exceptions.TimeoutError()
socketio.exceptions.TimeoutError
比較のために、Python クライアントを正常に実行したときのサーバー ログを次に示します。
Server initialized for eventlet.
(14184) wsgi starting up on http://0.0.0.0:5000
(14184) accepted ('127.0.0.1', 54749)
a5f56db4733b4b1b924b0cb2a599e7c6: Sending packet OPEN data {'sid': 'a5f56db4733b4b1b924b0cb2a599e7c6', 'upgrades': [], 'pingTimeout': 60000, 'pingInterval': 25000}
a5f56db4733b4b1b924b0cb2a599e7c6: Sending packet MESSAGE data 0
a5f56db4733b4b1b924b0cb2a599e7c6: Received request to upgrade to websocket
a5f56db4733b4b1b924b0cb2a599e7c6: Upgrade to websocket successful
a5f56db4733b4b1b924b0cb2a599e7c6: Received packet PING data None
a5f56db4733b4b1b924b0cb2a599e7c6: Sending packet PONG data None
a5f56db4733b4b1b924b0cb2a599e7c6: Received packet MESSAGE data 2["start"]
received event "start" from a5f56db4733b4b1b924b0cb2a599e7c6 [/]
emitting event "get name" to a5f56db4733b4b1b924b0cb2a599e7c6 [/]
a5f56db4733b4b1b924b0cb2a599e7c6: Sending packet MESSAGE data 21["get name"]
a5f56db4733b4b1b924b0cb2a599e7c6: Received packet MESSAGE data 31["Hermione Granger"]
received ack from a5f56db4733b4b1b924b0cb2a599e7c6 [/]
Hermione Granger