最近开发的项目需要用到 socket-io,于是网上找了一段 python 编写的 socket-io 的 server 和 client 代码,把这两份代码都放到服务器上也可以正常收发数据,但是!当我将 client.py 放到本地电脑,试图去连接服务器上的 server.py 时,却迟迟连接不上,还报错 400.
client 端具体错误信息如下:
socketio.exceptions.connectionerror: unexpected status code 400 in server response
server 端打印错误如下:
"GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 400 195 0.000150
在网上查了可能是跨域问题,但是在 server.py 中加了跨域后仍然连接不上。
跨域问题解决:
sio = socketio.Server(async_mode=‘eventlet’, cors_allowed_origins=‘*’)
最后发现,启动 server 后会出现这样一小行问题,由于没有标注 Error,我几乎都忽略了这行字:
The client is using an unsupported version of the Socket.IO or Engine.IO protocols (further occurrences of this error will be logged with level INFO)
看这意思好像是说客户端的 socketio 或者 engineio 的版本与服务器上的不同。
将 client.py 所在的本地的 socketio 与 engineio 环境更新为与服务器上版本一致。
server.py
import eventlet
eventlet.monkey_patch()
import socketio
import eventlet.wsgi
sio = socketio.Server(async_mode='eventlet', cors_allowed_origins='*') # 指明在evenlet模式下
@sio.event
def connect(sid, environ):
print(f"connect, sid={sid}, environ={environ}")
@sio.event
def disconnect(sid):
print('disconnect ', sid)
@sio.on('hello')
def hello(sid, data):
print('server receive:', data)
sio.emit('world', {'data': 'world'})
app = socketio.Middleware(sio)
eventlet.wsgi.server(eventlet.listen(('', 8080)), app)
client.py
import socketio
sio = socketio.Client()
@sio.on('connect')
def on_connect():
print("client connect")
@sio.on('world')
def world(data):
print('client receive:', data)
sio.connect('http://0.0.0.0:8080')
sio.emit("hello", {"data": "hello"})
print('client send hello success')
后来在与前端联调的过程中,后端使用 python 作为 Server,前端使用 js 作为 Client,又报错 400,还是版本的问题。由于后端使用的 python-socketio 版本是 4.16,所以前端调整 socket-io 的版本为 2.x。版本对应关系如下表所示:
JavaScript Socket.IO version | Socket.IO protocol revision | Engine.IO protocol revision | python-socketio version |
---|---|---|---|
0.9.x | 1, 2 | 1, 2 | Not supported |
1.x and 2.x | 3, 4 | 3 | 4.x |
3.x and 4.x | 5 | 4 | 5.x |