为什么缺少 __init__() 的参数?
Why is a parameter to __init__() missing?
总结
我有一个使用 Websockets 的客户端-服务器应用程序。后端(服务器)部分使用 autobahn
.
在 Python 中实现
服务器除了为 Websockets 端点提供服务外,还运行一系列线程,通过 queue.Queue()
.
为 Websockets 通道提供数据。
其中一个线程有问题:它在缺少参数时崩溃并在解决异常时挂起。
实施细节
服务器实现(删减以突出问题):
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
条件下挂起?
备注
- 我的程序从来没有抛出 Traceback(由于挂起)
- 删除此线程调用可解决问题(客户端连接正确)
构造函数需要 events
arg,而不是 dummy
方法。我认为你的意思更像是:
d = Dummy(self.events)
threading.Thread(d.dummy).start()
总结
我有一个使用 Websockets 的客户端-服务器应用程序。后端(服务器)部分使用 autobahn
.
服务器除了为 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
条件下挂起?
备注
- 我的程序从来没有抛出 Traceback(由于挂起)
- 删除此线程调用可解决问题(客户端连接正确)
构造函数需要 events
arg,而不是 dummy
方法。我认为你的意思更像是:
d = Dummy(self.events)
threading.Thread(d.dummy).start()