websocket Django channels:当两个或多个标签打开时,保存消息到数据库中

qzlgjiam  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(104)

我使用此解决方案将消息保存到DB Django channels: Save messages to database
但我有一个重复的问题(在数据库中),当用户(消息的作者)有两个或更多的标签在浏览器中打开同一个聊天室。
怎么了?救命啊!

import json

from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncWebsocketConsumer

from .models import Message

class ChatConsumer(AsyncWebsocketConsumer):
    @database_sync_to_async
    def create_chat(self, msg, sender):
        return Message.objects.create(sender=sender, msg=msg)

    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)
        await self.accept()

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

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        sender = text_data_json['sender']
        await self.channel_layer.group_send(self.room_group_name, {
            'type': 'chat_message',
            'message': message,
            'sender': sender
        })

    async def chat_message(self, event):
        message = event['message']
        sender = event['sender']
        new_msg = await self.create_chat(sender, message)  # It is necessary to await creation of messages
        await self.send(text_data=json.dumps({
            'message': new_msg.message,
            'sender': new_msg.sender
        }))

字符串

92vpleto

92vpleto1#

解决方案在这里,不要从发送消息到WebSocket(到每个打开的连接/打开的浏览器的标签)的函数中调用create_chat(将数据放入数据库)。只需从receive函数中调用它。

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

    @sync_to_async
    def get_user(sender):
        return User.objects.get(username=sender)
    
    @sync_to_async
    def get_case(case):
        return Case.objects.get(id=case)
    
    user_obj = await get_user(sender)
    case_obj = await get_case(case)

    new_msg = await self.create_chat(user_obj, message, case_obj, chat_type)

    # Send message to room group
    await self.channel_layer.group_send(
        self.room_group_name, {
            'type': 'chat_message',
            'message': message,
            'username': sender,
            'case':case,
            'chat_type':chat_type,
            'time': new_msg.creted_time,
        }
    )

字符串

相关问题