Не удается установить соединение между веб-сокетом и сервером
Я пишу приложение для чата, используя django channels, redis и daphne. Когда я пытаюсь отправить сообщение и нажимаю на кнопку, у меня появляется GET-запрос, но я написал js в моем html-файле, и он должен предотвратить стандартное поведение этой формы. Я не знаю, почему он не устанавливает соединение и просто отправляет GET-запрос, что здесь не так? Я проверил сервер redis, он работает. Я установил все необходимые модули, я проверил его с помощью gpt, ничего не помогает. Как заставить его установить соединение?
consumer.py:
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from django.apps import apps
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.chat_name = self.scope['url_route']['kwargs']['chat_name']
await self.channel_layer.group_add(self.chat_name, self.channel_name)
await self.accept()
@database_sync_to_async
def save_message(self, text_data):
Chat = apps.get_model('chat', 'Chat')
ChatMessage = apps.get_model('chat', 'ChatMessage')
User = apps.get_model('auth', 'User')
chat = Chat.objects.get(chat_name=text_data['chat_name'])
sender = User.objects.get(username=text_data['sender'])
ChatMessage.objects.create(
chat=chat,
body=text_data['message'],
sender = sender,
)
async def receive(self, text_data):
print('Received from frontend:', text_data)
data_json = json.loads(text_data)
await self.save_message(data_json)
event = {"type": "send_chat_message", "message": data_json}
await self.channel_layer.group_send(self.chat_name, event)
async def send_chat_message(self, event):
await self.send(text_data=json.dumps({"message": event["message"]}))
chat.html:
asgi.py:
import os
import django
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from chat.routing import websocket_urlpatterns
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'messanger.settings')
django.setup()
application = ProtocolTypeRouter({
"http": get_asgi_application(), # Обычные HTTP-запросы
"websocket": AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
})
routings.py:
from django.urls import re_path
from .consumers import ChatConsumer
websocket_urlpatterns = [
re_path(r"ws/chat/(?P<chat_name>\w+)/$", ChatConsumer.as_asgi()),
]
views.py
from django.shortcuts import render
from .models import *
def chat_list(req):
chats = req.user.chats.all()
print(chats)
return render(req, 'chat_list.html', {'chats': chats})
def chat(req, chat_name):
chat = req.user.chats.get(chat_name=chat_name)
chat_messages = ChatMessage.objects.filter(chat=chat)
return render(req, 'chat.html', {'chat_messages': chat_messages, 'chat': chat})
models.py:
from django.db import models
from django.contrib.auth.models import User
class Chat(models.Model):
chat_name = models.CharField(max_length=50)
members = models.ManyToManyField(User, related_name='chats')
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.chat_name
class ChatMessage(models.Model):
body = models.TextField()
chat = models.ForeignKey(Chat, on_delete=models.CASCADE, related_name='chat')
sender = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Message by @{self.sender} from the chat '{self.chat.chat_name}'"
I've just solved it. I forgot about script block in html file. It is subsidiary htmll, so we have to put {% block scripts %}
here before <script>
tag. Also It is required to put {% extends "base.html" %}
inside body.