Django और फ़्लटर वेबसोकेट को कनेक्ट करते समय समस्या


मैं WebSockets का उपयोग करके अपने Django बैकएंड और फ़्लटर कोड के साथ एक कनेक्शन स्थापित करने का प्रयास कर रहा हूं, लेकिन दुर्भाग्य से मैं ऐसा करने में असमर्थ हूं, कई लेख और वीडियो देखे और हर कोई मूल रूप से बिना किसी त्रुटि के वही कर रहा है.. कृपया एक दें थोड़ा सा प्रयास, मैं इसमें थोड़ा नया हूं।

मैंने क्या प्रयास किया है:

सबसे पहले मैंने ‘chat_app’ नामक एक नया django ऐप बनाया (इसे सेटिंग्स.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

फिर मैंने अपना उपभोक्ता.py बनाया (यहां मैं थोड़ा भ्रमित हूं, क्या नाम के बजाय मेरे कमरे को यूनिक_आईडी संदर्भित करना बेहतर नहीं है, क्योंकि आईडी अद्वितीय है और मेरे मामले में नाम नहीं है? इसके साथ बने रहने का फैसला किया ट्यूटोरियल.)

अजगर
# 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()

routing.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)),
    ]

और इस तरह मैं फ़्लटर में एक कनेक्शन स्थापित करने का प्रयास कर रहा हूं, मूल रूप से यह एक नया पृष्ठ है, जहां मैं पिछले पृष्ठ से नेविगेटर के माध्यम से रूम डेटा पास कर रहा हूं:

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” मेरे कमरे की यूनिक_आईडी है।

यदि आवश्यकता हुई तो मैं अतिरिक्त जानकारी प्रदान करूंगा

अद्यतन: मेरे द्वारा आजमाया गया नवीनतम विचार मेरे प्रोजेक्ट में सभी मूल CORS को अनुमति देना है:

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

दुर्भाग्य से, कोई सफलता नहीं..

समाधान 1

आपने मूलतः बिना जाने अपने ही प्रश्न का उत्तर दे दिया है –

उद्धरण:

फिर मैंने अपना उपभोक्ता.py बनाया (यहां मैं थोड़ा भ्रमित हूं, क्या नाम के बजाय मेरे कमरे को यूनिक_आईडी संदर्भित करना बेहतर नहीं है, क्योंकि आईडी अद्वितीय है और मेरे मामले में नाम नहीं है? इसके साथ बने रहने का फैसला किया ट्यूटोरियल.)

ऐसा लगता है कि आप Django में ‘unique_id’ का उपयोग कर रहे हैं, लेकिन फ़्लटर में, आप ‘roomName’ का उपयोग कर रहे हैं। सुनिश्चित करें कि आप अपने पूरे मॉड्यूल में सही पैरामीटर नामों का उपयोग कर रहे हैं। अपने Django ‘ChatConsumer’ को ‘unique_id’ के बजाय ‘room_name’ का उपयोग करने के लिए अपडेट करें –

अजगर
self.unique_id = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.unique_id

सुनिश्चित करें कि आपने इसे अपने सभी Django कोड में अपडेट कर दिया है।

फिर सुनिश्चित करें कि आपके फ़्लटर कोड में 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}/');

उपरोक्त को त्रुटियों का समाधान करना चाहिए।

コメント

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