Подключение приложения flutter к django с помощью веб-сокетов

Я совсем новичок в WebSockets, так что в основном я пытаюсь сделать все возможное, чтобы создать в моем проекте Django и интегрировать его в мой проект Flutter. Идея состоит в том, чтобы иметь комнаты и участников этих комнат, чтобы иметь возможность общаться. Итак, в настройках Django я добавил 'daphne' в установленных приложениях я создал потребителей чата следующим образом:

class ChatConsumer(AsyncWebsocketConsumer):

    async def connect(self):

        # scope is the request parameters passed from the url route
        self.room_id = self.scope['url_route']['kwargs']['room_id']
        self.room_group_name = 'chat_%s' % self.room_id

        # Join room group 
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)
        await self.accept()


    async def disconnect(self, close_code):

        # Leave room
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

Вот как выглядит моя комната и модели сообщений:

class Message(models.Model):
    """Chat message model"""

    body = models.TextField()
    sent_by = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)


    class Meta:
        ordering = ('created_at',)
    
    def __str__(self):
        return f'{self.sent_by}'


class Room(models.Model):
    class Meta:
        verbose_name_plural = "Rooms"
    
    unique_id =  models.CharField(
        max_length=8,
        primary_key=True,
        editable=False,
        unique=True)
    
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=101, null=True, blank=True)
    password = models.CharField(max_length=50, blank=True, null=True)
    users = models.ManyToManyField(User, through='UserRoom', related_name='users_room')
    messages = models.ManyToManyField(Message, blank=True)

    def __str__(self) -> str:
        return str(self.name)

Я добавил потребителей к своим урлам:

path('ws/<str:room_id>', chat_consumers.ChatConsumer.as_asgi()),

И настроил мой asgi.py следующим образом:

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_app.settings')

from my_app import urls


# Gets the application we are currently in
django_asgi_application = get_asgi_application()

# Configure asgi application, setting up the ProtocolRouter
application = ProtocolTypeRouter(
    {
        'http': django_asgi_application,
        'websocket': AllowedHostsOriginValidator(
            AuthMiddlewareStack(URLRouter(urls.urlpatterns))
        )
    }
)

Хватит с django.

В моем приложении Flutter я создал новый класс с функцией для подключения к каналу websocket, используя пакет web_socket_channel:

class WSChannel {
  final _baseURL = "here is the URL, which I run django server on, 192.168.0.1:8000, just example URL";
  final String roomID;
  WSChannel({required this.roomID});

  connectToChannel() {
    final channel =
        WebSocketChannel.connect(Uri.parse('wss://$_baseURL/$roomID'));
    return channel;
  }
}

Сейчас я в основном следую учебнику, предоставленному Flutter, для связи с WebSocket. В моем экранном виджете я пытаюсь подключиться к WebSocket:

@override
  Widget build(BuildContext context) {
    final channel = WSChannel(roomID: widget.room.uniqueID).connectToChannel();
    return Scaffold(
      backgroundColor: bluePrimary,
      body: SafeArea(
          child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 36, vertical: 16),
              child: Column(children: [
                Form(
                  child: TextFormField(
                    controller: _controller,
                    decoration:
                        const InputDecoration(labelText: 'Send a message'),
                  ),
                ),
                const SizedBox(height: 24),
                StreamBuilder(
                  stream: channel.stream,
                  builder: (context, snapshot) {
                    return Text(snapshot.hasData ? '${snapshot.data}' : '');
                  },
                ),
                FloatingActionButton(
                  onPressed: () {
                    if (_controller.text.isNotEmpty) {
                      channel.sink.add(_controller.text);
                    }
                  },
                  tooltip: 'Send message',
                  child: const Icon(Icons.send),
                )
              ]))),
    );
  }

Затем я вижу следующий вывод:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HandshakeException: Connection terminated during handshake

ОБНОВИТЬ:

После выполнения этого решения мне удалось получить связь с моим сервером django. Однако она отклоняется. Вот моя новая ошибка во flutter:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: WebSocketException: Connection to 'http://192.168.0.1:8000/sjfAmH#' was not upgraded to websocket
#0      _WebSocketImpl.connect (dart:_http/websocket_impl.dart:1011:41)
#1      WebSocket.connect (dart:_http/websocket.dart:320:22)
#2      new IOWebSocketChannel.connect (package:web_socket_channel/io.dart:81:28)
#3      WSChannel.connectToChannel (package:watch_with_me/webSockets/websocket_channel.dart:11:28)
#4      _InsideRoomPageState.build (package:watch_with_me/pages/room/inside_room_page.dart:20:61)
#5      StatefulElement.build (package:flutter/src/widgets/framework.dart:5583:27)
#6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5471:15)
#7      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11)
#8      Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#9      StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5)
#10  <…>

А в консоли django:

WebSocket HANDSHAKING /sjfAmH [192.168.0.1:57255]
WebSocket REJECT /sjfAmH [192.168.0.1:57255]
WebSocket DISCONNECT /sjfAmH [192.168.0.1:57255]
Вернуться на верх