如何向所有geventwebsocket客户端广播消息

时间:2019-01-28 14:10:15

标签: python python-3.x websocket gevent

我正在使用gevent-websocket在python中设置一个geventwebscoket应用。

在与我的应用程序几乎相同的示例(聊天应用程序)中,我定义了一个处理websocket连接和消息的应用程序,如下所示:


import json

from gevent import monkey
monkey.patch_all()

from flask import Flask, render_template
from werkzeug.debug import DebuggedApplication

from geventwebsocket import WebSocketServer, WebSocketApplication, Resource

flask_app = Flask(__name__)
flask_app.debug = True


class ChatApplication(WebSocketApplication):
    def on_open(self):
        print("Some client connected!")

    def on_message(self, message):
        if message is None:
            return

        message = json.loads(message)

        if message['msg_type'] == 'message':
            self.broadcast(message)
        elif message['msg_type'] == 'update_clients':
            self.send_client_list(message)

    def send_client_list(self, message):
        current_client = self.ws.handler.active_client
        current_client.nickname = message['nickname']

        self.ws.send(json.dumps({
            'msg_type': 'update_clients',
            'clients': [
                getattr(client, 'nickname', 'anonymous')
                for client in self.ws.handler.server.clients.values()
            ]
        }))

    def broadcast(self, message):
        for client in self.ws.handler.server.clients.values():
            client.ws.send(json.dumps({
                'msg_type': 'message',
                'nickname': message['nickname'],
                'message': message['message']
            }))

    def on_close(self, reason):
        print("Connection closed!")


@flask_app.route('/')
def index():
    return render_template('index.html')

WebSocketServer(
    ('0.0.0.0', 8000),

    Resource([
        ('^/chat', ChatApplication),
        ('^/.*', DebuggedApplication(flask_app))
    ]),

    debug=False
).serve_forever()

我想在我的代码中安排一些计划的过程,这些过程向每个连接到Websocket的客户端发送消息。 在示例和有限的文档中,我找不到从项目中其他位置调用广播方法的方法。每个消息/广播都必须作为对收到消息的反应来发送(据我所知)。

我试图弄清楚它,所以每次有人访问索引页面时我都尝试广播一条消息:

@flask_app.route('/')
def index():
    chat_application = ChatApplication()
    chat_application.broadcast("A new user on the page!")
    return render_template('index.html')

这将引发错误:

chat_application = ChatApplication()
TypeError: __init__() missing 1 required positional argument: 'ws'

长话短说: 我不知道如何向websocket上的每个客户端发送消息,因为我需要ChatApplication实例来访问广播功能,而且我似乎无法弄清楚如何创建一个ChatApplication对象来让我调用该功能。

1 个答案:

答案 0 :(得分:0)

我知道了。

通过启动这样的服务器

server = WebSocketServer(
    ('0.0.0.0', 8000),

    Resource([
        ('^/chat', ChatApplication),
        ('^/.*', DebuggedApplication(flask_app))
    ]),

    debug=False
)

server.serve_forever()

您可以访问所有客户端,并向他们发送这样的消息

for client in server.clients.values():
    client.ws.send("whatever you want to send")