使用全局变量的 WebSocket 线程

Posted

技术标签:

【中文标题】使用全局变量的 WebSocket 线程【英文标题】:WebSocket Threading using Global Variables 【发布时间】:2014-12-23 00:36:06 【问题描述】:

我正在尝试使用非常流行的Tornado server for Python 创建一个 WebSocket 服务器,但是我在创建一个全局范围的self 变量以便将数据写入类外的 Web 套接字时遇到问题。

This answer 完全解决了我的问题,但我想更进一步,将整个问题封装在一个线程中。

这是我的插座:

wss = []

class WSHandler(tornado.websocket.WebSocketHandler):

    def check_origin(self, origin):
        return True

    def open(self):
        print ('New connection established.')
        if self not in wss:
            wss.append(self)

    def on_message(self, message):
        print ('Received message: %s' % message)

    def on_close(self):
        print ('Connection closed.')
        if self in wss:
            wss.remove(self)

这是写入套接字的类之外的方法:

def write_data(message):
    for ws in wss:
        print ("Sending: %s" % message)
        ws.write_message(message);

这是线程服务器类:

class ServerThread(threading.Thread):

    def run(self):
        print ("Starting server.")
        http_server = tornado.httpserver.HTTPServer(application)
        http_server.listen(4045)
        main_loop = tornado.ioloop.IOLoop.instance()
        main_loop.start()

    def send_data(self, message):
        write_data(message);

奇怪的是,当代码没有包装在Thread 类中时,write 方法可以正常工作。在上面的代码中,当我调用时:

server_thread = ServerThread()
server_thread.start()
server_thread.send_data("Ping!")

什么都没有发生。方法write_data(message)被输入了,但是wss[]显然是空的。

您能提供的任何帮助将不胜感激!

更新:

我一直在研究这个问题,但无济于事。另一个奇怪的事情:New connection established. 从不打印到控制台,这让我认为套接字从不附加到列表中,而不是它是一个变量范围问题。

【问题讨论】:

我无法重现这个。 gist.github.com/binux/2e1c7b3b2b8de18f950c你的程序还有其他线程吗? tornado.ioloop.IOLoop.instance() 是进程共享的 IOLoop 对象,不好从线程启动。 这是我目前所拥有的:pastebin.com/S4hkDRqgsend_data(self, message) 中的打印语句没有按预期工作,并且套接字没有写入Ping! 您不应该在 thread.start 之后立即发送数据。由于尚未连接 websocket。 在测试期间,我在两行之间有time.sleep(2)。不幸的是,它仍然不起作用。 你能在send_data之前确认New connection established.吗? 【参考方案1】:

您不应该将端口 4045 用于 HTTP/WebSocket 服务,因为它已被浏览器阻止。您可能会从浏览器收到错误消息:

Failed to construct 'WebSocket': The port 4045 is not allowed.

http://www-archive.mozilla.org/projects/netlib/PortBanning.html http://support.apple.com/en-us/HT203772

【讨论】:

以上是关于使用全局变量的 WebSocket 线程的主要内容,如果未能解决你的问题,请参考以下文章

JMeter:全局变量___setProperty跨线程传参

使用具有共享全局变量的线程

jmeter全局变量配置:将token运用到全局(跨线程组使用变量)

在线程中使用全局变量

python多线程全局变量和锁

为啥lua语言中使用全局变量就会造成内存泄漏