我有 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
}))
如何确认消息是否到达连接的客户端:
检查每个客户端是否正在接收消息的一种方法是实现确认系统。当客户端在
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) 来检索连接的客户端数量。