我已经为集团用户之间的实时消息实现了Django Channel.

它在本地系统上工作正常,但当我将其推送到服务器时,我得到错误: WebSocket connection to 'ws://nailsent.developmentrecords.com/ws/chat/13/' failed: Error during WebSocket handshake: Unexpected response code: 404 (anonymous) @ 13:465

This is my script

<script>
const currentDate = new Date();
// Get the month abbreviation
const month = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(currentDate);
const day = currentDate.getDate();
const year = currentDate.getFullYear();
let hours = currentDate.getHours();
const ampm = hours >= 12 ? 'p.m.' : 'a.m.';
hours = hours % 12 || 12; // Convert 24-hour to 12-hour format

// Get the minutes
const minutes = currentDate.getMinutes();

// Combine all parts into the desired format
const formattedTime = '${month}. ${day}, ${year}, ${hours}:${minutes} ${ampm}';

    const card = document.querySelector('.card-body');
    const sendMessageInput = document.getElementById('sendMessageInput');
    const sendButton = document.getElementById('sendButton');
    const group_id = "{{ group_id }}";
    const userImg = "{{user_image}}"
    const username = "{{request.user.username}}";

    const chatSocket = new WebSocket('wss://${window.location.host}/ws/chat/${group_id}/');
    chatSocket.onopen = function (event) {
        console.log('WebSocket connection established.');
    };
    document.addEventListener("keydown", (e)=>{
        if (e.keyCode === 13){
            sendMessage();
        }
    })
    // Event listener for send button click
    sendButton.addEventListener('click', sendMessage);
    scrollToBottom();
    // Event listener for incoming messages
    if ("Notification" in window) {
        // Request permission from the user to display notifications
        if (Notification.permission !== "granted") {
            Notification.requestPermission();
        }
    }

    // Function to send a notification
    
    function showCustomNotification(username, message, image) {
    const customNotification = document.getElementById('custom-notification');
    customNotification.querySelector('.username').innerText = username;
    customNotification.querySelector('.message').innerText = message;
    const imageElement = customNotification.querySelector('.image');
    imageElement.src = image; 
    customNotification.style.display = 'block';
    
    // setTimeout(() => {
    //     customNotification.style.display = 'none';
    // }, 5000); // Hides the notification after 5 seconds (adjust as needed)
}

    // Function to append received message to receiver box
    chatSocket.onmessage = function (event) {
        try {
            const data = JSON.parse(event.data);
            if (data.message) {
                // Check if the message is from another user
                if (data.username !== username) {
                    
                    appendReceivedMessage(data.username, data.message, data.image);
                    showCustomNotification(data.username, data.message, data.image)
                }
            }
        } catch (error) {
            console.error('Error processing message:', error);
        }
    };

    // Function to append received message to receiver box
    function appendReceivedMessage(username, message, image) {
        const messageHTML = '<div class="receiver-box">
                            <div class="row">
                                <div class="col-1 d-flex align-items-end">
                                    <img src="${image ? image : "{% static 'all_pages/images/icons/message-def-img.png' %}" }" class="sender-image"
                                   alt="User Image"/>
                                </div>
                                <div class="col-11 ps-3 mb-2">
                                    <div class="ps-2 text-secondary d-block mb-1 text-left"><small>${username}</small></div>
                                    <div class="msg-box received-msg receiver-box1">${message}</div>
                                    <p class="time">${formattedTime}</p>
                                </div>
                            </div>
                        </div>';

        // Create a temporary container element
        const container = document.createElement('div');
        container.classList.add("col-12");
        container.innerHTML = messageHTML;

        // Append the container's child to the desired parent element
        card.appendChild(container);
        scrollToBottom() 
    }

    // Function to send message
    function sendMessage() {
        const message = sendMessageInput.value.trim();
        if (message !== '') {
            appendSentMessage(message);
            chatSocket.send(JSON.stringify({
                'message': message,
                'username': username,
                'group_id': group_id,
                'image': userImg,
            }));
            sendMessageInput.value = '';
        }
    }

    // Function to append sent message to sender box
    function appendSentMessage(message) {
        const messageHTML = '<div class="sender-box">
            <div class="row">
                <div class="col-11 d-flex align-items-end flex-column ps-3 mb-2">
                    <div class="ps-2 text-secondary d-block mb-1 text-right"><small>${username}</small></div>
                    <div class="msg-box sent-msg sender-box1">${message}</div>
                    <p class="time">${formattedTime}</p>
                </div>
                <div class="col-1 d-flex justify-content-end">
                    <div class="d-flex justify-content- align-items-end">
                        <img src=${userImg} class="receiver-image">
                    </div>
                </div>
            </div>
        </div>';

        // Create a temporary container element
        const container = document.createElement('div');
        container.classList.add("col-12");
        container.innerHTML = messageHTML;

        // Append the container's child to the desired parent element
        card.appendChild(container);

     scrollToBottom() 
    }

    function scrollToBottom() {
        card.scrollTop = card.scrollHeight;
    }

