我正在尝试开发一个支持后端长任务的网络应用程序。我在用flask-socketio
与芹菜一起打包在我的服务器上。我的工作流程如下:
- 当客户端打开 Html 页面时,我启动到服务器的套接字连接,该连接为用户创建一个 uid 并将其发回。
- 现在,一旦用户发布了对长任务的请求——我使用 celery 来安排它,一旦完成,我需要将其发送给发布请求的用户。 (我在post请求中存储了相关的userid)
我看过@Miguels 的回答39423646/flask-socketio-emit-to-特定用户 https://stackoverflow.com/questions/39423646/flask-socketio-emit-to-specific-user它为每个用户创建一个单独的房间,然后在该房间上广播消息。但我想问是否有其他更简单的方法来做到这一点,因为它似乎效率低下或强制的方式来做到这一点。
我还遇到了nodejs解决方案(如何使用套接字 io 向特定客户端发送消息 https://stackoverflow.com/questions/17476294/how-to-send-a-message-to-a-particular-client-with-socket-io)我觉得这是实现这一目标的更自然的方式。 python-socketio 中也有类似的解决方案吗?
Update: 经过一番搜索,我发现了以下解决方案 https://gist.github.com/ericremoreynolds/dbea9361a97179379f3b#gistcomment-1730314在 github 要点上。据此 -- ** flash-socketIO 已经将所有客户端放在由request.sid
**.
我仍然希望讨论其他方法来做到这一点。具体来说,如果网站流量相当高,是否会导致房间过多?
更新(2): 我当前的(工作)服务器代码使用房间。这是借用并修改的Flask-SocketIO celery 示例 https://github.com/jwhelland/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'