Django:WebSocket 握手期间出错:意外的响应代码:500

Django: Error during WebSocket handshake: Unexpected response code: 500

我一直在按照 this 教程构建聊天应用程序。

我一直面临与 'ws://127.0.0.1:8000/ws/lobby/' 的 WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:500 错误。我也检查了其他解决方案,但它们似乎不起作用。

控制台在 (room.html)

处显示错误
            'ws://'
            + window.location.host
            + '/ws/'
            + roomName
            + '/'
            );

在控制台中。

终端显示如下:

HTTP GET /favicon.ico/ 200 [0.01, 127.0.0.1:53842]
HTTP GET /lobby/?username=darsh 200 [0.01, 127.0.0.1:53842]
WebSocket HANDSHAKING /ws/lobby/ [127.0.0.1:53844]
HTTP GET /favicon.ico/ 200 [0.01, 127.0.0.1:53842]
Exception inside application: No route found for path 'ws/lobby/'.
Traceback (most recent call last):
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/staticfiles.py", line 44, in __call__
    return await self.application(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/routing.py", line 71, in __call__
    return await application(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/sessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/sessions.py", line 263, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/middleware.py", line 26, in __call__
    return await self.inner(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/routing.py", line 168, in __call__
    raise ValueError("No route found for path %r." % path)
ValueError: No route found for path 'ws/lobby/'.
WebSocket DISCONNECT /ws/lobby/ [127.0.0.1:53844]

我附上我使用的代码:

chat/room.html


<html>
  <head>
    <meta charset="utf-8"/>
    <title>Chatty</title>
    <!-- Include Bulma CSS framework -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css">
  </head>

  <body>
    <section class="section">
        <div class="container">
          <div class="columns is-multiline">
            <div class="column is-6 is-offset-3 mb-6">
              <section class="hero is-primary">
                <div class="hero-body">
                  <p class="title">Chatty</p>
                  <p class="subtitle">A simple chat built with Django, Channels and Redis</p>
                </div>
              </section>
            </div>
  
            <div class="column is-6 is-offset-3">
                <div class="box">     
                  <div id="chat-messages">
                  </div>
                </div>
  
                <div class="field">
                  <div class="control">
                    <input class="input" type="text" placeholder="Message" id="chat-message-input">
                  </div>
                </div>
  
                <div class="field">
                  <div class="control">
                    <a class="button is-info" id="chat-message-submit">Submit</a>
                  </div>
                </div>
  
                <small class="has-text-grey-light">Your username: {{ username }}</small>
              </div>
            </div>
         </div>
      </section>
      
      {{ room_name|json_script:"json-roomname" }}
      {{ username|json_script:"json-username" }}

      <script>
        const roomName = JSON.parse(document.getElementById('json-roomname').textContent);
        const userName = JSON.parse(document.getElementById('json-username').textContent);

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

            chatSocket.onmessage = function(e) {
                const data = JSON.parse(e.data);
              
                if (data.message) {
                  document.querySelector('#chat-messages').innerHTML += ('' + data.username + ': ' + data.message + '');
                } else {
                  alert('The message was empty!')
                }
            };
              
            document.querySelector('#chat-message-input').focus();
            document.querySelector('#chat-message-input').onkeyup = function(e) {
            if (e.keyCode === 13) {
                document.querySelector('#chat-message-submit').click();
            }
            };
              
            document.querySelector('#chat-message-submit').onclick = function(e) {
            const messageInputDom = document.querySelector('#chat-message-input');
            const message = messageInputDom.value;
            
            chatSocket.send(JSON.stringify({
                'message': message,
                'username': userName,
                'room': roomName
            }));
            
            messageInputDom.value = '';
            };

        chatSocket.onclose = function(e) {
        console.error('The socket closed unexpectedly');
        };

      </script>

  </body>
</html>

routing.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
  path('ws/', consumers.ChatConsumer.as_asgi()), # Using asgi
]

consumers.py

from channels.generic.websocket import AsyncWebsocketConsumer # The class we're using
from asgiref.sync import sync_to_async # Implement later

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

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

        await self.accept()

    async def disconnect(self, close_code):
        #Leave group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        data = json.loads(text_data)
        message = data['message']
        username = data['username']
        room = data['room']

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

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

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

您的路线需要 room_name

使用re_path

from django.urls import re_path 

websocket_urlpatterns = [
  re_path('ws/(?P<room_name>\w+)/', consumers.ChatConsumer.as_asgi()), # Using asgi
]

在您的情况下,这是 lobby,因此出现错误。