Sự cố khi kết nối websockets django và rung

lập trình


Tôi đang cố gắng thiết lập kết nối với mã Flutter và phụ trợ Django của mình bằng WebSockets, nhưng tiếc là tôi không thể làm như vậy, đã xem qua nhiều bài viết và video và về cơ bản mọi người đều làm như vậy mà không gặp lỗi.. Vui lòng cho biết thúc đẩy một chút, tôi chưa quen với điều này.

Những gì tôi đã thử:

Trước hết, tôi đã tạo một ứng dụng django mới có tên là ‘chat_app’ (đã thêm nó vào settings.py), nơi tôi đã tạo một mô hình Tin nhắn mới của mình:

Python
class Message(models.Model):
        room = models.ForeignKey(Room, on_delete=models.CASCADE)
        sender = models.ForeignKey(User, on_delete=models.CASCADE)
        content = models.TextField()
        timestamp = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return self.content

Sau đó, tôi tạo Consumer.py (ở đây tôi hơi bối rối, tốt hơn hết là nên đề cập đến phòng của tôi là Unique_id thay vì tên, vì ID là duy nhất chứ không phải tên trong trường hợp của tôi? Tôi đã quyết định giữ nguyên hướng dẫn.)

Python
# chat/consumers.py

import json
from channels.generic.websocket import AsyncWebsocketConsumer
from asgiref.sync import sync_to_async
from .models import Message
from room_app.models import Room

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.unique_id = self.scope['url_route']['kwargs']['unique_id']
        self.room_group_name = 'chat_%s' % self.unique_id

        # Check if the room exists in the database
        if not await self.room_exists():
            await self.close()
            return

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

        self.accept()

    def disconnect(self, close_code):
        # Leave room group
        self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from WebSocket
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # Save message to database
        Message.objects.create(
            room=self.unique_id,
            user=self.scope['user'],
            content=message
        )

        # Send message to room group
        self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message,
                'username': self.scope['user'].username
            }
        )

    # Receive message from room group
    def chat_message(self, event):
        message = event['message']
        username = event['username']

        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message,
            'username': username
        }))
    
    @sync_to_async
    def room_exists(self):
        return Room.objects.filter(unique_id=self.unique_id).exists()

Đã hoàn tất việc định tuyến.py

Python
# The WebSocket URL pattern for chat rooms is defined by this code
    websocket_urlpatterns = [
        re_path(r'ws/chat_app/(?P<room_name>\w+)/$', ChatConsumer.as_asgi()),
    ]

Sau đó thêm nó vào URL dự án của tôi:

Python
urlpatterns = [
        path('admin/', admin.site.urls),
        ...,
        path('ws/', include(websocket_urlpatterns)),
    ]

Và đây là cách tôi đang cố gắng thiết lập kết nối trong Flutter, về cơ bản đây là một trang mới, nơi tôi đang truyền dữ liệu phòng qua Bộ điều hướng từ trang trước:

class ChatScreen extends StatefulWidget {
  const ChatScreen({
    Key? key,
    required this.room,
  }) : super(key: key);
  final RoomModelResponse room;

  @override
  _ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final TextEditingController _controller = TextEditingController();
  final List<String> _messages = [];
  late WebSocketChannel _channel;

  @override
  void initState() {
    super.initState();
    _channel = IOWebSocketChannel.connect(
        'wss://192.168.0.11:8000/ws/chat_app/${widget.room.roomName}/'); // Update the WebSocket URL with your Django server address and room name
    _channel.stream.listen((message) {
      setState(() {
        _messages.add(message);
      });
    });
  }

Đầu ra:

Trong thiết bị đầu cuối rung tôi nhận được thông báo sau:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: WebSocketChannelException: WebSocketChannelException: WebSocketException: Connection to 'http://192.168.0.11:8000/ws/chat_app/3wVCio/#' was not upgraded to websocket
#0      new IOWebSocketChannel._withoutSocket.<anonymous closure> (package:web_socket_channel/io.dart:119:24)
#1      Stream.handleError.<anonymous closure> (dart:async/stream.dart:931:16)
#2      _HandleErrorStream._handleError (dart:async/stream_pipe.dart:269:17)
#3      _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:157:13)
#4      _RootZone.runBinaryGuarded (dart:async/zone.dart:1606:10)
#5      _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:358:15)
#6      _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:376:7)
#7      _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:280:7)
#8      _SyncStreamControllerDispatch._sendError (dart:async/stream_controller.dart:788:19)
#9 <…>

Django:

Not Found: /ws/chat_app/3wVCio/
[15/Feb/2024 16:46:19] "GET /ws/chat_app/3wVCio/ HTTP/1.1" 404 4379

Trong đó “3wVCio” là Unique_id của phòng tôi.

Tôi sẽ cung cấp thêm thông tin nếu cần

Cập nhật: Suy nghĩ mới nhất mà tôi đã thử là cho phép tất cả CORS gốc trong dự án của mình:

INSTALLED_APPS = [
    # other installed apps
    'corsheaders',
]
CORS_ALLOW_ALL_ORIGINS = True

Thật không may, không thành công..

Giải pháp 1

Về cơ bản bạn đã trả lời câu hỏi của chính mình mà không hề biết –

Trích dẫn:

Sau đó, tôi tạo Consumer.py (ở đây tôi hơi bối rối, tốt hơn hết là nên đề cập đến phòng của tôi là Unique_id thay vì tên, vì ID là duy nhất chứ không phải tên trong trường hợp của tôi? Tôi đã quyết định giữ nguyên hướng dẫn.)

Có vẻ như bạn đang sử dụng ‘unique_id’ ở Django, nhưng trong Flutter, bạn đang sử dụng ‘roomName’. Đảm bảo rằng bạn đang sử dụng tên tham số chính xác trong toàn bộ mô-đun của mình. Cập nhật Django ‘ChatConsumer’ của bạn để sử dụng ‘room_name’ thay vì ‘unique_id’ –

Python
self.unique_id = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.unique_id

Đảm bảo bạn cập nhật thông tin này trong toàn bộ mã Django của mình.

Sau đó, hãy đảm bảo URL WebSocket trong mã Flutter của bạn đang sử dụng đúng lược đồ (‘ws hoặc wss’) dựa trên cấu hình máy chủ Django của bạn. Nếu máy chủ Django của bạn đang sử dụng ‘ws’, bạn nên sử dụng –

phi tiêu
_channel = IOWebSocketChannel.connect(
    'ws://192.168.0.11:8000/ws/chat_app/${widget.room.roomName}/');

Tuy nhiên, nếu máy chủ Django của bạn được định cấu hình cho WebSocket an toàn (‘wss’), hãy sử dụng –

phi tiêu
_channel = IOWebSocketChannel.connect(
    'wss://192.168.0.11:8000/ws/chat_app/${widget.room.roomName}/');

Ở trên sẽ giải quyết các lỗi.

コメント

タイトルとURLをコピーしました