tornado Websocket Server:如何创建一个新对象以将 on_message 发送到该对象?

Posted

技术标签:

【中文标题】tornado Websocket Server:如何创建一个新对象以将 on_message 发送到该对象?【英文标题】:tornado Websocket Server: How to create a new object for sending on_message to this object? 【发布时间】:2017-05-07 11:44:29 【问题描述】:

我实际上尝试将接收到的消息(通过 tornado websocket)发送到特定对象。

我的代码如下所示:

clients = dict()

class WebServer(object):
    def __init__(self, port=8080):

        define("port", default=port, help="Run on the given port", type=int)

        app = tornado.web.Application([
        (r'/', IndexHandler),
        (r'/(?P<Id>\w*)', MyWebSocketHandler),
        (r"/static/(.*)", tornado.web.StaticFileHandler, 'path':'static/'),
        #(r'/ws', MyWebSocketHandler),
        ])

        print("DSP Control Application | Browse to <IP>:"+str(port)+" and have fun!")

        parse_command_line()
        app.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()


class IndexHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self, **kwargs):
        if "Id" in kwargs.keys():
            print "Your client id is: %s" % (kwargs["Id"],)
        self.render("index.html")
        #self.finish()


class MyWebSocketHandler(tornado.websocket.WebSocketHandler):

    def open(self, *args, **kwargs):
        self.id = kwargs["Id"]
        self.stream.set_nodelay(True)
        clients[self.id] = "id": self.id, "object": self

    def on_message(self, message):
        print "Client %s received a message: %s" % (self.id, message)
        #self.write_message("Client id: %s" % (list,))


    def on_close(self):
        if self.id in clients:
            del clients[self.id]

    def check_origin(self, origin):
        return True


if __name__ == "__main__":

    server = WebServer()

它主要是已经可以运行的基本 Tornado websocket 应用程序。每次客户端连接到我的服务器时,on_message 函数都会向控制台打印一条消息。到目前为止一切顺利...

但现在我想从我的控件类中实例化一个新对象。 on_message 函数应该将接收到的消息提供给该对象。

我正在像这样实例化对象:

class WebServer(object):
    def __init__(self, port=8080):

        define("port", default=port, help="Run on the given port", type=int)

        # Instantiate a new Object from class "Control"
        mycontrol = Control()

        app = tornado.web.Application([
        (r'/', IndexHandler),
        (r'/(?P<Id>\w*)', MyWebSocketHandler),
        (r"/static/(.*)", tornado.web.StaticFileHandler, 'path':'static/'),
        #(r'/ws', MyWebSocketHandler),
        ])

        ...

但是如何告诉MyWebSocketHandler()他需要在收到消息时调用mycontrol。我发现没有办法将这个对象交给 app 对象。

你能帮我解决这个问题吗?

问候 博斯蒂

【问题讨论】:

【参考方案1】:

您可以在应用程序创建步骤将默认 kwargs 传递给您的MyWebSocketHandler, kwargs 将被传递给您的处理程序http://www.tornadoweb.org/en/stable//web.html#tornado.web.RequestHandler.initialize 的initialize 方法@

class WebServer(object):
    def __init__(self, port=8080):

        define("port", default=port, help="Run on the given port", type=int)

        mycontrol = Control()
        app = tornado.web.Application([
            (r'/', IndexHandler),
            (r'/(?P<Id>\w*)', MyWebSocketHandler, 'control': mycontrol),
            (r"/static/(.*)", tornado.web.StaticFileHandler,'path':'static/'),
        ])

您可以存储对控件实例的引用并在以后使用它

class MyWebSocketHandler(tornado.websocket.WebSocketHandler):
    def initialize(self, control):
        self.control = control

    def open(self, *args, **kwargs):
        self.id = kwargs["Id"]
        self.stream.set_nodelay(True)
        clients[self.id] = "id": self.id, "object": self

    def on_message(self, message):
        print "Client %s received a message: %s" % (self.id, message)
        self.control.send(message)

【讨论】:

以上是关于tornado Websocket Server:如何创建一个新对象以将 on_message 发送到该对象?的主要内容,如果未能解决你的问题,请参考以下文章

Tornado-第三篇-tornado支持websocket协议

websocket使用nginx作为反向代理

如何在 Tornado 中创建多个 websocket 聊天?

websocket[tornado] 的单个实例可以处理不同的请求吗?

在 Tornado 中保留 websocket 连接列表 [重复]

tornado 只能升级到 websocket 错误