【问题标题】:Share a value across Tornado Websockets server在 Tornado Websockets 服务器上共享一个值
【发布时间】:2017-09-27 01:13:13
【问题描述】:

我有一个在 python 中使用 Tornado 框架的基本 websocket 服务器。我想在服务器函数之间共享一个值:

class EchoWebSocket(websocket.WebSocketHandler):

    def check_origin(self, origin):
        return True
    def open(self):
        print ("connection opened")
    def on_close(self):
        tornado.ioloop.IOLoop.instance().stop()
        print ("connection closed")
    def on_message(self,message):
        print (message)

def Main():
    application = tornado.web.Application([(r"/", EchoWebSocket),])
    application.listen(9000)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    Main() 

我试图从这样的类中创建一个全局对象:

class operate:
    state = "mutual"

    def __init__(self):
        self.state = 'mutual'

    def play(self):
        self.state = 'play'

    def pause(self):
        self.state = 'pause'

    def getStatus(self):
        return self.state 

并调用一个全局对象,猜测由于该对象是全局对象,所以不会在每条消息中都创建一个新对象:

def open(self):
    global objectTV
    objectTV = operate()
    objectTV.play()
.
.
.
.
 def on_message(self,message):
        global objectTV
        objectTV = operate()
        print(objectTV.getStatus())

但它总是打印'mutual'?

【问题讨论】:

    标签: python web-services tornado


    【解决方案1】:

    在方法on_message() 中,每次有新消息到达时,您都会在objectTv = operate() 上一次又一次地实例化objectTVoperate 类的新实例将初始状态设置为'mutual',这就是它打印'mutual' 的原因。

    一个简单的解决方法是从on_message() 中删除objectTV = operate() 行,它应该可以按照您的意愿工作。

    但请阅读有关此问题的一些答案:Why are global variables evil?

    因此,解决问题的更好方法是在处理程序实例上设置一个本地属性:

    class EchoWebSocket(websocket.WebSocketHandler):
        ...
        def open(self):
            self.objectTV = operate()
            self.objectTV.play()
    
        def on_message(self, message):
            print(self.objectTV.getStatus()) # -> 'play'
    

    【讨论】:

    • 我在问题中犯了一个错误,这种方式是根据我的问题工作的。但我真正需要的是一个在打开套接字并交换消息时可见的对象。我在'on_message'中有(如果,否则),我检查来自客户端的消息。根据我要更新对象的客户端消息。这种方式不适用于我所需要的,因为在从客户端发送的每条消息上,我认为 Tornado 都会为其打开一个新线程。您知道如何在消息之间共享该对象吗?
    • @Hussein 你想在不同的客户之间共享同一个对象吗?您可以从 open() 方法中删除这一行 - self.objectTV = operate(),并将 objectTV = operate() 直接设置为 EchoWebSocket 类上的类属性。连接的新客户端将共享同一个对象。如果我完全错过了您的意思,请随时使用有关您的问题或代码的更多详细信息来更新您的问题,我会更新我的答案。
    猜你喜欢
    • 2013-07-15
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    相关资源
    最近更新 更多