Django Channels中的Websocket连接无法工作(“WebSocket连接到'ws:// localhost:8000 / ws / board / 7 /'失败:”)

3
我正在尝试为我正在开发的Django项目运行一个websocket,但是我无法连接websocket,这很奇怪,因为我从channels文档中复制了示例聊天应用程序,并且它可以正常工作,但是当我将相同的代码复制粘贴到我的项目中时,它就不能正常工作。
因此,以下是相关的代码部分:
views.py中的相关视图
def board_view(request, key):

    board = get_object_or_404(request.user.boards, pk=key)

    key = dumps(board.pk)
    return render(request, 'core/board.html', 
            {"board":board, "permission":user_permission, "key":key})

board.html(相关部分)

    <script>
        const key = JSON.parse("{{key|escapejs}}");

        const chatSocket = new WebSocket(
            'ws://'
            + window.location.host
            + '/ws/board/'
            + key
            + '/'
        );

routing.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r"^ws/board/(?P<key>\d+)/$", consumers.ChatConsumer.as_asgi()),
]

consumers.py

import json
from channels.generic.websocket import WebsocketConsumer


class ChatConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()

        self.send(text_data=json.dumps({
            'type':'connection_established',
            'message':'you are now connected'
        }))

    def disconnect(self, close_code):
        pass

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

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

asgi.py

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

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

django_asgi_app = get_asgi_application()

import core.routing

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": AllowedHostsOriginValidator(
            AuthMiddlewareStack(URLRouter(core.routing.websocket_urlpatterns))
        ),
})

settings.py(相关部分): ASGI_APPLICATION = 'sketchboard.asgi.application' 以及

INSTALLED_MY_APPS = [
    'core',
]

INSTALLED_EXTENSIONS = [
    'daphne',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'guest_user',
    'guest_user.contrib.allauth',
    'rest_framework',
    'channels',
]

这与channels文档中的教程websocket设置几乎相同(当我尝试时,它运行良好)。

所以我应该从“board_view”页面的控制台上得到“you are now connected”(如consumers.py中定义的),但是我却得到了一个

WebSocket connection to 'ws://localhost:8000/ws/board/7/' failed: 消息。

我应该指出这里的7是“key”,它是一个动态变量,但这部分绝对有效。 我还尝试过在board.htmlrouting.py中只输入“test”作为路由, 像这样:

const chatSocket = new WebSocket('ws://' + window.location.host + '/test');
但我收到了相同的错误,所以我不认为问题在于routing.pyboard.html文件。 我还尝试向django discord server提问,但他们无法提供帮助。

这个问题真的让我束手无策,所以任何帮助都将不胜感激!:)

3个回答

6

可能您安装了最新的默认版本4,该版本不会在开发模式下启动ASGI服务器。请验证并安装channels版本==3.0.5。确保在运行runserver命令时ASGI服务器已启动。

(版本4通过daphne支持ASGI服务器,我猜是这样,但没有尝试过。)

如果没有,请告诉我,我们将进一步讨论。

enter image description here


我正在使用Channels 4版本,但它可以在开发服务器上运行,因为命令提示符进行了验证(类似于您发布的图像)。此外,我从网页控制台获得的错误确实表明存在WebSocket,但它无法连接。我还尝试使用Channels 3.0.5版本,但Django似乎不再识别它。但是Channels 4肯定也可以在开发服务器上运行。 - God-status
你的命令提示符是否验证了启动ASGI/Channels开发服务器? - Ranu Vijay
请验证您的websocket_urlpatterns,我相信WebSocket在URL中期望房间名称而不是键值。re_path(r"ws/chat/(?P<room_name>\w+)/$", consumers.ChatConsumer.as_asgi())。 - Ranu Vijay
Websocket 在哪里指定它期望的房间名称? - God-status
请问您能否分享一下在启动开发服务器时命令提示符的输出以及详细的错误信息。 - Ranu Vijay
显示剩余10条评论

4
对于channels==4.0.0,需要进行以下更改here,这要求您在django.contrib.staticfiles之前将daphne放入INSTALLED_APPS中。还要运行pip install -U 'channels[daphne]' channels-redis以确保您具有兼容的daphnechannels-redis版本。
或者,似乎从项目根目录(其中manage.py位于)而不是python manage.py runserver运行daphne <your main app>.asgi:application也可以。
此外,如前所述,降级到channels==3.0.5是另一种方法,可以使其正常工作,而无需将daphne添加到INSTALLED_APPS中。

2
将'daphne'添加到INSTALLED_APPS中就可以了。 - undefined
它对我有用,你是最棒的。 - undefined

0

你在settings.py文件中缺少了这个

ASGI_APPLICATION = 'appname.asgi.application'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接