Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript&;Django频道:窗口关闭时聊天应用程序注销通知_Javascript_Python_Django_Chat_Django Channels - Fatal编程技术网

Javascript&;Django频道:窗口关闭时聊天应用程序注销通知

Javascript&;Django频道:窗口关闭时聊天应用程序注销通知,javascript,python,django,chat,django-channels,Javascript,Python,Django,Chat,Django Channels,我正在编写一个带有Javascript和Django频道的聊天应用程序。我正在尝试获取“用户已离开聊天室”消息,以便在窗口关闭时发送,也可能在websocket关闭时发送。我不确定websocket是否关闭得太快,但我目前拥有的代码不起作用。我可能应该在聊天消费者的disconnect函数中定义。我不确定这些东西的处理顺序 Javascript // Declare variables var userName; var currentZone = new Date().toTi

我正在编写一个带有Javascript和Django频道的聊天应用程序。我正在尝试获取“用户已离开聊天室”消息,以便在窗口关闭时发送,也可能在websocket关闭时发送。我不确定websocket是否关闭得太快,但我目前拥有的代码不起作用。我可能应该在聊天消费者的disconnect函数中定义。我不确定这些东西的处理顺序

Javascript

// Declare variables
    var userName;
    var currentZone = new Date().toTimeString().slice(17);
    // var roomName = {{ room_name_json }};
    document.getElementById("chatname").innerHTML = roomName;

// Create Websocket
    var chatSocket = new ReconnectingWebSocket(
        'ws://' + window.location.host +
        '/ws/chat/' + roomName + '/');

// Send message
    chatSocket.onmessage = function(e) {
        var data = JSON.parse(e.data);
        var message = data['message'];
        document.querySelector('#chat-log').value += (message + '\n');
        document.getElementById("chat-log").scrollTop = document.getElementById("chat-log").scrollHeight;
    };

// Set User
    window.onload = function(){
        userName = sessionStorage.getItem("user");
        if (userName==null || userName===false) {
            userName = prompt("Please enter a username:");
        };
        return userName;
    }

//Join message
    function chatJoin() {
        if(chatSocket.readyState == false) {
           window.setTimeout(chatJoin, 500); /* Wait 500 milliseconds*/
        } else {
            var message = userName + " has joined the chat."
            chatSocket.send(JSON.stringify({
                'message': message
            }));
        }
    }
    chatJoin();

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

// Sign off message
    window.unload = function(e) {
        var message = userName +"has left the chat."
        chatSocket.send(JSON.stringify({
            'message': message
        }));
    };

    document.querySelector('#chat-message-input').focus();
    document.querySelector('#chat-message-input').onkeyup = function(e) {
        if (e.keyCode === 13) {  // enter, return
            document.querySelector('#chat-message-submit').click();
        }
    };

    document.querySelector('#chat-message-submit').onclick = function(e) {
        var currentDate = new Date();
        var currentTime = currentDate.toLocaleTimeString();
        var messageInputDom = document.querySelector('#chat-message-input');
        var message = userName + " " + currentTime + currentZone + ': ' + messageInputDom.value;
        chatSocket.send(JSON.stringify({
            'message': message
        }));

        messageInputDom.value = '';
    };
消费者

from channels.generic.websocket import AsyncWebsocketConsumer
from channels.generic.websocket import WebsocketConsumer

import json

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 group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

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

    # Receive message from WebSocket
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

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

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

        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))
我也尝试过这样的断开连接功能,我希望在消息中包含用户名,以便它需要接收一些数据:

    async def disconnect(self, text_data, close_code):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

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

        # Leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )
与其从断开连接的客户端发送“用户已断开连接”消息,不如让服务器来执行


因此,在断开连接时,在放弃通话组之前,发送XXX已离开聊天室。消息。

这是我考虑的方法。您知道如何将数据传递到断开连接功能吗?似乎断开功能无法接收数据?我将在问题中重新添加我所累的内容的细节,当我注意到disconnect不接受text_数据参数的问题时,我将其删除。您不需要更改disconnect函数的签名,因为它是一个您不调用自己的钩子。每个使用者连接都在作用域中存储了上下文信息。如果您使用的是文档中使用的身份验证方法,那么您可以从self.scop['user']获取用户,然后从该用户获取用户名。您可以将任何其他上下文信息存储在connect中的作用域a中,并使其可供其他方法访问。我没有使用身份验证,因为我试图在没有后端的情况下构建项目。userName变量是一个使用JavaScript设置的变量,存储在会话中。我发现,设置一个类似于self.user_名称的变量在全局范围内起作用,使其可用于断开连接功能。你知道我可以通过websocket发送JavaScript变量的方法吗?我尝试了使用.send()以JSON的形式发送它。在当前receive()函数中,将self.user_name设置为text_data_json['message']的测试未成功。我需要一种获取var的方法,但不需要发送它。我看到了这个问题,因为消费者是后端代码,他们不是孤立于用户的,传递用户var只会保留最近加入的用户。您对实现身份验证的简单方法有何建议?我唯一希望保留的是用户名和适当的会话。有没有办法在不实现数据库的情况下在python代码中缓存这些信息?这里的文档展示了如何使用内置会话身份验证。对于使用者,每个实例都用于单独的连接,因此您可以在使用者对象中存储特定用户的值。这就是自我范围的本质。就像普通的django视图一样,它有request.user。您还可以在启动websocket连接时将用户名作为查询字符串传递。可以在self.scope中访问该值。您可以针对该值发布一个单独的问题,并提供更多详细信息