【问题标题】:Django WebSocket DISCONNECT /ws/chat/lobby/ [127.0.0.1:3022]Django WebSocket DISCONNECT /ws/chat/lobby/ [127.0.0.1:3022]
【发布时间】:2020-02-13 09:35:46
【问题描述】:

我想创建聊天应用程序,我在这里关注https://channels.readthedocs.io/en/latest/tutorial/part_2.html

chat/
    __init__.py
    routing.py
    urls.py
    settings.py
    wsgi.py

我将此代码添加到我的 routing.py

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing

application = ProtocolTypeRouter({
    # (http->django views is added by default)
    'websocket': AuthMiddlewareStack(
        URLRouter(
            chat.routing.websocket_urlpatterns
        )
    ),
})

在我的 settings.py 中

ASGI_APPLICATION = 'Accounting.routing.application'
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}

在我的 urls.py 中

urlpatterns = [
    path('chat/', include('chat.urls')),
    path('admin/', admin.site.urls),
]

在我的聊天应用中

chat/
    __init__.py
    consumers.py
    routing.py
    templates/
        chat/
            index.html
            room.html
    urls.py
    views.py

我有消费者.py

from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
import json

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):
        # 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
        }))

这是我聊天中的代码>routing.py

from django.urls import re_path

from . import consumers

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

在我的聊天中>views.py

from django.shortcuts import render

def index(request):
    return render(request, 'chat/index.html', {})

def room(request, room_name):
    return render(request, 'chat/room.html', {
        'room_name': room_name
    })

我的聊天应用中有 urls.py

从 django.urls 导入路径

from . import views
app_name = 'chat'
urlpatterns = [
    path('', views.index, name='index'),
    path('<str:room_name>/', views.room, name='room'),
]

我遵循所有方向,我复制粘贴代码,py 的位置,turorial 中的所有内容,但我仍然收到此错误

我错过了什么吗?

更新

当我在我的 pycharm 终端中尝试这个时 docker run -p 6379:6379 -d redis:2.8

【问题讨论】:

  • 你运行redis服务器了吗?
  • redis 服务器?那是什么?
  • CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('127.0.0.1', 6379)], }, }, } 您在设置中添加此代码,因为 django-channels 将进程放在队列系统上。该系统是 django-channels 使用的 redis。所以你应该运行它。使用 docker docker run -p 6379:6379 -d redis:2.8 运行它
  • 我得到相同的结果
  • 我更新了我的问题 @ishakO 先生。

标签: python django django-rest-framework


【解决方案1】:

这里有一些问题。

1) 您正在混合使用 asyncsync 消费者代码。

我建议只使用async consumer all you methods 然后应该是async 方法。

看起来您正在从同步上下文调用 get_thread,但 get_thread 已包装在 database_sync_to_async 中,因此需要从异步上下文调用(并且需要等待)。

你还需要awaitself.channel_layer.group_add

2) 在您的ThreadView 中有一个ChatMessage.objects.create,您还应该通过线程通道组发送消息。

from channels.layers import get_channel_layer
channel_layer = get_channel_layer()

async_to_sync(channel_layer.group_send)(f"thread_{thread.id}", {"type": "chat.message", "text": ...})

您还需要将聊天消息保存到 websocket_receive 中的数据库。

【讨论】:

    【解决方案2】:

    我认为在您的 settings.py 文件中启用了一个名为 CHANNEL_LAYER 的模板变量(这是错误的确切原因),因此请尝试从 project/settings.py 中删除这段代码

    CHANNEL_LAYERS = {
        'default': {
            'BACKEND': '',
            'CONFIG': {
               "hosts":[127.0.0.1],
            },
        },
    }
    

    就我而言,这是错误的根本原因。如果它不起作用,请尝试更改您的 chat/routing.py 文件。

    【讨论】:

      【解决方案3】:

      添加“.as_asgi()”

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

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,它是服务器断开连接的问题,这导致了所有这些问题。 https://github.com/tporadowski/redis/releases/tag/v5.0.9 下载最新版本并运行 redis-server 应用程序。它解决了我的问题

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-17
          • 2015-10-26
          • 1970-01-01
          • 2021-06-18
          • 2016-05-13
          • 2021-04-16
          • 1970-01-01
          • 2017-03-09
          相关资源
          最近更新 更多