React 和 Django 连接与通道设置 - WebSocket 连接失败

问题描述 投票:0回答:1

我尝试使用通道设置 Django 来向 React 提供通知。

https://github.com/axilaris/react-django-channels<-- I have put my project code here.

在后端/后端/settings.py

INSTALLED_APPS = [
..
    'channels',
]



CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels.layers.InMemoryChannelLayer'
    }
}

ASGI_APPLICATION = 'backend.routing.application'

在后端/后端/asgi.py

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
#import backend.routing
import user_api.routing

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

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": URLRouter(
        user_api.routing.websocket_urlpatterns
        #backend.routing.websocket_urlpatterns <-- not sure if should be this
    ),
})

在后端/user_api/routing.py

from channels.routing import ProtocolTypeRouter, URLRouter
from django.urls import path
from . import consumers

application = ProtocolTypeRouter({
    "websocket": URLRouter([
        path("ws/notifications/", consumers.NotificationConsumer.as_asgi()),
    ]),
})

在后端/user_api/consumers.py

from channels.generic.websocket import AsyncWebsocketConsumer
import json

class NotificationConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        print "XXX connect"
        await self.accept()

    async def disconnect(self, close_code):
        print "XXX disconnect"
        pass

    async def receive(self, text_data):
        print "XXX receive"
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        await self.send(text_data=json.dumps({
            'message': message
        }))

终于在 React 中,App.js

useEffect(() => {

    const ws = new WebSocket('ws://localhost:8000/ws/notification/');

    ws.onopen = () => {
      console.log('Connected to notification websocket');
    };

    ws.onmessage = e => {
      const data = JSON.parse(e.data);
      setMessage(data.message);
    };

    ws.onerror = e => {
      console.error('WebSocket error', e);
    };

    ws.onclose = e => {
      console.error('WebSocket closed', e);
    };

    return () => {
      ws.close();
    };

  }, []);

从浏览器控制台日志来看,似乎无法连接

App.js:59 WebSocket connection to 'ws://localhost:8000/ws/notification/' failed: 
App.js:71 WebSocket error Event
ws.onerror @ App.js:71
App.js:75 WebSocket closed CloseEvent

请注意,React 运行在端口 3000 上,Django 运行在端口 8000 上

% npm start <-- React

% python manage.py runserver <-- Django

来自 django 和 React 的日志https://gist.github.com/axilaris/2e0a5ae1887f7d12a226565efa85dd6f

反应日志

App.js:59 WebSocket connection to 'ws://localhost:8000/ws/notification/' failed: 
App.js:71 WebSocket error  Event {isTrusted: true, type: 'error', target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …}
App.js:75 WebSocket closed  CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '', type: 'close', …}

django 日志

WARNING:django.request:Not Found: /ws/notification/
Not Found: /ws/notification/
WARNING:django.request:Not Found: /ws/notification/
[27/Mar/2024 14:19:44] "GET /ws/notification/ HTTP/1.1" 404 2230
[27/Mar/2024 14:19:44,843] - Broken pipe from ('127.0.0.1', 60943)
[27/Mar/2024 14:19:44] "GET /ws/notification/ HTTP/1.1" 404 2230
[27/Mar/2024 14:19:44,843] - Broken pipe from ('127.0.0.1', 60947)

我的感觉是 Django 端缺少一些东西,通道没有正确设置并且没有监听连接。我的设置中缺少什么。 有人怀疑:

  • 由于通道套接字设置位于 user_api 中,因此未调用通道
  • CORS?
reactjs django websocket cors
1个回答
0
投票

问题:-

看下面。

application = ProtocolTypeRouter({
    "websocket": URLRouter([
        path("ws/notifications/", consumers.NotificationConsumer.as_asgi()),
    ]),
})

notifications

还有

const ws = new WebSocket('ws://localhost:8000/ws/notification/');

notification

路径应该是相同的路径。

使用方法如下。

答案:-

application = ProtocolTypeRouter({
    "websocket": URLRouter([
        path("ws/notifications/", consumers.NotificationConsumer.as_asgi()),
    ]),
})

还有

const ws = new WebSocket('ws://localhost:8000/ws/notifications/');

© www.soinside.com 2019 - 2024. All rights reserved.