From 7af1295754c449a8e2c9db49aa2d8f627ba4b72f Mon Sep 17 00:00:00 2001 From: RuKira Date: Sat, 4 Apr 2026 17:06:35 -0400 Subject: [PATCH] Updatedededed...? Still needs testing. --- RelayServer/Endpoints/RtcEndpoints.cs | 8 +- .../Services/Chat/ChatSocketBehavior.cs | 77 +++++++++++++++++++ .../Services/Rtc/RtcChannelPresenceService.cs | 55 +++++++++++++ .../Services/Rtc/RtcNotificationService.cs | 13 +++- 4 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 RelayServer/Services/Rtc/RtcChannelPresenceService.cs diff --git a/RelayServer/Endpoints/RtcEndpoints.cs b/RelayServer/Endpoints/RtcEndpoints.cs index 0d2b5ec..29dba1d 100644 --- a/RelayServer/Endpoints/RtcEndpoints.cs +++ b/RelayServer/Endpoints/RtcEndpoints.cs @@ -17,7 +17,7 @@ public static class RtcEndpoints { await rtcCallService.WriteOfferAsync(request.ChannelId, request.Username, request.SessionDescription); - RtcNotificationService.Broadcast(new RtcNotificationMessage + RtcNotificationService.BroadcastToChannel(new RtcNotificationMessage { Type = "rtc_offer_updated", ChannelId = request.ChannelId, @@ -59,7 +59,7 @@ public static class RtcEndpoints // Sdp = request.Sdp // }); - RtcNotificationService.Broadcast(new RtcNotificationMessage + RtcNotificationService.BroadcastToChannel(new RtcNotificationMessage { Type = "rtc_answer_updated", ChannelId = request.ChannelId @@ -93,7 +93,7 @@ public static class RtcEndpoints request.Direction ); - RtcNotificationService.Broadcast(new RtcNotificationMessage + RtcNotificationService.BroadcastToChannel(new RtcNotificationMessage { Type = "rtc_candidate_added", ChannelId = request.ChannelId, @@ -126,7 +126,7 @@ public static class RtcEndpoints { await rtcCallService.LeaveCallAsync(request.ChannelId, request.Username); - RtcNotificationService.Broadcast(new RtcNotificationMessage + RtcNotificationService.BroadcastToChannel(new RtcNotificationMessage { Type = "rtc_call_left", ChannelId = request.ChannelId, diff --git a/RelayServer/Services/Chat/ChatSocketBehavior.cs b/RelayServer/Services/Chat/ChatSocketBehavior.cs index 3d9bfa5..f90afae 100644 --- a/RelayServer/Services/Chat/ChatSocketBehavior.cs +++ b/RelayServer/Services/Chat/ChatSocketBehavior.cs @@ -2,6 +2,7 @@ using RelayServer.Models; using RelayServer.Services.Crypto; using RelayServer.Services.Data; +using RelayServer.Services.Rtc; using WebSocketSharp; using WebSocketSharp.Server; @@ -53,9 +54,31 @@ public class ChatSocketBehavior : WebSocketBehavior HandleGetHistory(msg); return; } + + if (msg.StartsWith("RTC_JOIN_CHANNEL|")) + { + HandleRtcJoinChannel(msg); + return; + } + + if (msg.StartsWith("RTC_LEAVE_CHANNEL|")) + { + HandleRtcLeaveChannel(msg); + return; + } HandleEncryptedChatMessage(msg); } + + /// + /// + /// + /// + protected override void OnClose(CloseEventArgs e) + { + RtcChannelPresenceService.RemoveSession(ID); + base.OnClose(e); + } /// /// Extracts a display username from a stored user record id value. @@ -419,6 +442,10 @@ public class ChatSocketBehavior : WebSocketBehavior .GetResult(); } + /// + /// + /// + /// private bool EnsureCoreReady() { if (ClientKeyService is null || Db is null) @@ -430,6 +457,10 @@ public class ChatSocketBehavior : WebSocketBehavior return true; } + /// + /// + /// + /// private bool EnsureCryptoReady() { if (string.IsNullOrWhiteSpace(ServerPrivateKey) || string.IsNullOrWhiteSpace(ChannelDbKey)) @@ -446,4 +477,50 @@ public class ChatSocketBehavior : WebSocketBehavior return true; } + + /// + /// + /// + /// + private void HandleRtcJoinChannel(string msg) + { + var parts = msg.Split('|', 3); + if (parts.Length < 3) + { + Console.WriteLine("Invalid RTC_JOIN_CHANNEL payload."); + return; + } + + var username = parts[1]; + var channelId = parts[2]; + + RtcChannelPresenceService.SetUser(ID, username); + RtcChannelPresenceService.JoinChannel(ID, channelId); + + Console.WriteLine($"RTC presence joined: session={ID}, user={username}, channel={channelId}"); + } + + /// + /// + /// + /// + private void HandleRtcLeaveChannel(string msg) + { + var parts = msg.Split('|', 3); + if (parts.Length < 3) + { + Console.WriteLine("Invalid RTC_LEAVE_CHANNEL payload."); + return; + } + + var username = parts[1]; + var channelId = parts[2]; + + if (RtcChannelPresenceService.IsInChannel(ID, channelId)) + { + RtcChannelPresenceService.LeaveChannel(ID); + } + + Console.WriteLine($"RTC presence left: session={ID}, user={username}, channel={channelId}"); + } } \ No newline at end of file diff --git a/RelayServer/Services/Rtc/RtcChannelPresenceService.cs b/RelayServer/Services/Rtc/RtcChannelPresenceService.cs new file mode 100644 index 0000000..581f5b7 --- /dev/null +++ b/RelayServer/Services/Rtc/RtcChannelPresenceService.cs @@ -0,0 +1,55 @@ +using System.Collections.Concurrent; + +namespace RelayServer.Services.Rtc; + +public static class RtcChannelPresenceService +{ + private static readonly ConcurrentDictionary SessionToChannel = new(); + private static readonly ConcurrentDictionary SessionToUsername = new(); + + public static void SetUser(string sessionId, string username) + { + SessionToUsername[sessionId] = username; + } + + public static void JoinChannel(string sessionId, string channelId) + { + SessionToChannel[sessionId] = channelId; + } + + public static void LeaveChannel(string sessionId) + { + SessionToChannel.TryRemove(sessionId, out _); + } + + public static void RemoveSession(string sessionId) + { + SessionToChannel.TryRemove(sessionId, out _); + SessionToUsername.TryRemove(sessionId, out _); + } + + public static IReadOnlyList GetSessionsInChannel(string channelId) + { + return SessionToChannel + .Where(x => x.Value == channelId) + .Select(x => x.Key) + .ToList(); + } + + public static IReadOnlyList GetUsersInChannel(string channelId) + { + var sessionIds = GetSessionsInChannel(channelId); + + return sessionIds + .Where(id => SessionToUsername.ContainsKey(id)) + .Select(id => SessionToUsername[id]) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + } + + public static bool IsInChannel(string sessionId, string channelId) + { + return SessionToChannel.TryGetValue(sessionId, out var currentChannel) && + string.Equals(currentChannel, channelId, StringComparison.Ordinal); + } +} \ No newline at end of file diff --git a/RelayServer/Services/Rtc/RtcNotificationService.cs b/RelayServer/Services/Rtc/RtcNotificationService.cs index 5c4f209..9968d74 100644 --- a/RelayServer/Services/Rtc/RtcNotificationService.cs +++ b/RelayServer/Services/Rtc/RtcNotificationService.cs @@ -8,12 +8,21 @@ public static class RtcNotificationService { public static WebSocketServer? Server { get; set; } - public static void Broadcast(RtcNotificationMessage message) + public static void BroadcastToChannel(RtcNotificationMessage message) { if (Server is null) return; + var host = Server.WebSocketServices["/"]; + if (host is null) + return; + var json = JsonSerializer.Serialize(message); - Server.WebSocketServices["/"]?.Sessions.Broadcast(json); + var sessionIds = RtcChannelPresenceService.GetSessionsInChannel(message.ChannelId); + + foreach (var sessionId in sessionIds) + { + host.Sessions.SendTo(json, sessionId); + } } } \ No newline at end of file