如何获取websocket async_to_sync调用的日志和结果

问题描述 投票:0回答:1

我有 websocket,只需将消息发送到

channel_layer

from channels.layers import get_channel_layer
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        '{}'.format(mychannelname),
        {
            "type": "chat_message",
            "message": "send you"
        }
    )

看起来效果很好,消息会发送到客户端浏览器, 但是我想知道它是否可以从服务器正常工作。

是否有可能或者我可以获得连接到通道的客户端数量?

我的consumers.py创建渠道

import json

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


class ChatConsumer(AsyncWebsocketConsumer):
    
    async def connect(self):

        self.room_group_name = self.scope["url_route"]["kwargs"]["room_name"]

        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()
        await self.send(text_data=json.dumps({
            'channel_name': self.channel_name
        }))
    async def disconnect(self, close_code):
        print("some disconnect")
        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']
        print("receive data",text_data_json)
    
        print("channel_name:",self.channel_name)
        print("group_name:",self.room_group_name)
        if text_data_json['type'] == "register":
            self.user_id = text_data_json['message']
        print("user_id is:",self.user_name)

        #res = await self.save_message_to_db(message)
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': "nicelydone",
            }
        )

    async def chat_message(self, event):
        print("someone call chat_message")
        message = event['message']
        await self.send(text_data=json.dumps({
            'message': message
        }))
javascript python django websocket
1个回答
0
投票

如何确认消息是否到达连接的客户端:
检查每个客户端是否正在接收消息的一种方法是实现确认系统。当客户端在

chat_message
方法中收到消息时,您可以让客户端向服务器发送回确认消息。

以下是如何做到这一点的示例:

socket.onmessage = function(event) {
    const data = JSON.parse(event.data);
    console.log("Received message:", data.message);

    // Send acknowledgment back to the server
    socket.send(JSON.stringify({
        'type': 'acknowledgment',
        'message': 'Message received'
    }));
};

然后,在服务器上,您可以在

receive
方法中处理此确认以确认交付:

async def receive(self, text_data):
    text_data_json = json.loads(text_data)
    message_type = text_data_json.get('type')

    if message_type == "acknowledgment":
        print(f"Acknowledgment received from {self.channel_name}")

    # Continue with the rest of your logic here...

这样,每次客户端收到消息时,他们都会发回一个确认,您可以在服务器上记录或跟踪该确认。

如何获取通道组内连接的客户端数量:
Django Channels 不直接提供内置方法来获取组中客户端的数量。但是,您可以通过维护活动连接计数来手动跟踪这一点。例如:

  • 调用
    connect
    时增加计数器。
  • 调用
    disconnect
    时减少计数器。

您可以使用 Redis 等缓存来存储和检索此计数,该计数将在不同的工作进程中持续存在。

以下是实现此方法的方法:

from asgiref.sync import async_to_sync
from django.core.cache import cache

class ChatConsumer(AsyncWebsocketConsumer):

    async def connect(self):
        self.room_group_name = self.scope["url_route"]["kwargs"]["room_name"]

        # Increment connected client count
        await self.update_client_count(1)
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)
        await self.accept()

    async def disconnect(self, close_code):
        # Decrement connected client count
        await self.update_client_count(-1)
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

    @database_sync_to_async
    def update_client_count(self, delta):
        current_count = cache.get(self.room_group_name, 0)
        new_count = current_count + delta
        cache.set(self.room_group_name, new_count)
        print(f"Current clients in {self.room_group_name}: {new_count}")

这里,缓存可以设置为使用Redis或Memcached,允许您将room_group_name存储为key,将count存储为value。

这样,update_client_count 将跟踪频道组中当前的活动连接,并且您可以在需要时通过调用cache.get(room_group_name) 来检索连接的客户端数量。

© www.soinside.com 2019 - 2024. All rights reserved.