【发布时间】:2023-03-10 05:50:01
【问题描述】:
我正在使用channels 来实现 WebSockets。
我正在尝试通过 websocket 从post_save django 信号发送数据。
下面是我的代码。
signals.py
@receiver(post_save, sender=CheckIn)
def send_data_on_save(sender, instance, **kwargs):
channel_layer = get_channel_layer()
stats = get_stats()
async_to_sync(channel_layer.group_send)(
'dashboard',
{
'type': 'send_data',
'message': stats
}
)
analytics = get_analytics()
async_to_sync(channel_layer.group_send)(
'analytic',
{
'type': 'send_data',
'message': analytics
}
)
consumers.py
class DashboardConsumer(WebsocketConsumer):
def connect(self):
self.room_group_name = 'dashboard'
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave room group
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'send_data',
'message': message
}
)
# Receive message from room group
def send_data(self, event):
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps({
'message': message
}))
同一段代码正在我的本地机器(windows)上运行,但是当我尝试在服务器(ubuntu 16.04)上运行这段代码时,我收到以下错误:
追溯
Exception inside application: module 'asyncio' has no attribute '_get_running_loop'
File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
result = coro.throw(exc)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/sessions.py", line 183, in __call__
return await self.inner(receive, self.send)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/middleware.py", line 41, in coroutine_call
await inner_instance(receive, send)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/consumer.py", line 59, in __call__
[receive, self.channel_receive], self.dispatch
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/utils.py", line 52, in await_many_dispatch
await dispatch(result)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/asgiref/sync.py", line 145, in __call__
return await asyncio.wait_for(future, timeout=None)
File "/usr/lib/python3.5/asyncio/tasks.py", line 373, in wait_for
return (yield from fut)
File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
yield self # This tells Task to wait for completion.
File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/db.py", line 14, in thread_handler
return super().thread_handler(loop, *args, **kwargs)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/asgiref/sync.py", line 164, in thread_handler
return func(*args, **kwargs)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/consumer.py", line 105, in dispatch
handler(message)
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/channels/generic/websocket.py", line 39, in websocket_connect
self.connect()
File "/home/user1/demowebapps/vmsbackend/check_in/consumers.py", line 57, in connect
self.channel_name
File "/home/user1/demowebapps/env/lib/python3.5/site-packages/asgiref/sync.py", line 41, in __call__
if asyncio._get_running_loop() is not None:
module 'asyncio' has no attribute '_get_running_loop'
当我从javascript.send() 函数正常发送数据时,它在服务器上正常工作,但是当调用post_save 信号时,只有我在服务器上收到此错误。这在我的本地系统上运行良好。
我尝试从信号中删除async_to_sync 然后它没有给出错误但它没有通过网络套接字传输数据。
然后它正在给:
./check_in/signals.py:47: RuntimeWarning: Coroutine'RedisChannelLayer.group_send' was never awaited
'message': analytics
我在本地和服务器上都使用 pythom 3.5.2。
我不知道怎么了。是代码还是其他东西。任何帮助表示赞赏。 谢谢
【问题讨论】:
标签: python django python-asyncio django-channels django-signals