[英]django channels: notifications of message not working properly
我正在编写一个 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()
}
}
};
我对为什么会这样感到非常困惑,并且从频道开始,还有很多我不太了解的东西,因此非常感谢国王的帮助! 如有必要,我非常乐意提供额外的代码
在您的收件人 function 中,您只有一个收件人和一个已连接的用户。 此代码获取消息附带的收件人并将其发送给该用户(收件人),让它知道它来自该用户(发件人)。 当消息到达 websocket 时,消息已经带有收件人标签。我们需要摆脱它并跟踪 ChatRoom object 中所有连接的用户。您可以简单地在视图中处理它,或者当用户连接到 websocket。发送消息时,获取房间中的每个接收用户,这应该是除发送 object 的用户之外的所有用户。
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)()
您似乎正试图以两种不同的方式发送通知,但方式不对。
# 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')
第一种方法尝试通过通道层发送它,这是正确的方法,因为当前通道是发送方的通道,因此您需要 pipe 通过通道层将其发送到接收方的通道。 问题是您没有使用正确的处理程序名称。 您使用notification
作为类型而不是send_notification
,因此它永远不会被处理。 在第二种情况下,您直接在当前频道(发送者的频道)中调用send_notification
function,因此它将发送给发送者而不是预期的接收者。 上面的整个代码块应替换为:
# 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}'
}
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.