使用WebSockets和Python-can与asyncio

时间:2018-08-27 13:13:14

标签: python websocket python-asyncio

目标是创建可从WebSocket和CAN总线处理数据的应用程序。 我正在使用websockets,它是异步的,但python-can库是同步的,而这正是问题开始的地方。

我发现的唯一方法是使用装饰器,这些装饰器将同步函数转换为异步函数,反之亦然。

在下面的简化示例中:服务器通过can bus接收消息->服务器将消息发送到ws。

WebSocket.py:

async def websocket_handler(websocket, path):
    # ...

async def send(data):
    await client.send(json.dumps(data))

def init():
    return websockets.serve(websocket_handler, 'localhost', 6969)

CAN.py:

_bus = None

@force_sync
async def on_message_received(msg):
    # ...
    await WebSocket.send(...)

@force_async
def handle_messages():
    while True:
        msg = _bus.recv()
        if msg is not None:
            print(msg)
            on_message_received(msg)

async def init():
    global _bus
    _bus = Bus('test', bustype='virtual')
    await handle_messages()

装饰器:

def force_async(fn):
    pool = ThreadPoolExecutor()

    def wrapper(*args, **kwargs):
        future = pool.submit(fn, *args, **kwargs)
        return asyncio.wrap_future(future)

    return wrapper


def force_sync(fn):

    def wrapper(*args, **kwargs):
        res = fn(*args, **kwargs)
        if asyncio.iscoroutine(res):
            return asyncio.new_event_loop().run_until_complete(res)
        return res

    return wrapper

main.py:

asyncio.get_event_loop().run_until_complete(asyncio.gather(
    CAN.init(),
    WebSocket.init(),
    can_test.init()
))

asyncio.get_event_loop().run_forever()

我是Python的新手,但它看起来非常错误。有正确的方法吗?

0 个答案:

没有答案