我有一个django服务(例如'brisbane'
),当使用以下通道和信号保存数据库模型时,该服务会将更新推送到客户端浏览器:
def invalidated_serialized_model_receiver(self, sender, **kwargs):
...
async_to_sync(get_channel_layer().group_send)(name, update)
这有效并提供了实时更新。
'brisbane'
现在需要与另一个服务(相同的代码)'sydney'
进行交互,以便可以根据sydney's
数据的变化实时进行类似的实时更新。这使用了在另一个进程中运行的使用者,看起来像这样:
async def remote_site_consume(site):
socket_url = site.urn(protocol='ws', resource_name='/ws/watch/')
async with websockets.connect(socket_url) as websocket:
await websocket.send(json.dumps({'type': 'watch_messages'}))
...
async for event in websocket:
event = json.loads(event)
await get_event_handler(event)(site, websocket, event)
信号可能会从发生问题的事件处理程序内合法发送。发生这种情况时,它将引发RuntimeError
'您不能在与异步事件循环相同的线程中使用AsyncToSync -只需直接等待异步功能即可。'
我不能只使用await,因为信号也是从没有事件循环的线程发送的。
答案 0 :(得分:0)
我正在尝试用此替代async_to_sync的方法,该方法似乎至少在本地测试中有效:
def invalidated_serialized_model_receiver(self, sender, **kwargs):
...
create_or_use_loop(self.channel_layer.group_send(name, update))
def create_or_use_loop(awaitable):
try:
event_loop = asyncio.get_event_loop()
except RuntimeError:
event_loop = None
if event_loop and event_loop.is_running():
event_loop.call_soon_threadsafe(event_loop.create_task, awaitable)
else:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(awaitable)
finally:
loop.close()
asyncio.set_event_loop(event_loop)
这感觉很笨拙。