[ad_1]
我正在尝试使用 WebSockets 与我的 Django 后端和 Flutter 代码建立连接,但不幸的是我无法这样做,浏览了很多文章和视频,每个人基本上都在做同样的事情而没有收到错误。有点推动,我对此有点陌生。
我尝试过的:
首先,我创建了一个名为“chat_app”的新 django 应用程序(将其添加到 settings.py 中),在其中创建了消息的新模型:
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
然后我制作了consumers.py(在这里我有点困惑,引用我的房间unique_id而不是名称不是更好吗,因为ID是唯一的,而不是我的情况下的名称?决定坚持使用教程。)
# 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()
完成路由.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()), ]
然后将其添加到我的项目 URL 中:
urlpatterns = [ path('admin/', admin.site.urls), ..., path('ws/', include(websocket_urlpatterns)), ]
这就是我尝试在 Flutter 中建立连接的方式,基本上它是一个新页面,我在其中通过上一页的导航器传递房间数据:
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); }); }); }
输出:
在颤振终端中,我收到以下消息:
[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 <…>
姜戈:
Not Found: /ws/chat_app/3wVCio/ [15/Feb/2024 16:46:19] "GET /ws/chat_app/3wVCio/ HTTP/1.1" 404 4379
其中“3wVCio”是我房间的 unique_id。
如果需要,我会提供更多信息
更新: 我最近尝试过的想法是允许我的项目中的所有原始 CORS:
INSTALLED_APPS = [ # other installed apps 'corsheaders', ] CORS_ALLOW_ALL_ORIGINS = True
不幸的是,没有成功。。
解决方案1
你基本上已经在不知情的情况下回答了你自己的问题 –
引用:然后我制作了consumers.py(在这里我有点困惑,引用我的房间unique_id而不是名称不是更好吗,因为ID是唯一的,而不是我的情况下的名称?决定坚持使用教程。)
您似乎在 Django 中使用“unique_id”,但在 Flutter 中,您使用“roomName”。 确保您在整个模块中使用正确的参数名称。 更新您的 Django ‘ChatConsumer’ 以使用 ‘room_name’ 而不是 ‘unique_id’ –
self.unique_id = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.unique_id
确保在所有 Django 代码中更新此内容。
然后确保 Flutter 代码中的 WebSocket URL 使用基于 Django 服务器配置的正确方案(“ws 或 wss”)。 如果您的 Django 服务器使用“ws”,您应该使用 –
_channel = IOWebSocketChannel.connect( 'ws://192.168.0.11:8000/ws/chat_app/${widget.room.roomName}/');
但是,如果您的 Django 服务器配置为安全 WebSocket (‘wss’),请使用 –
_channel = IOWebSocketChannel.connect( 'wss://192.168.0.11:8000/ws/chat_app/${widget.room.roomName}/');
以上应该可以解决错误。
[ad_2]
コメント