Как я могу получать уведомления от другого пользователя, используя каналы в django?
Фактически, я впервые использую каналы, но это простая концепция для понимания.
Я следовал учебнику, который привел меня к способу, которым я могу отправить уведомление в реальном времени, но есть часть, которую я не могу увидеть ни в одном учебнике, где об этом забывают.
во всех руководствах показано, как можно отправлять уведомления или сообщения через чат, когда я делаю это для одного пользователя после открытия новой страницы, страница работает нормально. например, если я вошел под именем пользователя "test" и открыл новый браузер, войдя под именем пользователя "test", страница будет работать нормально
проблема заключается в следующем: когда я пытаюсь открыть например "страницу инкогнито" с помощью google chrome, чтобы использовать другого пользователя, например "new test" имя пользователя, которое я хочу, чтобы он получил уведомление, мы можем считать его целевым пользователем от отправителя на главной странице "test".
теперь данные меняются в данных, но я не могу увидеть это изменение перед глазами, пока не перезагружу веб-страницу.
Когда я протестировал это, я увидел, что javascript не получает никаких данных от пользователя "new test", и я думаю, что эта проблема возникает из-за channel_layer каким-то образом.
любая помощь и объяснение того, что здесь происходит?
#consumers.py
from channels.consumer import AsyncConsumer
from channels.db import database_sync_to_async
import json
from .models import Notification
from django.contrib.auth.models import User
class NotificationConsumer(AsyncConsumer):
async def websocket_connect(self, event):
await self.send({
'type': 'websocket.accept',
})
user = self.scope['user']
notif_room = f"user_id_{user.id}"
self.notif_room = notif_room
await self.channel_layer.group_add(
notif_room,
self.channel_name
)
async def websocket_receive(self, event):
serialize_data = json.loads(event['text'])
self.comment = serialize_data['comment']
self.user_sender = serialize_data['user_sender']
notif_count = await self.update_notification()
await self.channel_layer.group_send(
self.notif_room,
{
"type": 'send_notif',
'text': json.dumps({'notif_count': notif_count})
}
)
async def send_notif(self, event):
await self.send({
'type': 'websocket.send',
'text': event['text']
})
async def websocket_disconnect(self, event):
print("Disconnect the connections")
@database_sync_to_async
def update_notification(self):
comment = self.comment
user_sender = User.objects.get(id=int(self.user_sender))
notifs = Notification.objects.create(
user_sender=user_sender,
message=comment
)
for users in User.objects.all().exclude(username=self.scope['user'].username):
users.rec.add(notifs)
return Notification.objects.filter(user_receiver=self.scope['user'].id).count()
#file.html
{% extends 'base.html' %}
{% block title %} Data Show {% endblock %}
{% block body %}
<div class="container">
<button type="button" class="btn notification-button btn-primary">
Notifications <span class="badge badge-light">{{ notifications.count }}</span>
</button>
<br><br/>
<form id="formData" method="post">
{% csrf_token %}
{% if user.is_authenticated %}
<input type="text" hidden="hidden" value="{{ user_sender.id }}" name="user">
{% endif %}
<input type="text" name="comment" id="comment">
<input type="submit" value="create" />
</form>
</div>
<script>
let ws_protocol = "ws://";
const navigation = window.location;
let formData = document.getElementById("formData");
let id_name = document.getElementById("id-name");
let user = document.querySelector("input[name='user']");
let comment = document.getElementById("comment");
let notif_label = document.querySelector(".badge");
let notification_button = document.querySelector(".notification-button");
if (navigation.protocol === "https") {
ws_protocol = "wss://";
}
let target = `${ws_protocol}${navigation.host}${navigation.pathname}`
const socket = new WebSocket(target);
socket.onopen = (e) => {
console.log("connection accepted by javascript");
formData.onsubmit = function (e) {
e.preventDefault();
try {
let data = {
"comment": comment.value,
"user_sender": user.value
}
socket.send(JSON.stringify(data))
} catch (e) {
alert("you should login to be able to comment here");
}
}
}
socket.onmessage = (e) => {
console.log("receive message by javascript");
let json_data = JSON.parse(JSON.stringify(e.data))
json_data = JSON.parse(json_data)
notif_label.textContent = json_data.notif_count;
console.log(json_data)
}
socket.onerror = (e) => {
console.log("display error by javascript");
}
socket.onclose = (e) => {
console.log("close connection by javascript");
}
notification_button.onclick = function() {
notif_label.textContent = '';
}
</script>
{% endblock %}