[ad_1]
J’essaie d’établir une connexion avec mon backend Django et mon code Flutter à l’aide de WebSockets, mais malheureusement je ne parviens pas à le faire, j’ai parcouru de nombreux articles et vidéos et tout le monde fait essentiellement la même chose sans recevoir d’erreur. Veuillez donner un petit coup de pouce, je suis un peu nouveau dans ce domaine.
Ce que j’ai essayé :
Tout d’abord, j’ai créé une nouvelle application Django appelée ‘chat_app’ (je l’ai ajoutée dans settings.py), où j’ai créé un nouveau modèle de mes messages :
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
Ensuite, j’ai créé mon consumer.py (ici, je suis un peu confus, n’est-il pas préférable de faire référence à ma chambre unique_id au lieu de son nom, puisque l’identifiant est unique et non le nom dans mon cas ? J’ai décidé de m’en tenir au Didacticiel.)
# 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()
Terminé le routage.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()), ]
Ensuite, je l’ai ajouté aux URL de mon projet :
urlpatterns = [ path('admin/', admin.site.urls), ..., path('ws/', include(websocket_urlpatterns)), ]
Et c’est ainsi que j’essaie d’établir une connexion dans Flutter, en gros, c’est une nouvelle page, où je transmets les données de la pièce via le navigateur de la page précédente :
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); }); }); }
Les sorties:
Dans le terminal Flutter, j’obtiens le message suivant :
[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
Où le “3wVCio” est l’identifiant unique de ma chambre.
Je fournirai des informations supplémentaires si besoin
Mise à jour: La dernière chose que j’ai essayée consiste à autoriser tous les CORS d’origine dans mon projet :
INSTALLED_APPS = [ # other installed apps 'corsheaders', ] CORS_ALLOW_ALL_ORIGINS = True
Malheureusement, aucun succès..
Solution 1
En gros, vous avez répondu à votre propre question sans le savoir –
Citation:Ensuite, j’ai créé mon consumer.py (ici, je suis un peu confus, n’est-il pas préférable de faire référence à ma chambre unique_id au lieu de son nom, puisque l’identifiant est unique et non le nom dans mon cas ? J’ai décidé de m’en tenir au Didacticiel.)
Il semble que vous utilisiez « unique_id » dans Django, mais dans Flutter, vous utilisez « roomName ». Assurez-vous que vous utilisez les noms de paramètres corrects dans tous vos modules. Mettez à jour votre Django ‘ChatConsumer’ pour utiliser ‘room_name’ au lieu de ‘unique_id’ –
self.unique_id = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.unique_id
Assurez-vous de mettre à jour cela dans tout votre code Django.
Assurez-vous ensuite que l’URL WebSocket dans votre code Flutter utilise le schéma correct (« ws ou wss ») en fonction de la configuration de votre serveur Django. Si votre serveur Django utilise ‘ws’, vous devez utiliser –
_channel = IOWebSocketChannel.connect( 'ws://192.168.0.11:8000/ws/chat_app/${widget.room.roomName}/');
Cependant, si votre serveur Django est configuré pour WebSocket sécurisé (« wss »), utilisez –
_channel = IOWebSocketChannel.connect( 'wss://192.168.0.11:8000/ws/chat_app/${widget.room.roomName}/');
Ce qui précède devrait résoudre les erreurs.
[ad_2]
コメント