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

如何在SocketIO及Flask-SocketIO中向单个或两个客户端发送事件

嘿,这个问题我刚好熟!在Flask-SocketIO里给单个或指定几个客户端发消息,核心就是利用**客户端会话ID(sid)和房间(room)**这两个机制,我给你拆解成具体步骤和实用例子:

一、给单个客户端发送事件

每个客户端连接到服务器后,都会被分配一个唯一的sid(会话ID),我们只要拿到这个sid,就能精准给它发消息。

1. 先记录客户端的sid(关联用户)

通常我们会把用户ID和对应的sid存在一个映射里,方便后续查找:

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

app = Flask(__name__)
# 解决跨域问题,根据你的实际情况调整
socketio = SocketIO(app, cors_allowed_origins="*")

# 存储用户ID到sid的映射
user_sid_map = {}

@socketio.on('connect')
def handle_connect():
    current_sid = request.sid
    print(f"客户端 {current_sid} 已上线")

# 监听客户端的登录事件,绑定用户ID和sid
@socketio.on('user_login')
def handle_user_login(user_id):
    user_sid_map[user_id] = request.sid
    # 给当前登录的客户端发确认消息
    emit('login_confirm', {'msg': f'欢迎回来,用户{user_id}'}, to=request.sid)

2. 定向给单个客户端发消息

比如要给用户ID为10086的客户端发私有消息:

# 先从映射里拿到目标sid
target_sid = user_sid_map.get('10086')
if target_sid:
    # 使用socketio.emit指定to参数为目标sid
    socketio.emit(
        'private_msg',
        {'content': '这是只有你能收到的消息'},
        to=target_sid
    )
二、给指定的两个客户端发送事件

这里有两种优雅的实现方式,看你需求选:

方法1:分别给两个sid发送

如果只是偶尔给固定两个用户发消息,直接两次定向发送就行:

# 假设要给userA和userB发消息
userA_sid = user_sid_map.get('userA')
userB_sid = user_sid_map.get('userB')

if userA_sid and userB_sid:
    # 给两个客户端分别发送相同的事件
    socketio.emit('two_person_msg', {'content': '这是给你们俩的专属消息'}, to=userA_sid)
    socketio.emit('two_person_msg', {'content': '这是给你们俩的专属消息'}, to=userB_sid)

方法2:创建临时房间(更优雅)

如果这两个用户需要频繁互动,用临时房间更方便——把两个sid加入同一个房间,直接给房间发消息,房间里的所有客户端都会收到:

userA_sid = user_sid_map.get('userA')
userB_sid = user_sid_map.get('userB')

if userA_sid and userB_sid:
    # 创建一个唯一的房间名
    temp_room = f"chat_between_{userA}_and_{userB}"
    # 把两个客户端加入房间
    socketio.server.enter_room(userA_sid, temp_room)
    socketio.server.enter_room(userB_sid, temp_room)
    
    # 给房间发消息,两个客户端都会收到
    socketio.emit('room_msg', {'content': '房间专属消息'}, to=temp_room)
    
    # 用完可以让客户端退出房间,节省资源
    socketio.server.leave_room(userA_sid, temp_room)
    socketio.server.leave_room(userB_sid, temp_room)
重要注意事项
  • 客户端断开连接时,记得从user_sid_map里移除对应的条目,避免发送无效sid:
@socketio.on('disconnect')
def handle_disconnect():
    # 遍历找到当前sid对应的用户ID并删除
    for user_id, sid in list(user_sid_map.items()):
        if sid == request.sid:
            del user_sid_map[user_id]
            break
    print(f"客户端 {request.sid} 已下线")
  • 如果是在Flask视图函数里发送消息,一定要用socketio.emit而不是emit——后者默认只给当前上下文的客户端发,前者是全局发送。

这些都是Flask-SocketIO官方支持的标准用法,灵活组合就能搞定各种定向消息需求啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:59:56