Добавьте метод event_message, в GroupConsumer как показано ниже:
async def event_message(self, event):
message = event.get("message")
user = event.get("user", None)
await self.send(
json.dumps(
{
"type": "event_message",
"message": message,
"status": event.get("status", None),
"user": user
}
)
)
Вам нужно обработать эти два сообщения в методе onmessage обработчика событий API-интерфейса веб-интерфейса.
Добавьте следующий код, в файл groupchat.html после этого кода.
chatSocket.onopen = function (e) {
console.log("conneсted")
}
Добавим после:
chatSocket.onmessage = function (e) {
const data = JSON.parse(e.data);
console.log(data)
document.querySelector('#chat-log').value += (data.message + '\n');
status = data.status
user = data.user
if (status == "Left") {
document.getElementById(`members-${user}`).remove()
} else if (status == "Join") {
var members_list = document.getElementById('members')
var members_item = document.createElement("li")
members_item.innerHTML = user
members_item.setAttribute("id", `members-${user}`)
console.log(members_item)
members_list.appendChild(members_item)
}
};
Оба event_message и text_message добавляются в журнал чата.
Если тип сообщения event_message, вы проверяете значение ключа состояния, переданного из бэкэнда, со статусом Left и удаляете пользователя из списка членов группы.
Если значение ключа состояния равно Join, вы добавляете пользователя в список участников группы.
В итоге наш код в groupchat.html должен выглядеть следующим образом:
{% block script %}
<script>
base_url = `${window.location.host}${window.location.pathname}`
const chatSocket = new WebSocket(`ws://${base_url}`);
chatSocket.onopen = function (e) {
console.log("conneсted")
}
chatSocket.onmessage = function (e) {
const data = JSON.parse(e.data);
console.log(data)
document.querySelector('#chat-log').value += (data.message + '\n');
status = data.status
user = data.user
if (status == "Left") {
document.getElementById(`members-${user}`).remove()
} else if (status == "Join") {
var members_list = document.getElementById('members')
var members_item = document.createElement("li")
members_item.innerHTML = user
members_item.setAttribute("id", `members-${user}`)
console.log(members_item)
members_list.appendChild(members_item)
}
};
chatSocket.onclose = function (e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function (e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function (e) {
const messageInputDom = document.querySelector('#chat-message-input');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'type': "text_message",
"author": `{{request.user}}`,
'message': message
}));
messageInputDom.value = '';
};
</script>
{% endblock script %}
Обзор действий
Когда член группы открывает группу: клиент получает через grouppage HTTP-запрос, и сервер вызывает представление group_chat_view, которое извлекает чат и сообщения о событиях для группового чата и отображает их в шаблоне groupchat.
В шаблоне клиент создает экземпляр API веб-сокета, который отправляет запрос Handshake на сервер через URL-адрес веб-сокета.
Сервер вызывает потребителя, связанного с URL-адресом, который принимает рукопожатие, и соединение устанавливается.
Принимая рукопожатие, экземпляр потребителя добавляется в группу каналов, которая идентифицируется uuid группы чата.
Когда пользователь отправляет сообщение группе: Сообщение отправляется от клиента через конечную chatsSocket.send точку chatSocket. Метод receive класса-потребителя, связанный с конечной точкой, получает сообщение.
Сообщение передается каждому GroupConsumer экземпляру класса в той же группе каналов с помощью метода group_send класса channel_layers.
Это получено методом сообщения text_message каждого GroupConsumer класса, так как text_message было указано как тип сообщения.
Текстовое сообщение отправляется каждому клиенту с помощью send метода в text_message методе. Сообщение принимается на клиенте обработчиком событий onmessage. Затем журнал чата обновляется новым сообщением.
Сигнал сохранения сообщения отправляется после сохранения экземпляра группового чата, когда пользователь добавляется или удаляется из группового чата.
Получатель сигнала broadcast_event_to_groups получает событие и создает сообщение о событии. Сообщение о событии передается всем GroupConsumer экземплярам в одной группе.
Широковещательное сообщение получено методом event_message в GroupConsumer. Сообщение отправляется клиенту, и журнал чата обновляется.