[ad_1]
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:
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.)
# 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
# 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:
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’ –
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 –
_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 –
_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.
[ad_2]
コメント