Не удалось подключиться к веб-сокетам Django ⇐ Javascript
-
Гость
Не удалось подключиться к веб-сокетам Django
Я разместил на Linode приложение django, которое включает в себя функцию чата. Я использую каналы django для реализации этой функциональности. Я не использую какой-либо конкретный такие технологии, как Redis, просто встроенная вещь django для реализации веб-сокетов, потому что я сейчас просто тестирую сайт. Ниже приведен файл Chatroom.html:
{% расширяет 'common_anime_chat/base.html' %} {% нагрузки статической %} {% таблица стилей блока %} {% таблица стилей конечного блока %} {% блокирует контент %} {{ request.user.username|json_script:"user_username" }} {{ request.user.profile.profile_picture.url|json_script:"user_pfp"}} const hardcodedProfilePictures = { 'itsmyname': '/media/profile_pictures/profile1.png', 'user123': '/media/profile_picturues/profile2.png', // Добавьте сюда дополнительные жестко запрограммированные изображения профиля для других имен пользователей }; document.querySelector('#submit').onclick = function (e) { const messageInputDOM = document.querySelector('#input'); константное сообщение = messageInputDOM.value; chatSocket.send(JSON.stringify({ 'сообщение': сообщение, 'имя пользователя': имя_пользователя, 'user_pfp': userPfp, 'room_name':roomName })); messageInputDOM.value = ''; }; constchatMessagesDOM = document.querySelector('#chat-messages'); const userUsername = JSON.parse(document.getElementById('user_username').textContent); // console.log(имяпользователя) const pathArray = window.location.pathname.split('/'); const roomName = pathArray[pathArray.length - 2]; // Используйте -1, если имя комнаты находится в последнем сегменте пусть userPfp = JSON.parse(document.getElementById('user_pfp').textContent); // Объект для хранения изображений профиля, связанных с именами пользователей пусть ProfilePictures = {}; constchatSocket = новый WebSocket(window.location.protocol === 'https:'? 'wss://': 'ws://') + окно.location.host + '/чат/' + имя комнаты + '/' ); chatSocket.onopen = функция (событие) { console.log('Соединение WebSocket открыто.'); }; console.log('URL WebSocket:',chatSocket.url); chatSocket.onclose = функция (событие) { console.log('Соединение WebSocket закрыто.'); }; chatSocket.onerror = функция (ошибка) { console.log('Ошибка WebSocket:', ошибка); }; chatSocket.onmessage = функция (e) { константные данные = JSON.parse(e.data); const messageContainer = document.createElement('div'); messageContainer.classList.add('чат-сообщение'); let ProfilePicture = document.createElement('img'); ProfilePicture.src = data.user_pfp; ProfilePicture.alt = 'Изображение профиля'; ProfilePicture.style.maxHeight = '42px'; ProfilePicture.style.borderRadius = '50%'; ProfilePicture.classList.add('картинка-профиля'); messageContainer.appendChild(profilePicture); const messageContent = document.createElement('span'); messageContent.classList.add('содержимое сообщения'); const usernameSpan = document.createElement('span'); usernameSpan.classList.add('имя пользователя'); usernameSpan.textContent = data.username + ': '; usernameSpan.style.color = 'белый'; messageContent.appendChild(usernameSpan); const messageSpan = document.createElement('span'); messageSpan.textContent = data.message; messageSpan.style.color = 'белый'; messageContent.appendChild(messageSpan); messageContainer.appendChild(messageContent); chatMessagesDOM.appendChild(messageContainer); }; // Извлекаем и загружаем изображения профиля для каждого пользователя fetch('/api/get_user_profile_pictures/') // Измените этот URL-адрес на конечную точку, которая предоставляет URL-адреса изображений профиля для всех пользователей .then(ответ => ответ.json()) .then(данные => { профильPictures = данные; console.log(профилекартинки) }) .catch(ошибка => { console.log(профилекартинки) console.error('Ошибка загрузки изображений профиля:', error); }); document.querySelector('#input').addEventListener('keydown', function (event) { if (event.key === 'Enter') { // Предотвратить поведение клавиши Enter по умолчанию (отправка формы) событие.preventDefault(); // Запускаем событие нажатия кнопки отправки document.querySelector('#submit').click(); } }); {% контента в конце блока %} Ниже приведен файл Route.py:
из django.urls import re_path от . потребители импорта websocket_urlpatterns = [ re_path(r'^ws/chat/(?P\w+)/$', Consumer.ChatRoomConsumer.as_asgi()) ] В консоли выводится следующий результат:
Подключение WebSocket к «ws://my.ip.address/chat/AUdZzo8slKKwKvzmUrnmLRfnVkuAYfJj/» не удалось: (анонимно) @ (индекс):92 (индекс): 109 Ошибка WebSocket: событие {isTrusted: true, тип: «ошибка», цель: WebSocket, currentTarget: WebSocket, eventPhase: 2,…} Сайт работал отлично вместе с веб-сокетами на локальном хосте.
Хотя маловероятно, что в моем файле Consumer.py есть ошибка, поскольку я не думаю, что поток кода вообще доходит до него, файл Consumer.py выглядит следующим образом:
import AsyncWebsocketConsumer импортировать JSON из django.contrib.auth.models импортировать пользователя # из Channels.db импорта data_sync_to_async из asgiref.sync импортировать sync_to_async из .models импортировать чат, сообщение, профиль из asyncer импортировать asyncify @sync_to_async def save_message_to_database(имя_чата, имя пользователя, сообщение): пытаться: чат = ChatRoom.objects.get(name=chatroom_name) пользователь = User.objects.get(имя пользователя=имя пользователя) user_profile = Profile.objects.get(пользователь=пользователь) new_message = Message.objects.create(chat_room=чат, отправитель=user_profile, content=message) print("Сообщение сохранено в БД:", new_message) кроме ChatRoom.DoesNotExist: print(f"Чат с именем '{chatroom_name}' не существует.") кроме Profile.DoesNotExist: print(f"Профиль пользователя с именем '{username}' не существует.") кроме исключения как e: print(f"Произошла ошибка при сохранении сообщения: {e}") @sync_to_async защита get_chatroom_by_name(имя): пытаться: вернуть ChatRoom.objects.get(имя=имя) кроме ChatRoom.DoesNotExist: возврат Нет @sync_to_async защита get_messages_for_chatroom (чат): список возврата (Message.objects.filter(chat_room=chatroom).order_by('метка времени')) класс ChatRoomConsumer(AsyncWebsocketConsumer): асинхронное определение подключения (сам): self.room_name = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.room_name ожидайте self.channel_layer.group_add( self.room_group_name, self.channel_name ) ожидайте self.accept() print("Прежде чем попасть в чат") чат = ожидайте get_chatroom_by_name(self.room_name) print("чат:",чат) print("Чат:",чат) сообщения = ждут get_messages_for_chatroom(chatroom.id) для сообщения в сообщениях: print("ОТПРАВКА СООБЩЕНИЯ В ФУНКЦИЮ") ожидайте self.send_message_to_client(сообщение) асинхронная защита send_message_to_client(self, message): user_id = ожидайте sync_to_async(лямбда: message.sender.user_id)() пользователь = ждут sync_to_async(лямбда: User.objects.get(id=user_id))() print("ОТПРАВКА СООБЩЕНИЙ НА ФРАНТЕНД") ждут self.send(text_data=json.dumps({ 'сообщение': message.content, 'имя пользователя': user.username, 'user_pfp': message.sender.profile_picture.url, 'room_name': self.room_name, })) асинхронное отключение (self, close_code): ожидайте self.channel_layer.group_discard( self.room_group_name, self.channel_name ) асинхронное определение получения (self, text_data): text_data_json = json.loads(text_data) сообщение = text_data_json['сообщение'] имя пользователя = text_data_json['имя пользователя'] user_pfp = text_data_json['user_pfp'] имя_комнаты = text_data_json['имя_комнаты'] await save_message_to_database(имя_чата=имя_комнаты, имя пользователя=имя_пользователя, сообщение=сообщение) ожидайте self.channel_layer.group_send( self.room_group_name, { 'тип': 'chatroom_message', 'сообщение': сообщение, 'имя пользователя': имя пользователя, 'user_pfp': user_pfp, 'room_name': имя_комнаты, 'tester_message': 'сообщение тестера в функции приема' } ) асинхронная защита Chatroom_message (я, событие): сообщение = событие['сообщение'] имя пользователя = событие['имя пользователя'] user_pfp = событие['user_pfp'] ждут self.send(text_data=json.dumps({ 'сообщение': сообщение, 'имя пользователя': имя пользователя, 'user_pfp': user_pfp, 'tester_message': 'сообщение тестера в сообщении чата' })) Пожалуйста, помогите мне решить эту проблему!
Я разместил на Linode приложение django, которое включает в себя функцию чата. Я использую каналы django для реализации этой функциональности. Я не использую какой-либо конкретный такие технологии, как Redis, просто встроенная вещь django для реализации веб-сокетов, потому что я сейчас просто тестирую сайт. Ниже приведен файл Chatroom.html:
{% расширяет 'common_anime_chat/base.html' %} {% нагрузки статической %} {% таблица стилей блока %} {% таблица стилей конечного блока %} {% блокирует контент %} {{ request.user.username|json_script:"user_username" }} {{ request.user.profile.profile_picture.url|json_script:"user_pfp"}} const hardcodedProfilePictures = { 'itsmyname': '/media/profile_pictures/profile1.png', 'user123': '/media/profile_picturues/profile2.png', // Добавьте сюда дополнительные жестко запрограммированные изображения профиля для других имен пользователей }; document.querySelector('#submit').onclick = function (e) { const messageInputDOM = document.querySelector('#input'); константное сообщение = messageInputDOM.value; chatSocket.send(JSON.stringify({ 'сообщение': сообщение, 'имя пользователя': имя_пользователя, 'user_pfp': userPfp, 'room_name':roomName })); messageInputDOM.value = ''; }; constchatMessagesDOM = document.querySelector('#chat-messages'); const userUsername = JSON.parse(document.getElementById('user_username').textContent); // console.log(имяпользователя) const pathArray = window.location.pathname.split('/'); const roomName = pathArray[pathArray.length - 2]; // Используйте -1, если имя комнаты находится в последнем сегменте пусть userPfp = JSON.parse(document.getElementById('user_pfp').textContent); // Объект для хранения изображений профиля, связанных с именами пользователей пусть ProfilePictures = {}; constchatSocket = новый WebSocket(window.location.protocol === 'https:'? 'wss://': 'ws://') + окно.location.host + '/чат/' + имя комнаты + '/' ); chatSocket.onopen = функция (событие) { console.log('Соединение WebSocket открыто.'); }; console.log('URL WebSocket:',chatSocket.url); chatSocket.onclose = функция (событие) { console.log('Соединение WebSocket закрыто.'); }; chatSocket.onerror = функция (ошибка) { console.log('Ошибка WebSocket:', ошибка); }; chatSocket.onmessage = функция (e) { константные данные = JSON.parse(e.data); const messageContainer = document.createElement('div'); messageContainer.classList.add('чат-сообщение'); let ProfilePicture = document.createElement('img'); ProfilePicture.src = data.user_pfp; ProfilePicture.alt = 'Изображение профиля'; ProfilePicture.style.maxHeight = '42px'; ProfilePicture.style.borderRadius = '50%'; ProfilePicture.classList.add('картинка-профиля'); messageContainer.appendChild(profilePicture); const messageContent = document.createElement('span'); messageContent.classList.add('содержимое сообщения'); const usernameSpan = document.createElement('span'); usernameSpan.classList.add('имя пользователя'); usernameSpan.textContent = data.username + ': '; usernameSpan.style.color = 'белый'; messageContent.appendChild(usernameSpan); const messageSpan = document.createElement('span'); messageSpan.textContent = data.message; messageSpan.style.color = 'белый'; messageContent.appendChild(messageSpan); messageContainer.appendChild(messageContent); chatMessagesDOM.appendChild(messageContainer); }; // Извлекаем и загружаем изображения профиля для каждого пользователя fetch('/api/get_user_profile_pictures/') // Измените этот URL-адрес на конечную точку, которая предоставляет URL-адреса изображений профиля для всех пользователей .then(ответ => ответ.json()) .then(данные => { профильPictures = данные; console.log(профилекартинки) }) .catch(ошибка => { console.log(профилекартинки) console.error('Ошибка загрузки изображений профиля:', error); }); document.querySelector('#input').addEventListener('keydown', function (event) { if (event.key === 'Enter') { // Предотвратить поведение клавиши Enter по умолчанию (отправка формы) событие.preventDefault(); // Запускаем событие нажатия кнопки отправки document.querySelector('#submit').click(); } }); {% контента в конце блока %} Ниже приведен файл Route.py:
из django.urls import re_path от . потребители импорта websocket_urlpatterns = [ re_path(r'^ws/chat/(?P\w+)/$', Consumer.ChatRoomConsumer.as_asgi()) ] В консоли выводится следующий результат:
Подключение WebSocket к «ws://my.ip.address/chat/AUdZzo8slKKwKvzmUrnmLRfnVkuAYfJj/» не удалось: (анонимно) @ (индекс):92 (индекс): 109 Ошибка WebSocket: событие {isTrusted: true, тип: «ошибка», цель: WebSocket, currentTarget: WebSocket, eventPhase: 2,…} Сайт работал отлично вместе с веб-сокетами на локальном хосте.
Хотя маловероятно, что в моем файле Consumer.py есть ошибка, поскольку я не думаю, что поток кода вообще доходит до него, файл Consumer.py выглядит следующим образом:
import AsyncWebsocketConsumer импортировать JSON из django.contrib.auth.models импортировать пользователя # из Channels.db импорта data_sync_to_async из asgiref.sync импортировать sync_to_async из .models импортировать чат, сообщение, профиль из asyncer импортировать asyncify @sync_to_async def save_message_to_database(имя_чата, имя пользователя, сообщение): пытаться: чат = ChatRoom.objects.get(name=chatroom_name) пользователь = User.objects.get(имя пользователя=имя пользователя) user_profile = Profile.objects.get(пользователь=пользователь) new_message = Message.objects.create(chat_room=чат, отправитель=user_profile, content=message) print("Сообщение сохранено в БД:", new_message) кроме ChatRoom.DoesNotExist: print(f"Чат с именем '{chatroom_name}' не существует.") кроме Profile.DoesNotExist: print(f"Профиль пользователя с именем '{username}' не существует.") кроме исключения как e: print(f"Произошла ошибка при сохранении сообщения: {e}") @sync_to_async защита get_chatroom_by_name(имя): пытаться: вернуть ChatRoom.objects.get(имя=имя) кроме ChatRoom.DoesNotExist: возврат Нет @sync_to_async защита get_messages_for_chatroom (чат): список возврата (Message.objects.filter(chat_room=chatroom).order_by('метка времени')) класс ChatRoomConsumer(AsyncWebsocketConsumer): асинхронное определение подключения (сам): self.room_name = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.room_name ожидайте self.channel_layer.group_add( self.room_group_name, self.channel_name ) ожидайте self.accept() print("Прежде чем попасть в чат") чат = ожидайте get_chatroom_by_name(self.room_name) print("чат:",чат) print("Чат:",чат) сообщения = ждут get_messages_for_chatroom(chatroom.id) для сообщения в сообщениях: print("ОТПРАВКА СООБЩЕНИЯ В ФУНКЦИЮ") ожидайте self.send_message_to_client(сообщение) асинхронная защита send_message_to_client(self, message): user_id = ожидайте sync_to_async(лямбда: message.sender.user_id)() пользователь = ждут sync_to_async(лямбда: User.objects.get(id=user_id))() print("ОТПРАВКА СООБЩЕНИЙ НА ФРАНТЕНД") ждут self.send(text_data=json.dumps({ 'сообщение': message.content, 'имя пользователя': user.username, 'user_pfp': message.sender.profile_picture.url, 'room_name': self.room_name, })) асинхронное отключение (self, close_code): ожидайте self.channel_layer.group_discard( self.room_group_name, self.channel_name ) асинхронное определение получения (self, text_data): text_data_json = json.loads(text_data) сообщение = text_data_json['сообщение'] имя пользователя = text_data_json['имя пользователя'] user_pfp = text_data_json['user_pfp'] имя_комнаты = text_data_json['имя_комнаты'] await save_message_to_database(имя_чата=имя_комнаты, имя пользователя=имя_пользователя, сообщение=сообщение) ожидайте self.channel_layer.group_send( self.room_group_name, { 'тип': 'chatroom_message', 'сообщение': сообщение, 'имя пользователя': имя пользователя, 'user_pfp': user_pfp, 'room_name': имя_комнаты, 'tester_message': 'сообщение тестера в функции приема' } ) асинхронная защита Chatroom_message (я, событие): сообщение = событие['сообщение'] имя пользователя = событие['имя пользователя'] user_pfp = событие['user_pfp'] ждут self.send(text_data=json.dumps({ 'сообщение': сообщение, 'имя пользователя': имя пользователя, 'user_pfp': user_pfp, 'tester_message': 'сообщение тестера в сообщении чата' })) Пожалуйста, помогите мне решить эту проблему!
Мобильная версия