【问题标题】:Broadcast to all connected clients except sender with python flask socketio使用 python flask socketio 向所有连接的客户端广播,但发送者除外
【发布时间】:2015-05-29 18:27:17
【问题描述】:

我正在关注 Alex Hadik 的 Flask Socketio 教程,该教程构建了一个非常简单的烧瓶聊天应用程序。

http://www.alexhadik.com/blog/2015/1/29/using-socketio-with-python-and-flask-on-heroku

我想向除发件人之外的所有已连接用户广播一条消息。我已经浏览了flasksocketio init.py,但我仍然不确定如何执行此操作。

这是服务器代码。

from flask import Flask, render_template,request
from flask.ext.socketio import SocketIO,emit,send
import json,sys

app = Flask(__name__)
socketio = SocketIO(app)
clients = {}
@app.route("/")
def index():
    return render_template('index.html',)

@socketio.on('send_message')
def handle_source(json_data):
    text = json_data['message'].encode('ascii', 'ignore')
    current_client = request.namespace
    current_client_id = request.namespace.socket.sessid
    update_client_list(current_client,current_client_id)
    if clients.keys():
        for client in clients.keys():
            if not current_client_id in client:
                clients[client].socketio.emit('echo', {'echo': 'Server Says: '+text})       

def update_client_list(current_client,current_client_id):
    if not current_client_id in clients: clients[current_client_id] = current_client
    return 

if __name__ == "__main__":
    socketio.run(app,debug = False)

目前只是向所有连接的客户端广播。我创建了一个连接的客户端字典(客户端),它存储由客户端 ID 索引的 request.namespace。 为除发送客户端之外的所有客户端调用 clients[client].socketio.emit() 仍会导致消息被广播给调用用户。

有人对我如何向除发件人以外的所有连接用户广播消息有任何想法吗?

【问题讨论】:

  • 我遇到了同样的问题,我的快速解决方案(目前)是让每个客户端在页面加载时生成一个“唯一”ID。此 ID 包含在对服务器的所有回调中。当服务器转发消息时,每个客户端都会将此 ID 与其自己的 ID 进行比较,以确定消息是由另一个客户端发送还是由它自己发送(在这种情况下,它将被忽略)。这可能不是最好的解决方案,但它对我有用。

标签: python flask socket.io


【解决方案1】:

您可以尝试使用socket.broadcast.emit 而不是socket.emit。我不确定这是否适用于 Python 库,但它是您在 Socket.io 中为 Node.js 寻找的语法。

【讨论】:

    【解决方案2】:

    我无法评论@Alex 的回复,因为我没有足够的声誉,但如果你想发出广播消息,这就是在 Python 中完成的方式:

    emit('echo', {'data':'what ever you are trying to send'},  broadcast=True)
    

    【讨论】:

    • 来自 Flask-SocketIO 参考:“在启用广播选项的情况下发送消息时,连接到命名空间的所有客户端都会收到它,包括发送者。” OP正在寻求一种向所有但原始发件人发出的方法
    • 我不太理解这种行为。根据Socket.IO reference“广播意味着向除启动它的套接字之外的其他所有人发送消息。”.
    【解决方案3】:

    您不必保存用户 ID 和管理单个发射,您可以使用 emit('my_event', {data:my_data}, broadcast=True, include_self=False) 指定没有发送者的广播。在你的情况下,它会是这样的:

    @socketio.on('send_message')
        def handle_source(json_data):
            text = json_data['message'].encode('ascii', 'ignore')
            emit('echo', {'echo': 'Server Says: '+text}, broadcast=True, include_self=False)
    

    如果您必须为特定的客户组发送消息,您可以创建rooms,然后使用emit('my_event', {data:my_data}, room=my_room, include_self=False) 向加入my_room 的客户发送消息。您可以查看flask_socketio.emit的参考以获取更多详细信息。

    【讨论】:

      【解决方案4】:

      https://flask-socketio.readthedocs.io/en/latest/#flask_socketio.SocketIO.emit

      您正在寻找socketio.emit()skip_sid 参数。

      skip_sid – 广播或广播时要忽略的客户端的会话 ID 寻址一个房间。这通常设置为 消息,以便除该客户端之外的每个人都收到消息。到 跳过多个 sid 传递一个列表。

      【讨论】:

      • 我在 python-socketio 中的广播也有问题。 skip_sid 就像一个魅力。谢谢。
      猜你喜欢
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 2023-02-01
      • 2015-07-04
      相关资源
      最近更新 更多