【问题标题】:Tornado websocket modelTornado websocket 模型
【发布时间】:2016-11-30 18:38:45
【问题描述】:

我对 Python 不是很熟悉,而且对 Tornado websockets 很陌生,所以我很难理解它是如何工作的。

具体来说,这是一个常见的例子:

class EchoWebSocket(tornado.websocket.WebSocketHandler):
    def open(self):
        print("WebSocket opened")

    def on_message(self, message):
        self.write_message(u"You said: " + message)

    def on_close(self):
        print("WebSocket closed")

让我感到困惑的是请求的处理方式。我读到 Tornado 是非阻塞的,如果理解得很好是单线程的,每个请求都由处理程序以快速的方式处理,如果操作持续更长时间,那么当某些操作(例如数据库)完成时会调用回调.这允许为大量用户提供服务。但是让我对这些 websocket 和示例感到困惑的是,在这种情况下,self 是什么?

我知道在 Java 和 C# 中它类似于 this,但我不明白每次客户端发送消息时 this self 如何代表不同的客户端?此外,每个应用程序只有一个 EchoWebSocket 实例,还是每个请求都有一个实例?

此外,我应该如何保留对客户的引用?我尝试了两种方法:

class EchoWebSocket(tornado.websocket.WebSocketHandler):

    clients = []

    def open(self):
        print("WebSocket opened")

    def on_message(self, message):
        EchoWebSocket.clients.append(self)
        self.write_message(u"You said: " + message)

    def on_close(self):
        print("WebSocket closed")

class EchoWebSocket(tornado.websocket.WebSocketHandler):

    def __init__(self, application, request):
        super(EchoWebSocket,self).__init__(application, request)
        self.clients = []

    def open(self):
        print("WebSocket opened")

    def on_message(self, message):
        self.clients.append(self)
        self.write_message(u"You said: " + message)


    def on_close(self):
        print("WebSocket closed")

但第二种方法似乎不起作用。什么是正确的方法,为什么?

【问题讨论】:

    标签: python websocket tornado


    【解决方案1】:

    在 python 中,按照惯例,self 是对当前类的实例对象的引用。

    AFAIK,tornado 框架为每个客户端创建类 WebSocketHandler 的实例。因此,您实际上不必保留对客户的参考。每个客户端自然由处理程序的不同实例处理。实际上,这意味着self 将是两个不同客户端的不同对象。

    要保留对已连接客户端的引用,类似的方法会起作用:

    class EchoWebSocket(tornado.websocket.WebSocketHandler):
        all_clients = set()
    
        def open(self):
            self.all_clients.add(self)
    
        def on_message(self, message):
            pass
    
        def on_close(self):
            self.all_clients.remove(self)
    

    【讨论】:

    • 感谢您的回答。现在对我来说更清楚了。但是,如果我想从一个客户端向所有其他客户端广播消息,我必须保留所有客户端的列表,所以第一种方法使用类变量是正确的。
    猜你喜欢
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    • 2016-03-11
    相关资源
    最近更新 更多