Python AsyncJsonWebSocketConsumer Problem



我收到错误

You cannot call this from an async context - use a thread or sync_to_async.当我运行我的项目时。我的消费者看起来像

class AllConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
self.user_id = str(self.scope['url_route']['kwargs']['user_id'])
await self.accept()
user = sync_to_async(User.objects.get(id=self.user_id))
sync_to_async(OnlineUserActivity.update_user_activity(user))
online_users = []
user_activity_objects = OnlineUserActivity.get_user_activities(timedelta(minutes=1))
for online_user in user_activity_objects:
online_users.append(online_user.user_id)
all_users = User.objects.all().values_list('id')
for _user in all_users:
await self.channel_layer.group_send(
str(_user[0]),
{
"type": "online_users",
'message': online_users
}
)
await self.channel_layer.group_add(
self.user_id,
self.channel_name,
)
async def disconnect(self, close_code):
try:
online_user = OnlineUserActivity.objects.get(user_id=self.user_id)
online_user.delete()
online_users = []
user_activity_objects = OnlineUserActivity.get_user_activities(timedelta(minutes=1))
for x in user_activity_objects:
online_users.append(x.user_id)
all_users = User.objects.all().values_list('id')
for _user in all_users:
await self.channel_layer.group_send(
str(_user[0]),
{
"type": "online_users",
'message': online_users
}
)
except Exception as e:
print(e)
async_to_sync(self.channel_layer.group_discard(
self.user_id,
self.channel_name
))
async def receive(self, text_data):
text_data_json = json.loads(text_data)
socket_type = text_data_json['type']
bla bla. ... 

而且我的路由 py 看起来像

from django.urls import re_path
from core import consumers
websocket_urlpatterns = [
re_path(r'ws/(?P<user_id>w+)/$', consumers.AllConsumer),
]

我的websocket 请求触及我的消费者,但它会抛出这样的异常。 我的操作系统是 Ubuntu 18 一切都无需同步到异步部分即可工作,你能帮我吗谢谢 主要问题,错误问题是

You cannot call this from an async context - use a thread or sync_to_async.

而不是:

user = sync_to_async(User.objects.get(id=self.user_id))

您应该使用:

user = await sync_to_async(User.objects.get)(id=self.user_id)

根据问题的参考,函数连接是从异步上下文定义的。但在下面一行中,调用是从同步上下文进行的:

user = sync_to_async(User.objects.get(id=self.user_id)) 

sync_to_async不尊重功能定义的上下文。

相反,使用 sync_to_async,使用async_to_sync的工作方式如下:

user = async_to_sync(User.objects.get(id=self.user_id)).awaitable

还有另一种选择,可以使用,但不建议在生产环境中使用。可以在这里详细参考:

https://docs.djangoproject.com/en/3.0/topics/async/

我希望这有所帮助。

我迟到了,但正确答案(据我说(应该如下

from channels.db import database_sync_to_async
user = await database_sync_to_async(User.objects.get)(id=self.user_id)

另外,如果您使用的是参考文献,请说书中的作者 使用以下方法

from channels.db import database_sync_to_async
book = await database_sync_to_async(Book.objects.select_related('author').get)(pk=book_id)
author = book.author

最新更新