Message subscribe

This commit is contained in:
2025-09-27 17:50:51 +08:00
parent 78f8a9e638
commit 1075177511
3 changed files with 95 additions and 3 deletions

View File

@@ -162,4 +162,25 @@ public class ChatRoomService(
return m; return m;
})]; })];
} }
}
private const string ChatRoomSubscribeKeyPrefix = "chatroom:subscribe:";
public async Task SubscribeChatRoom(SnChatMember member)
{
var cacheKey = ChatRoomSubscribeKeyPrefix + member.Id;
await cache.SetAsync(cacheKey, true, TimeSpan.FromHours(1));
}
public async Task UnsubscribeChatRoom(SnChatMember member)
{
var cacheKey = ChatRoomSubscribeKeyPrefix + member.Id;
await cache.RemoveAsync(cacheKey);
}
public async Task<bool> IsSubscribedChatRoom(Guid memberId)
{
var cacheKey = ChatRoomSubscribeKeyPrefix + memberId;
var result = await cache.GetAsync<bool?>(cacheKey);
return result ?? false;
}
}

View File

@@ -280,7 +280,16 @@ public partial class ChatService(
var accountsToNotify = FilterAccountsForNotification(members, message, sender); var accountsToNotify = FilterAccountsForNotification(members, message, sender);
logger.LogInformation($"Trying to deliver message to {accountsToNotify.Count} accounts..."); // Filter out subscribed users from push notifications
var subscribedMemberIds = new List<Guid>();
foreach (var member in members)
{
if (await scopedCrs.IsSubscribedChatRoom(member.Id))
subscribedMemberIds.Add(member.AccountId);
}
accountsToNotify = accountsToNotify.Where(a => !subscribedMemberIds.Contains(Guid.Parse(a.Id))).ToList();
logger.LogInformation("Trying to deliver message to {count} accounts...", accountsToNotify.Count);
if (accountsToNotify.Count > 0) if (accountsToNotify.Count > 0)
{ {
@@ -289,7 +298,7 @@ public partial class ChatService(
await scopedNty.SendPushNotificationToUsersAsync(ntyRequest); await scopedNty.SendPushNotificationToUsersAsync(ntyRequest);
} }
logger.LogInformation($"Delivered message to {accountsToNotify.Count} accounts."); logger.LogInformation("Delivered message to {count} accounts.", accountsToNotify.Count);
} }
private PushNotification BuildNotification(SnChatMessage message, SnChatMember sender, SnChatRoom room, string roomSubject, private PushNotification BuildNotification(SnChatMessage message, SnChatMember sender, SnChatRoom room, string roomSubject,

View File

@@ -192,6 +192,12 @@ public class BroadcastEventHandler(
case "messages.typing": case "messages.typing":
await HandleMessageTyping(evt, packet); await HandleMessageTyping(evt, packet);
break; break;
case "messages.subscribe":
await HandleMessageSubscribe(evt, packet);
break;
case "messages.unsubscribe":
await HandleMessageUnsubscribe(evt, packet);
break;
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -278,6 +284,62 @@ public class BroadcastEventHandler(
await pusher.PushWebSocketPacketToUsersAsync(respRequest); await pusher.PushWebSocketPacketToUsersAsync(respRequest);
} }
private async Task HandleMessageSubscribe(WebSocketPacketEvent evt, WebSocketPacket packet)
{
using var scope = serviceProvider.CreateScope();
var crs = scope.ServiceProvider.GetRequiredService<ChatRoomService>();
if (packet.Data == null)
{
await SendErrorResponse(evt, "messages.subscribe requires you to provide the ChatRoomId");
return;
}
var requestData = packet.GetData<ChatController.ChatRoomWsUniversalRequest>();
if (requestData == null)
{
await SendErrorResponse(evt, "Invalid request data");
return;
}
var sender = await crs.GetRoomMember(evt.AccountId, requestData.ChatRoomId);
if (sender == null)
{
await SendErrorResponse(evt, "User is not a member of the chat room.");
return;
}
await crs.SubscribeChatRoom(sender);
}
private async Task HandleMessageUnsubscribe(WebSocketPacketEvent evt, WebSocketPacket packet)
{
using var scope = serviceProvider.CreateScope();
var crs = scope.ServiceProvider.GetRequiredService<ChatRoomService>();
if (packet.Data == null)
{
await SendErrorResponse(evt, "messages.unsubscribe requires you to provide the ChatRoomId");
return;
}
var requestData = packet.GetData<ChatController.ChatRoomWsUniversalRequest>();
if (requestData == null)
{
await SendErrorResponse(evt, "Invalid request data");
return;
}
var sender = await crs.GetRoomMember(evt.AccountId, requestData.ChatRoomId);
if (sender == null)
{
await SendErrorResponse(evt, "User is not a member of the chat room.");
return;
}
await crs.UnsubscribeChatRoom(sender);
}
private async Task SendErrorResponse(WebSocketPacketEvent evt, string message) private async Task SendErrorResponse(WebSocketPacketEvent evt, string message)
{ {
await pusher.PushWebSocketPacketToDeviceAsync(new PushWebSocketPacketToDeviceRequest await pusher.PushWebSocketPacketToDeviceAsync(new PushWebSocketPacketToDeviceRequest