Вот мой текущий код представления:
Код: Выделить всё
async def stream_chat_messages(request, recipient_id: int) -> StreamingHttpResponse:
"""View used to stream chat messages between the authenticated user and a specified recipient."""
recipient = await sync_to_async(get_object_or_404)(User, id=recipient_id)
async def event_stream():
async for message in get_existing_messages(request.user, recipient):
yield message
last_id = await get_last_message_id(request.user, recipient)
while True:
new_messages = (
ChatMessage.objects.filter(
Q(sender=request.user, recipient=recipient)
| Q(sender=recipient, recipient=request.user),
id__gt=last_id,
)
.annotate(
profile_picture_url=Concat(
Value(settings.MEDIA_URL),
F("sender__userprofile__profile_picture"),
output_field=CharField(),
),
is_pinned=Q(pinned_by__in=[request.user]),
)
.order_by("created_at")
.values(
"id",
"created_at",
"content",
"profile_picture_url",
"sender__id",
"edited",
"file",
"file_size",
"is_pinned",
)
)
async for message in new_messages:
message["created_at"] = message["created_at"].isoformat()
message["content"] = escape(message["content"])
json_message = json.dumps(message, cls=DjangoJSONEncoder)
yield f"data: {json_message}\n\n"
last_id = message["id"]
await asyncio.sleep(0.1)
async def get_existing_messages(user, recipient) -> AsyncGenerator:
messages = (
ChatMessage.objects.filter(
Q(sender=user, recipient=recipient)
| Q(sender=recipient, recipient=user)
)
.filter(
(Q(sender=user) & Q(sender_hidden=False))
| (Q(recipient=user) & Q(recipient_hidden=False))
)
.annotate(
profile_picture_url=Concat(
Value(settings.MEDIA_URL),
F("sender__userprofile__profile_picture"),
output_field=CharField(),
),
is_pinned=Q(pinned_by__in=[user]),
)
.order_by("created_at")
.values(
"id",
"created_at",
"content",
"profile_picture_url",
"sender__id",
"edited",
"file",
"file_size",
"is_pinned",
)
)
async for message in messages:
message["created_at"] = message["created_at"].isoformat()
message["content"] = escape(message["content"])
json_message = json.dumps(message, cls=DjangoJSONEncoder)
yield f"data: {json_message}\n\n"
async def get_last_message_id(user, recipient) -> int:
last_message = await ChatMessage.objects.filter(
Q(sender=user, recipient=recipient) | Q(sender=recipient, recipient=user)
).alast()
return last_message.id if last_message else 0
return StreamingHttpResponse(event_stream(), content_type="text/event-stream")
Будем очень признательны за любые советы или примеры того, как эффективно справиться с этой проблемой.
Подробнее здесь: https://stackoverflow.com/questions/790 ... tpresponse