目标是创建可从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的新手,但它看起来非常错误。有正确的方法吗?