Updatedededed...? Still needs testing.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using RelayServer.Models;
|
||||
using RelayServer.Services.Crypto;
|
||||
using RelayServer.Services.Data;
|
||||
using RelayServer.Services.Rtc;
|
||||
using WebSocketSharp;
|
||||
using WebSocketSharp.Server;
|
||||
|
||||
@@ -54,9 +55,31 @@ public class ChatSocketBehavior : WebSocketBehavior
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.StartsWith("RTC_JOIN_CHANNEL|"))
|
||||
{
|
||||
HandleRtcJoinChannel(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.StartsWith("RTC_LEAVE_CHANNEL|"))
|
||||
{
|
||||
HandleRtcLeaveChannel(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
HandleEncryptedChatMessage(msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected override void OnClose(CloseEventArgs e)
|
||||
{
|
||||
RtcChannelPresenceService.RemoveSession(ID);
|
||||
base.OnClose(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts a display username from a stored user record id value.
|
||||
/// </summary>
|
||||
@@ -419,6 +442,10 @@ public class ChatSocketBehavior : WebSocketBehavior
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool EnsureCoreReady()
|
||||
{
|
||||
if (ClientKeyService is null || Db is null)
|
||||
@@ -430,6 +457,10 @@ public class ChatSocketBehavior : WebSocketBehavior
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool EnsureCryptoReady()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ServerPrivateKey) || string.IsNullOrWhiteSpace(ChannelDbKey))
|
||||
@@ -446,4 +477,50 @@ public class ChatSocketBehavior : WebSocketBehavior
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
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}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
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}");
|
||||
}
|
||||
}
|
||||
55
RelayServer/Services/Rtc/RtcChannelPresenceService.cs
Normal file
55
RelayServer/Services/Rtc/RtcChannelPresenceService.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace RelayServer.Services.Rtc;
|
||||
|
||||
public static class RtcChannelPresenceService
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, string> SessionToChannel = new();
|
||||
private static readonly ConcurrentDictionary<string, string> 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<string> GetSessionsInChannel(string channelId)
|
||||
{
|
||||
return SessionToChannel
|
||||
.Where(x => x.Value == channelId)
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static IReadOnlyList<string> 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user