我有一个使用Websockets的客户端 - 服务器应用程序。后端(服务器)部分使用autobahn
在Python中实现。
服务器除了为Websockets端点提供服务外,还运行一系列线程,这些线程将为Websockets通道提供数据,但queue.Queue()
。
其中一个线程出现问题:它在缺少参数时崩溃并在解决异常时挂起。
服务器实现(缩减以突出显示问题):
from autobahn.asyncio.websocket import WebSocketServerProtocol, WebSocketServerFactory
import time
import threading
import arrow
import queue
import asyncio
import json
# backends of components
import dummy
class MyServerProtocol(WebSocketServerProtocol):
def __init__(self):
super().__init__()
print("webserver initialized")
# global queue to handle updates from modules
self.events = queue.Queue()
# consumer
threading.Thread(target=self.push).start()
threading.Thread(target=dummy.Dummy().dummy, args=(self.events,)).start()
def push(self):
""" consume the content of the queue and push it to the browser """
while True:
update = self.events.get()
print(update)
if update:
self.sendMessage(json.dumps(update).encode('utf-8'), False)
print(update)
time.sleep(1)
def worker(self):
print("started thread")
while True:
try:
self.sendMessage(arrow.now().isoformat().encode('utf-8'), False)
except AttributeError:
print("not connected?")
time.sleep(3)
def onConnect(self, request):
print("Client connecting: {0}".format(request.peer))
def onOpen(self):
print("WebSocket connection open.")
def onClose(self, wasClean, code, reason):
print("WebSocket connection closed: {0}".format(reason))
if __name__ == '__main__':
factory = WebSocketServerFactory(u"ws://127.0.0.1:9100")
factory.protocol = MyServerProtocol
loop = asyncio.get_event_loop()
coro = loop.create_server(factory, '0.0.0.0', 9100)
loop.run_until_complete(coro)
loop.run_forever()
上面代码中导入的dummy
模块:
import time
import arrow
class Dummy:
def __init__(self, events):
self.events = events
print("dummy initialized")
def dummy(self):
while True:
self.events.put({
'dummy': {
'time': arrow.now().isoformat()
}
})
time.sleep(1)
当运行上面的代码并从客户端连接时,我得到输出webserver initialized
(证明连接已启动),以及客户端上的WebSocket connection to 'ws://127.0.0.1:9100/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
。
调试代码时,我看到对threading.Thread(target=dummy.Dummy().dummy, args=(self.events,)).start()
的调用崩溃,而调试器(PyCharm)导致我C:\Program Files (x86)\Python36-32\Lib\asyncio\selector_events.py
,特别是第236行
# It's now up to the protocol to handle the connection.
except Exception as exc:
if self._debug:
线程在执行if self._debug
时挂起,但我在except
行看到(感谢Pycharm)
exc: __init__() missing 1 required positional argument: 'events'
为什么缺少此参数?它是通过threading.Thread(target=dummy.Dummy().dummy, args=(self.events,)).start()
电话提供的。
作为一个附带问题:为什么线程会挂起if
条件?
答案 0 :(得分:2)
构造函数需要events
arg,而不是dummy
方法。我认为你的意思更像是:
d = Dummy(self.events)
threading.Thread(d.dummy).start()