为什么缺少__init __()的参数?

时间:2017-11-08 15:01:05

标签: python multithreading websocket python-asyncio autobahn

摘要

我有一个使用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条件?

注释

  • 我的程序(由于挂起)从未抛出Traceback
  • 删除此线程调用可解决问题(客户端正确连接)

1 个答案:

答案 0 :(得分:2)

构造函数需要events arg,而不是dummy方法。我认为你的意思更像是:

d = Dummy(self.events)
threading.Thread(d.dummy).start()