如何使用python-socketio实现客户端间直接通信,求具体实现示例?
你可以通过python-socketio实现客户端之间的消息发送,本质是通过服务端做中转转发,和你已知的JS版本socket.io的实现逻辑完全一致,API也高度相似。
socket.io本身没有原生的客户端直连能力,所有端到端的消息都会经过服务端中转,你之前了解的房间、广播逻辑在python-socketio中都有对应的实现,以下是完整示例:
1. 服务端实现
首先安装依赖:
pip install python-socketio eventlet
服务端代码示例:
import socketio import eventlet # 初始化socketio服务,允许跨域 sio = socketio.Server(cors_allowed_origins="*") app = socketio.WSGIApp(sio) # 客户端连接触发事件 @sio.event def connect(sid, environ): print(f"客户端 {sid} 已连接") # 可默认将新连接加入公共房间 sio.enter_room(sid, "public_room") # 处理客户端加入房间的请求 @sio.event def join_room(sid, room_name): sio.enter_room(sid, room_name) # 给房间内所有用户发送加入通知 sio.emit("room_notice", f"用户{sid}加入房间{room_name}", to=room_name) # 处理点对点私信转发 @sio.event def private_message(sid, target_sid, content): # 直接将消息转发给指定sid的客户端 sio.emit("private_msg", {"from_sid": sid, "content": content}, to=target_sid) # 处理房间广播消息转发 @sio.event def room_broadcast(sid, room_name, content): # skip_sid参数跳过消息发送者,避免自己收到自己发的广播 sio.emit("room_msg", {"from_sid": sid, "content": content}, to=room_name, skip_sid=sid) # 客户端断开连接触发事件 @sio.event def disconnect(sid): print(f"客户端 {sid} 已断开连接") if __name__ == "__main__": eventlet.wsgi.server(eventlet.listen(("", 5000)), app)
2. 客户端实现
首先安装客户端依赖:
pip install python-socketio[client]
客户端代码示例:
import socketio sio = socketio.Client() @sio.event def connect(): print("连接成功,当前客户端sid为:", sio.sid) # 接收点对点私信 @sio.event def private_msg(data): print(f"收到来自{data['from_sid']}的私信:{data['content']}") # 接收房间广播消息 @sio.event def room_msg(data): print(f"收到房间广播,来自{data['from_sid']}:{data['content']}") # 接收房间通知 @sio.event def room_notice(content): print("房间通知:", content) @sio.event def disconnect(): print("已断开与服务端的连接") if __name__ == "__main__": sio.connect("http://localhost:5000") # 示例:加入自定义房间 sio.emit("join_room", "game_room_1") # 示例:给指定sid的客户端发私信,替换为目标客户端的sid即可 # sio.emit("private_message", ("target_client_sid", "这是一条私信")) # 示例:给指定房间发广播 # sio.emit("room_broadcast", ("game_room_1", "大家好呀")) sio.wait()
JS API对应关系
你之前使用的JS版本API和python-socketio的对应关系如下:
- JS的
socket.join('room')对应python服务端的sio.enter_room(sid, 'room'),客户端只需发起事件请求服务端执行对应操作即可 - JS的
io.sockets.in('room').emit('event_name', data)对应python服务端的sio.emit('event_name', data, to='room'),如需排除发送者自己可额外加skip_sid=sid参数
内容的提问来源于stack exchange,提问作者XDGFX
相关产品推荐
相关产品推荐

