You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask-SocketIO通过sid推送消息客户端无法接收问题

Flask-SocketIO 按sid推送消息客户端无法接收问题修复

问题现象

客户端可正常连接服务端,服务端也能成功获取到客户端对应的sid,但尝试通过sid向客户端推送消息时,客户端无法接收到任何来自服务端的消息。

本人英语水平有限,敬请谅解。

原有问题代码

服务端 server.py

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
tokenList = {}


@app.route("/test")
def testConnect():
    sid = tokenList["114514"]
    print(sid)
    emit('newMission', {'from': 'server'}, namespace="newMission", to=sid)
    return 'success'


@socketio.on('register')
def register(data):
    print("服务器%s尝试注册" % data["secret"])
    emit('register', {"token": "1919810"})
    print("注册成功,token为%s" % "1919810")
    sid = request.sid
    join_room("mainRoom")
    tokenList["114514"] = sid


"""@socketio.on('message')
def message(data):
    print(data)  # {'from': 'client'}
    emit('response', {'from': 'server'})
    sleep(5)
    emit('response', "exit")"""

if __name__ == '__main__':
    socketio.run(app, debug=True, host='127.0.0.1', port=8090)

客户端 client.py

import socketio

sio = socketio.Client()


@sio.event()
def connect():
    print('正在注册,请稍后')
    sio.emit('register', {'secret': '114514'})


@sio.on('register')
def isReg(data):
    print("注册成功,当前token为" + data["token"])


@sio.on("newMission", namespace="message")
def newMission(data):
    print(data)


sio.connect('ws://localhost:8090')
sio.wait()

问题根因

  • 核心错误是命名空间不匹配:服务端发送newMission事件时指定命名空间为newMission,客户端监听该事件时绑定的命名空间为message,且客户端从未连接过这两个自定义命名空间,所有连接、事件交互默认都在根命名空间/下,消息根本无法路由到客户端的监听函数。
  • 普通HTTP路由(/test接口)不属于SocketIO事件上下文,直接调用事件上下文专属的emit()方法会出现上下文缺失问题,无法正确推送消息。

修复方案

  • 无特殊多命名空间需求时,全部使用默认根命名空间,删除所有事件发送、监听处错误的自定义namespace参数;如果必须使用自定义命名空间,需保证客户端连接、事件监听、服务端事件发送三处的命名空间字符串完全一致。
  • 在普通HTTP路由中推送SocketIO消息时,使用初始化得到的socketio实例的emit方法,不要直接使用上下文中的emit。

修复后服务端代码

from flask import Flask, request
from flask_socketio import SocketIO, emit, join_room

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
tokenList = {}


@app.route("/test")
def testConnect():
    sid = tokenList["114514"]
    print(sid)
    # 普通路由调用socketio实例的emit方法,移除错误的namespace参数
    socketio.emit('newMission', {'from': 'server'}, to=sid)
    return 'success'


@socketio.on('register')
def register(data):
    print("客户端%s尝试注册" % data["secret"])
    emit('register', {"token": "1919810"})
    print("注册成功,token为%s" % "1919810")
    sid = request.sid
    join_room("mainRoom")
    tokenList["114514"] = sid


if __name__ == '__main__':
    socketio.run(app, debug=True, host='127.0.0.1', port=8090)

修复后客户端代码

import socketio

sio = socketio.Client()


@sio.event()
def connect():
    print('正在注册,请稍后')
    sio.emit('register', {'secret': '114514'})


@sio.on('register')
def isReg(data):
    print("注册成功,当前token为" + data["token"])


# 移除错误的namespace参数,和服务端发送事件的命名空间保持一致
@sio.on("newMission")
def newMission(data):
    print("收到服务端推送:", data)


sio.connect('ws://localhost:8090')
sio.wait()

修复后启动服务,访问http://127.0.0.1:8090/test,客户端即可正常收到推送的newMission事件消息。

内容的提问来源于stack exchange,提问作者IcyCoffee4513

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:18:14