python 使用 python-socketio 400 错误

齐磊
2023-12-01

背景描述

最近开发的项目需要用到 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')

server 与 client 版本对应关系

后来在与前端联调的过程中,后端使用 python 作为 Server,前端使用 js 作为 Client,又报错 400,还是版本的问题。由于后端使用的 python-socketio 版本是 4.16,所以前端调整 socket-io 的版本为 2.x。版本对应关系如下表所示:

JavaScript Socket.IO versionSocket.IO protocol revisionEngine.IO protocol revisionpython-socketio version
0.9.x1, 21, 2Not supported
1.x and 2.x3, 434.x
3.x and 4.x545.x

参考链接:https://github.com/miguelgrinberg/python-socketio

 类似资料: