【问题标题】:Unable to connect to django channels on react native app using web sockets无法使用网络套接字连接到本机应用程序上的 Django 频道
【发布时间】:2022-11-30 04:03:56
【问题描述】:

我正在尝试使用网络套接字连接到 Django 服务器/频道。 HTTP 视图正在工作,但“ws”(WebSocket)连接正在被拒绝只要反应本机应用程序.它在 React Web App 上完美运行

适用于 React Native 移动应用程序的 App.js

  var ws = React.useRef(
new WebSocket('ws://192.168.10.14:8000/ws/chat/Hello/'),
).current;
ws.onopen = () => {
    setServerState('Connected to the server');
  };
  ws.onclose = e => {
    setServerState('Disconnected. Check internet or server.');
  };
  ws.onerror = e => {
    console.error(e);
    setServerState(e.message);
  };
  ws.onmessage = e => {
    serverMessagesList.push(e.data);
    setServerMessages([...serverMessagesList]);
  };
  const submitMessage = () => {
    ws.send(messageText);
    setMessageText('');
    setInputFieldEmpty(true);
  };

我得到这个错误错误 {"isTrusted": false, "message": "预期 HTTP 101 响应但为 '403 访问被拒绝'"}

但是在网络上

用于 React Web 应用程序的 App.js

  let W3CWebSocket = require("websocket").w3cwebsocket;
  var client = new W3CWebSocket("ws://192.168.10.14:8000/ws/chat/Hello/");
  client.onerror = function (e) {
    console.log("Connection Error: " + JSON.stringify(e));
    console.log("Connection Error");
  };

  client.onopen = function () {
    console.log("WebSocket Client Connected");
    let data = JSON.stringify({ message: "Hello Socket!" }); 
    client.send(data);
  };

  client.onclose = function () {
    console.log("echo-protocol Client Closed");
  };

  client.onmessage = function (e) {
    if (typeof e.data === "string") {
      console.log("Received: '" + e.data + "'");
    }
  };

此代码运行良好

现在对于后端网址.py

websocket_urlpatterns = [
    re_path(r'ws/chat/(?P<room_name>\w+)/$', consumer.ChatConsumer.as_asgi()),
]

消费者.py

from asgiref.sync import async_to_sync
import json
# WebsocketConsumer is a class that we can inherit from to create a consumer
# A consumer is a class that handles WebSocket connections
# so that we can send and receive messages over the WebSocket
from channels.generic.websocket import WebsocketConsumer


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

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

        self.accept()

    def disconnect(self, close_code):
        print(close_code)
        # Leave room group
        async_to_sync(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']

        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

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

        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message
        }))

设置.py

ASGI_APPLICATION = "xyz.asgi.application"


CHANNEL_LAYERS = {
    'default': {
        'BACKEND': "channels.layers.InMemoryChannelLayer",
        'hosts': [('localhost')],
    }
}

asgi.py

"""
ASGI config for XYZ project.

"""

import Appointments
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'XYZ.settings')

django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter({
    "http": django_asgi_app,
    
    "websocket": AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                Appointments.urls.websocket_urlpatterns
            )
        )
    ),
})

注意:相同的后端对于 React.js 完美运行,但对于 React Native 会出现上述错误

【问题讨论】:

    标签: reactjs react-native django-rest-framework websocket django-channels


    【解决方案1】:

    这是我以前遇到过一次的奇怪错误

    对我有用的是为移动应用程序创建不同的渠道路线

    websocket_urlpatterns = [
    re_path(r'ws/chat/(?P<room_name>w+)/$', consumer.ChatConsumer.as_asgi()),
    re_path(r'ws/mobile-chat/(?P<room_name>[^/]+)/$', 
    consumer.ChatConsumer.as_asgi())
    ]
    

    我不知道它为什么或如何工作,因为显然没有错误的原因或解决方案,但我希望它也对你有用!

    【讨论】:

    • 不,已经尝试过了,没有用。它只是拒绝请求
    【解决方案2】:

    1- React Native 现在内置了对 WebSockets 的支持,因此无需下载任何外部库。

    2-删除 useRef 将使其工作

     var ws = React.useRef(new WebSocket('ws://192.168.10.14:8000/ws/chat/Hello/'),
    

     var ws = new WebSocket('ws://192.168.10.14:8000/ws/chat/Hello/'),
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-14
      • 2022-01-01
      • 1970-01-01
      • 2012-10-21
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      相关资源
      最近更新 更多