Chat room subscribe

This commit is contained in:
LittleSheep 2025-06-27 22:55:00 +08:00
parent 5dd138949e
commit 2a28948418
5 changed files with 103 additions and 0 deletions

View File

@ -252,6 +252,7 @@ public partial class ChatService(
if (member.Account.Id == sender.AccountId) continue; if (member.Account.Id == sender.AccountId) continue;
if (member.Notify == ChatMemberNotify.None) continue; if (member.Notify == ChatMemberNotify.None) continue;
if (scopedWs.IsUserSubscribedToChatRoom(member.AccountId, room.Id.ToString())) continue;
if (message.MembersMentioned is null || !message.MembersMentioned.Contains(member.Account.Id)) if (message.MembersMentioned is null || !message.MembersMentioned.Contains(member.Account.Id))
{ {
var now = SystemClock.Instance.GetCurrentInstant(); var now = SystemClock.Instance.GetCurrentInstant();

View File

@ -0,0 +1,53 @@
using System.Net.WebSockets;
using DysonNetwork.Sphere.Chat;
namespace DysonNetwork.Sphere.Connection.Handlers;
public class MessagesSubscribeHandler(ChatRoomService crs, WebSocketService webSocketService) : IWebSocketPacketHandler
{
public string PacketType => "messages.subscribe";
public async Task HandleAsync(
Account.Account currentUser,
string deviceId,
WebSocketPacket packet,
WebSocket socket,
WebSocketService srv
)
{
var request = packet.GetData<ChatController.TypingMessageRequest>();
if (request is null)
{
await socket.SendAsync(
new ArraySegment<byte>(new WebSocketPacket
{
Type = WebSocketPacketType.Error,
ErrorMessage = "messages.subscribe requires you provide the ChatRoomId"
}.ToBytes()),
WebSocketMessageType.Binary,
true,
CancellationToken.None
);
return;
}
var sender = await crs.GetRoomMember(currentUser.Id, request.ChatRoomId);
if (sender is null)
{
await socket.SendAsync(
new ArraySegment<byte>(new WebSocketPacket
{
Type = WebSocketPacketType.Error,
ErrorMessage = "User is not a member of the chat room."
}.ToBytes()),
WebSocketMessageType.Binary,
true,
CancellationToken.None
);
return;
}
webSocketService.SubscribeToChatRoom(sender.ChatRoomId.ToString(), deviceId);
}
}

View File

@ -0,0 +1,21 @@
using System.Net.WebSockets;
using DysonNetwork.Sphere.Chat;
namespace DysonNetwork.Sphere.Connection.Handlers;
public class MessagesUnsubscribeHandler(WebSocketService webSocketService) : IWebSocketPacketHandler
{
public string PacketType => "messages.unsubscribe";
public Task HandleAsync(
Account.Account currentUser,
string deviceId,
WebSocketPacket packet,
WebSocket socket,
WebSocketService srv
)
{
webSocketService.UnsubscribeFromChatRoom(deviceId);
return Task.CompletedTask;
}
}

View File

@ -17,6 +17,31 @@ public class WebSocketService
(WebSocket Socket, CancellationTokenSource Cts) (WebSocket Socket, CancellationTokenSource Cts)
> ActiveConnections = new(); > ActiveConnections = new();
private static readonly ConcurrentDictionary<string, string> ActiveSubscriptions = new(); // deviceId -> chatRoomId
public void SubscribeToChatRoom(string chatRoomId, string deviceId)
{
ActiveSubscriptions[deviceId] = chatRoomId;
}
public void UnsubscribeFromChatRoom(string deviceId)
{
ActiveSubscriptions.TryRemove(deviceId, out _);
}
public bool IsUserSubscribedToChatRoom(Guid accountId, string chatRoomId)
{
var userDeviceIds = ActiveConnections.Keys.Where(k => k.AccountId == accountId).Select(k => k.DeviceId);
foreach (var deviceId in userDeviceIds)
{
if (ActiveSubscriptions.TryGetValue(deviceId, out var subscribedChatRoomId) && subscribedChatRoomId == chatRoomId)
{
return true;
}
}
return false;
}
public bool TryAdd( public bool TryAdd(
(Guid AccountId, string DeviceId) key, (Guid AccountId, string DeviceId) key,
WebSocket socket, WebSocket socket,
@ -39,6 +64,7 @@ public class WebSocketService
); );
data.Cts.Cancel(); data.Cts.Cancel();
ActiveConnections.TryRemove(key, out _); ActiveConnections.TryRemove(key, out _);
UnsubscribeFromChatRoom(key.DeviceId);
} }
public bool GetAccountIsConnected(Guid accountId) public bool GetAccountIsConnected(Guid accountId)

View File

@ -187,6 +187,8 @@ public static class ServiceCollectionExtensions
// The handlers for websocket // The handlers for websocket
services.AddScoped<IWebSocketPacketHandler, MessageReadHandler>(); services.AddScoped<IWebSocketPacketHandler, MessageReadHandler>();
services.AddScoped<IWebSocketPacketHandler, MessageTypingHandler>(); services.AddScoped<IWebSocketPacketHandler, MessageTypingHandler>();
services.AddScoped<IWebSocketPacketHandler, MessagesSubscribeHandler>();
services.AddScoped<IWebSocketPacketHandler, MessagesUnsubscribeHandler>();
return services; return services;
} }