发送给特定用户的 SocketIO(无需为每个客户端使用单独的空间)
SocketIO to emit to a particular user (without using separate room for every client)
我正在尝试开发一个在后端支持长时间任务的 Web 应用程序。我在我的服务器上使用 flask-socketio
包和芹菜。我的工作流程如下:
- 当客户端打开 Html 页面时——我启动到服务器的套接字连接,服务器为用户创建一个 uid 并将其发回。
- 现在,一旦用户 post 发出对长任务的请求 -- 我使用 celery 安排它,完成后我需要将它发送给 post 发出请求的用户。 (我在post请求中存储了相关的userid)
我查看了@Miguels 对 的回答,它为每个用户创建了一个单独的房间,然后在该房间广播消息。但我想问一下是否有其他更简单的方法来做到这一点,因为这样做似乎效率低下或被迫。
我还遇到了 nodejs 解决方案 (how-to-send-a-message-to-a-particular-client-with-socket-io),我认为这是一种更自然的实现方式。 python-socketio 中是否也有类似的解决方案?
更新:经过更多搜索后,我在 github 要点上找到了 following solution。据此 -- ** flash-socketIO 已经将所有客户端放在 request.sid
** 给出的单独房间中。
我仍然希望讨论其他方法来做到这一点。 特别是如果站点访问量很高——会不会导致房间太多?
更新 (2):我当前的(工作)服务器代码,它使用房间。这是从flask-SocketIO celery example
借用和修改的
@celery.task(bind=True)
def long_task(self, userid, url):
# LONG TASK
time.sleep(10)
# meta = some result
post(url, json=meta)
# It seems i can't directly emit from celery function so I mimic a post request and emit from that function
return meta
@app.route('/longtask', methods=['POST'])
def longtask():
userid = request.json['userid']
task = long_task.delay(elementid, userid, url_for('event', _external=True))
return jsonify({}), 202
@socketio.on('connect', namespace='/custom')
def events_connect():
userid = str(uuid.uuid4())
session['userid'] = userid
current_app.clients[userid] = request.sid
emit('userid', {'userid': userid})
@app.route('/event/', methods=['POST'])
def event():
userid = request.json['userid']
data = request.json
roomid = app.clients.get(userid)
socketio.emit('celerystatus', data, namespace='/custom', room=roomid)
return 'ok'
您可以为每个单独的用户创建一个房间。您可以将消息发送到特定的房间,让哪个用户分享消息。
io.to(user.room).emit('specific-user', { message });
这里的意思是将用户房间分开,你需要定义一个房间id到一个聊天室,就像聊天应用程序(一对一通信)。
房间 ID 可以由您自己的 ID 和用户 ID 组成,您希望为每个用户发送一条消息以获得唯一的房间 ID。
您不必创建任何房间来解决单个用户。只需将 to
参数设置为您要寻址的用户的 sid
:
emit('my event', my_data, to=user_sid)
分配给每个用户的 sid
值在 connect
事件处理程序中作为 request.sid
提供给您。
我正在尝试开发一个在后端支持长时间任务的 Web 应用程序。我在我的服务器上使用 flask-socketio
包和芹菜。我的工作流程如下:
- 当客户端打开 Html 页面时——我启动到服务器的套接字连接,服务器为用户创建一个 uid 并将其发回。
- 现在,一旦用户 post 发出对长任务的请求 -- 我使用 celery 安排它,完成后我需要将它发送给 post 发出请求的用户。 (我在post请求中存储了相关的userid)
我查看了@Miguels 对
我还遇到了 nodejs 解决方案 (how-to-send-a-message-to-a-particular-client-with-socket-io),我认为这是一种更自然的实现方式。 python-socketio 中是否也有类似的解决方案?
更新:经过更多搜索后,我在 github 要点上找到了 following solution。据此 -- ** flash-socketIO 已经将所有客户端放在 request.sid
** 给出的单独房间中。
我仍然希望讨论其他方法来做到这一点。 特别是如果站点访问量很高——会不会导致房间太多?
更新 (2):我当前的(工作)服务器代码,它使用房间。这是从flask-SocketIO celery example
借用和修改的@celery.task(bind=True)
def long_task(self, userid, url):
# LONG TASK
time.sleep(10)
# meta = some result
post(url, json=meta)
# It seems i can't directly emit from celery function so I mimic a post request and emit from that function
return meta
@app.route('/longtask', methods=['POST'])
def longtask():
userid = request.json['userid']
task = long_task.delay(elementid, userid, url_for('event', _external=True))
return jsonify({}), 202
@socketio.on('connect', namespace='/custom')
def events_connect():
userid = str(uuid.uuid4())
session['userid'] = userid
current_app.clients[userid] = request.sid
emit('userid', {'userid': userid})
@app.route('/event/', methods=['POST'])
def event():
userid = request.json['userid']
data = request.json
roomid = app.clients.get(userid)
socketio.emit('celerystatus', data, namespace='/custom', room=roomid)
return 'ok'
您可以为每个单独的用户创建一个房间。您可以将消息发送到特定的房间,让哪个用户分享消息。
io.to(user.room).emit('specific-user', { message });
这里的意思是将用户房间分开,你需要定义一个房间id到一个聊天室,就像聊天应用程序(一对一通信)。 房间 ID 可以由您自己的 ID 和用户 ID 组成,您希望为每个用户发送一条消息以获得唯一的房间 ID。
您不必创建任何房间来解决单个用户。只需将 to
参数设置为您要寻址的用户的 sid
:
emit('my event', my_data, to=user_sid)
分配给每个用户的 sid
值在 connect
事件处理程序中作为 request.sid
提供给您。