总结问题
我正在使用该python-socketio
软件包作为我正在创建的基于 Web 的游戏的服务器。我最初在 Python 中实现客户端(带有python-socketio[client]
)用于调试目的,并在开发时广泛使用该Server.call()
方法。这与在 Python 中运行的所有内容完美配合,并且在将客户端函数的返回值发送回服务器之前等待用户输入。
但是,当尝试将事情切换到 JavaScript 时,Server.call()
无论我做什么都会超时。我真的不知道我可以切换到任何替代方案,而不必完全破坏我已经实施的程序,但我愿意接受建议。
描述你尝试过的东西
我尝试在 JavaScript 中重新实现我的 Python 客户端代码,或多或少与最初编写的完全一致。这是一个失败,因为正如我在上面提到的任何时候我使用Server.call()
它超时(或者如果我设置无限期挂起timeout=None
)。
我还尝试过切换Server.call()
,而是使用Server.emit()
回调来设置全局变量,然后阻塞直到使用 设置Server.sleep()
,但这似乎也不起作用。
显示一些代码
这是一个演示该问题的最小示例。服务器在两个用例中是相同的,Python 客户端和 JavaScript 客户端实际上是相同的,但只有在使用 Python 客户端时才有效。
这是服务器,用 Python 编写并使用python-socketio
模块:
# 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