django channels:消息通知不能正常工作



我正在写一个django模块,处理与通知配对的实时消息。到目前为止:
对话只能在不超过2个用户之间进行。每条消息之后都应该发送一个通知。

我目前正在努力使通知显示出来,问题是通知在发件人配置文件页面中呈现,而不是在收件人配置文件中呈现。我看不出错误在哪里

这是我所做的:consumers.py

import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from .models import Chat, ChatRoom
from accounts.models import User
from asgiref.sync import sync_to_async
from django.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404
from asgiref.sync import async_to_sync
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_id = self.scope['url_route']['kwargs']['room_id']
self.room_group_name = 'chat_%s' % self.room_id
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
recipient = text_data_json['recipient']
self.user_id = self.scope['user'].id
# Find room object
room = await database_sync_to_async(ChatRoom.objects.get)(pk=self.room_id)
print('ok1')
# Create new chat object
chat = Chat(
content=message,
sender=self.scope['user'],
room=room,
)
print('ok2')
await database_sync_to_async(chat.save)()
print("ok3")
# get the recipient user
recipient_user = await database_sync_to_async(User.objects.get)(id=recipient)
print("ok4")
await sync_to_async(chat.recipient.add)(recipient_user.id)
print("ok5")
await database_sync_to_async(chat.save)()

await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message,
'user_id': self.user_id
})
# Send a notification to the recipient
await self.channel_layer.send(
recipient_user.username,
{
'type': 'notification',
'message': message
}
)
await self.send_notification(f'New message from {self.user_id}')
print('notification has been created')
async def chat_message(self, event):
message = event['message']
user_id = event['user_id']
await self.send(text_data=json.dumps({
'message': message,
'user_id': user_id
}))
async def send_notification(self, message):
await self.send(text_data=json.dumps({
'type': 'notification',
'message':message
}))

这是我的room.js代码,这是javascript代码处理的逻辑,以显示消息逻辑和通知:

chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
console.log("data",data)
console.log("datatype",data.type)
var message_type = data.type;
console.log("message type",message_type)
if(message_type === 'notification'){
$("#notification-bar2").text(data.message);
$("#notification-bar2").show();
}
if(message_type !== 'notification'){
const messageElement = document.createElement('div')
const userId = data['user_id']
const loggedInUserId = JSON.parse(document.getElementById('user_id').textContent)
console.log(loggedInUserId)
messageElement.innerText = data.message
if (userId === loggedInUserId) {
messageElement.classList.add( 'relative', 'max-w-xl', 'px-4', 'py-2', 'text-gray-700', 'bg-gray-100','rounded', 'shadow','flex', 'justify-end','message', 'sender','block')
} else {
messageElement.classList.add('relative', 'max-w-xl', 'px-4', 'py-2', 'text-gray-700', 'bg-gray-100','rounded', 'shadow','flex', 'justify-start','message', 'receiver','block')
}
chatLog.appendChild(messageElement)
if (document.querySelector('#emptyText')) {
document.querySelector('#emptyText').remove()
}
}
};

我对为什么会这样感到非常困惑,并且从渠道开始新鲜,仍然有相当多的东西我不太了解,因此任何国王的帮助都非常感激!如果有必要,我很乐意提供额外的代码

似乎你试图以两种不同的方式发送通知,但做错了。

# Send a notification to the recipient
await self.channel_layer.send(
recipient_user.username,
{
'type': 'notification',
'message': message
}
)
await self.send_notification(f'New message from {self.user_id}')
print('notification has been created')

第一种方法尝试通过通道层发送它,这是正确的方式,因为当前通道是发送方的通道,所以您需要通过通道层将其管道传输到接收方的通道。问题是您没有使用处理程序的正确名称。您使用notification作为类型而不是send_notification,因此它永远不会被处理。在第二种情况下,您直接在当前通道中调用send_notification函数,该通道是发送方的通道,因此它将被发送到发送方而不是预期的接收方。上面的整个代码块应该替换为:

# Send a notification to the recipient
await self.channel_layer.send(
recipient_user.username,
{
'type': 'send_notification',
'message': f'New message from {self.user_id}'
}
)

在接收函数中,只有一个接收方和一个已连接的用户。此代码接受消息的接收者,并将其发送给该用户(接收者),让其知道消息来自该用户(发送者)。当消息到达websocket时,它已经被标记了接收者。我们需要摆脱,并保持跟踪所有我们的连接用户在聊天室对象。您可以简单地在视图中或当用户连接到websocket时处理这个问题。当发送消息时,获取房间中每个接收用户,应该是除了发送对象的用户之外的所有用户。

print('ok2')
await database_sync_to_async(chat.save)()
print("ok3")
# get the recipient user
# database_sync_to_async function that gets the list of users
# dont forget to call users.remove(sender)
for each in users:
recipient_user = each
print("ok4")
await sync_to_async(chat.recipient.add)(recipient_user.id)
print("ok5")
await database_sync_to_async(chat.save)()

最新更新