Pusher service basis

This commit is contained in:
2025-07-12 22:15:18 +08:00
parent 33f56c4ef5
commit e1b47bc7d1
22 changed files with 1117 additions and 104 deletions

View File

@@ -1,9 +1,17 @@
using System.Net.WebSockets;
using DysonNetwork.Shared.Proto;
namespace DysonNetwork.Pusher.Connection;
public interface IWebSocketPacketHandler
{
string PacketType { get; }
Task HandleAsync(Account currentUser, string deviceId, WebSocketPacket packet, WebSocket socket, WebSocketService srv);
Task HandleAsync(
Account currentUser,
string deviceId,
WebSocketPacket packet,
WebSocket socket,
WebSocketService srv
);
}

View File

@@ -1,8 +1,7 @@
using System.Collections.Concurrent;
using System.Net.WebSockets;
using DysonNetwork.Shared.Proto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Swashbuckle.AspNetCore.Annotations;
namespace DysonNetwork.Pusher.Connection;
@@ -18,15 +17,15 @@ public class WebSocketController(WebSocketService ws, ILogger<WebSocketContext>
{
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
HttpContext.Items.TryGetValue("CurrentSession", out var currentSessionValue);
if (currentUserValue is not Account.Account currentUser ||
currentSessionValue is not Auth.Session currentSession)
if (currentUserValue is not Account currentUser ||
currentSessionValue is not AuthSession currentSession)
{
HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
}
var accountId = currentUser.Id;
var deviceId = currentSession.Challenge.DeviceId;
var accountId = currentUser.Id!;
var deviceId = currentSession.Challenge.DeviceId!;
if (string.IsNullOrEmpty(deviceId))
{
@@ -69,7 +68,7 @@ public class WebSocketController(WebSocketService ws, ILogger<WebSocketContext>
private async Task _ConnectionEventLoop(
string deviceId,
Account.Account currentUser,
Account currentUser,
WebSocket webSocket,
CancellationToken cancellationToken
)

View File

@@ -2,7 +2,9 @@ using System.Text.Json;
using NodaTime;
using NodaTime.Serialization.SystemTextJson;
public class WebSocketPacketType
namespace DysonNetwork.Pusher.Connection;
public abstract class WebSocketPacketType
{
public const string Error = "error";
public const string MessageNew = "messages.new";
@@ -31,7 +33,7 @@ public class WebSocketPacket
DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower,
};
return JsonSerializer.Deserialize<WebSocketPacket>(json, jsonOpts) ??
throw new JsonException("Failed to deserialize WebSocketPacket");
throw new JsonException("Failed to deserialize WebSocketPacket");
}
/// <summary>

View File

@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Net.WebSockets;
using DysonNetwork.Shared.Proto;
namespace DysonNetwork.Pusher.Connection;
@@ -13,7 +14,7 @@ public class WebSocketService
}
private static readonly ConcurrentDictionary<
(Guid AccountId, string DeviceId),
(string AccountId, string DeviceId),
(WebSocket Socket, CancellationTokenSource Cts)
> ActiveConnections = new();
@@ -29,21 +30,23 @@ public class WebSocketService
ActiveSubscriptions.TryRemove(deviceId, out _);
}
public bool IsUserSubscribedToChatRoom(Guid accountId, string chatRoomId)
public bool IsUserSubscribedToChatRoom(string 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)
if (ActiveSubscriptions.TryGetValue(deviceId, out var subscribedChatRoomId) &&
subscribedChatRoomId == chatRoomId)
{
return true;
}
}
return false;
}
public bool TryAdd(
(Guid AccountId, string DeviceId) key,
(string AccountId, string DeviceId) key,
WebSocket socket,
CancellationTokenSource cts
)
@@ -54,7 +57,7 @@ public class WebSocketService
return ActiveConnections.TryAdd(key, (socket, cts));
}
public void Disconnect((Guid AccountId, string DeviceId) key, string? reason = null)
public void Disconnect((string AccountId, string DeviceId) key, string? reason = null)
{
if (!ActiveConnections.TryGetValue(key, out var data)) return;
data.Socket.CloseAsync(
@@ -67,12 +70,12 @@ public class WebSocketService
UnsubscribeFromChatRoom(key.DeviceId);
}
public bool GetAccountIsConnected(Guid accountId)
public bool GetAccountIsConnected(string accountId)
{
return ActiveConnections.Any(c => c.Key.AccountId == accountId);
}
public void SendPacketToAccount(Guid userId, WebSocketPacket packet)
public void SendPacketToAccount(string userId, WebSocketPacket packet)
{
var connections = ActiveConnections.Where(c => c.Key.AccountId == userId);
var packetBytes = packet.ToBytes();
@@ -106,8 +109,12 @@ public class WebSocketService
}
}
public async Task HandlePacket(Account.Account currentUser, string deviceId, WebSocketPacket packet,
WebSocket socket)
public async Task HandlePacket(
Account currentUser,
string deviceId,
WebSocketPacket packet,
WebSocket socket
)
{
if (_handlerMap.TryGetValue(packet.Type, out var handler))
{