</script>

Consumer.py

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "nailSent_porject.settings")
from channels.layers import get_channel_layer
import django
django.setup()
from channels.generic.websocket import AsyncWebsocketConsumer
import json
from asgiref.sync import sync_to_async
from .models import Message, Group, User
# Now you can access settings like this
class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.group_id = self.scope['url_route']['kwargs']['group_id']
        self.group_name = f'{self.group_id}'
        # Join  group
        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )
        await self.accept()
        url_pattern = self.scope['url_route']['route']
        print(" this is a url=========================", url_pattern)

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.group_name,
            self.channel_name
        )
    
    async def receive(self, text_data):
        try:
            data = json.loads(text_data)
            message = data['message']
            username = data['username']
            group =  data['group_id']
            image  = data['image']
            # Send message to room group
            await self.save_message(message,username,group)
            await self.channel_layer.group_send(
                self.group_name,
                {
                    'type': 'chat_message',
                    'message': message,
                    'username': username,
                    'image':image,
                }
            )
        except json.JSONDecodeError:
            self.send(data=json.dumps({
                'error': 'Invalid JSON format.'
            }))
        except Exception as e:
            self.send(data=json.dumps({
                'error': str(e)
            }))

    # Receive message from room group
    async def chat_message(self, event):
        try:
            message = event['message']
            username =  event['username']
            image = event['image']
            # sending message to websocket
            await self.send(text_data=json.dumps({
                'message': message,
                'username': username,
                'image':image,
            }))
        except KeyError:
            print("Error: 'message' key not found in event:", event)
        except Exception as e:
            print("Error in chat_message:", e)
    @sync_to_async
    def save_message(self, message,username, group_id):
        user = User.objects.get(username=username)
        group = Group.objects.get(id=group_id)
        Message.objects.create(content=message,sender=user,group=group)

routing.py

from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'wss/chat/(?P<group_id>[^/]+)/$', consumers.ChatConsumer.as_asgi()),
    ]

application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    ),
})

我还创建了一个名为Daphne.socketdaphne.service的文件,但是,Daphne在服务器上启动,但给了我上面的错误.

推荐答案

try 将/ws/个位置添加到项目的nginx配置文件中.例如:

location /ws/ {
    proxy_pass http://localhost:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

在本例中,WebSocket连接位于8000端口

Python相关问答推荐

Odoo 14 hr. emergency.public内的二进制字段

为什么带有dropna=False的groupby会阻止后续的MultiIndex.dropna()工作?

海运图:调整行和列标签

Mistral模型为不同的输入文本生成相同的嵌入

关于Python异步编程的问题和使用await/await def关键字

从spaCy的句子中提取日期

为什么NumPy的向量化计算在将向量存储为类属性时较慢?'

SQLAlchemy bindparam在mssql上失败(但在mysql上工作)

Python中的变量每次增加超过1

matplotlib + python foor loop

如何检测鼠标/键盘的空闲时间,而不是其他输入设备?

使用字典或列表的值组合

mdates定位器在图表中显示不存在的时间间隔

jsonschema日期格式

如何在验证文本列表时使正则表达式无序?

没有内置pip模块的Python3.11--S在做什么?

查找数据帧的给定列中是否存在特定值

我可以同时更改多个图像吗?

如何将django url参数传递给模板&S url方法?

为什么在安装了64位Python的64位Windows 10上以32位运行?