如何让Python-SocketIO客户端阻塞至收到服务器事件响应?
Python Socket.IO客户端阻塞等待自定义响应事件问题解决
问题根源
你用sio.call()导致永久阻塞的原因很明确:call()方法是为请求-ACK响应模式设计的,它会一直等待服务器通过ACK机制回复,而你的服务器是发送homePage这个自定义事件来回应getHome请求,并非标准ACK,所以客户端会无限等待ACK,卡死在那里。
正确实现方式:emit + wait_for
要实现发送请求后阻塞等待自定义响应事件,应该用sio.emit()发送事件,再配合sio.wait_for()方法阻塞等待目标响应事件。这样能严格保证顺序执行,收到响应后再进行下一步操作。
修改后的完整代码
#!/usr/bin/python3 import socketio sio = socketio.Client() # 用于暂存服务器返回的响应数据 home_response = None @sio.event def message(data): print(data) @sio.event def homePage(data): global home_response home_response = data print(data) if __name__ == "__main__": sio.connect('http://docedit/socket.io/') print("First call") sio.emit("getHome") # 阻塞等待homePage事件,可设置超时时间防止无限等待 sio.wait_for('homePage', timeout=10) # 这里可以根据home_response做后续逻辑处理 print("Received first response, proceeding to second call") print("Second call") sio.emit("getHome") sio.wait_for('homePage', timeout=10) sio.disconnect()
关键细节
wait_for('homePage')会暂停当前线程,直到收到服务器的homePage事件,或者触发超时(建议设置timeout参数,避免因服务器异常导致永久阻塞)。- 用全局变量
home_response存储响应数据,方便后续业务逻辑使用;如果不需要留存数据,也可以直接在homePage事件处理函数内完成所有处理。 - 每次发送
getHome事件后,都要调用wait_for,确保请求和响应严格按顺序执行。
可选方案:修改服务器适配call()
如果你坚持想用sio.call(),需要修改Node.js服务器的响应逻辑,改用ACK回调返回数据,而不是发送自定义事件。服务器端示例代码如下:
// Node.js服务器端代码 io.on('connection', (socket) => { socket.on('getHome', (ackCallback) => { // 处理获取首页数据的逻辑 const homeData = "Welcome to Home"; // 通过ACK回调把数据返回给客户端 ackCallback(homeData); }); });
此时客户端的call()就能正常获取返回值,代码如下:
#!/usr/bin/python3 import socketio sio = socketio.Client() @sio.event def message(data): print(data) sio.connect('http://docedit/socket.io/') print("First call") # call()会阻塞直到收到ACK响应,并返回服务器的数据 response = sio.call("getHome") print(response) # 输出: Welcome to Home print("Second call") response = sio.call("getHome") print(response) sio.disconnect()
内容的提问来源于stack exchange,提问作者Nooneye
相关产品推荐
相关产品推荐

