sharp-chat/SharpChatCommon/ConnectionsContext.cs

177 lines
5.6 KiB
C#
Raw Normal View History

2024-05-20 16:16:32 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
namespace SharpChat.SockChat {
2024-05-21 20:08:23 +00:00
public class ConnectionsContext {
2024-05-20 16:16:32 +00:00
public static readonly TimeSpan TimeOut = TimeSpan.FromMinutes(5);
2024-05-21 20:08:23 +00:00
private readonly HashSet<ConnectionInfo> Connections = new();
private readonly HashSet<ConnectionInfo> AuthedConnections = new();
private readonly Dictionary<long, HashSet<ConnectionInfo>> UserConnections = new();
2024-05-20 16:16:32 +00:00
2024-05-21 20:08:23 +00:00
public ConnectionInfo[] All => Connections.ToArray();
public ConnectionInfo[] Authed => AuthedConnections.ToArray();
2024-05-20 16:16:32 +00:00
2024-05-21 20:08:23 +00:00
public void WithAll(Action<ConnectionInfo> body) {
foreach(ConnectionInfo conn in Connections)
2024-05-20 16:16:32 +00:00
body(conn);
}
2024-05-21 20:08:23 +00:00
public void WithAuthed(Action<ConnectionInfo> body) {
foreach(ConnectionInfo conn in AuthedConnections)
2024-05-20 16:16:32 +00:00
body(conn);
}
2024-05-21 20:08:23 +00:00
public ConnectionInfo[] GetTimedOut() {
List<ConnectionInfo> conns = new();
2024-05-20 16:16:32 +00:00
2024-05-21 20:08:23 +00:00
foreach(ConnectionInfo conn in Connections)
2024-05-20 16:16:32 +00:00
if(DateTimeOffset.UtcNow - conn.LastPing > TimeOut)
conns.Add(conn);
return conns.ToArray();
}
public int GetCountForUser(long userId) {
return UserConnections.ContainsKey(userId) ? UserConnections.Count : 0;
}
public int GetCountForUser(UserInfo userInfo) {
return GetCountForUser(userInfo.UserId);
}
public bool HasUser(long userId) {
return GetCountForUser(userId) > 0;
}
public bool HasUser(UserInfo userInfo) {
return HasUser(userInfo.UserId);
}
2024-05-21 20:08:23 +00:00
public ConnectionInfo[] GetUser(long userId) {
2024-05-20 16:16:32 +00:00
if(!UserConnections.ContainsKey(userId))
2024-05-21 20:08:23 +00:00
return Array.Empty<ConnectionInfo>();
2024-05-20 16:16:32 +00:00
return UserConnections[userId].ToArray();
}
2024-05-21 20:08:23 +00:00
public ConnectionInfo[] GetUser(UserInfo userInfo) {
2024-05-20 16:16:32 +00:00
return GetUser(userInfo.UserId);
}
2024-05-21 20:08:23 +00:00
public void WithUser(long userId, Action<ConnectionInfo> body) {
2024-05-20 16:16:32 +00:00
if(!UserConnections.ContainsKey(userId))
return;
2024-05-21 20:08:23 +00:00
foreach(ConnectionInfo conn in UserConnections[userId])
2024-05-20 16:16:32 +00:00
body(conn);
}
2024-05-21 20:08:23 +00:00
public void WithUser(UserInfo userInfo, Action<ConnectionInfo> body) {
2024-05-20 16:16:32 +00:00
WithUser(userInfo.UserId, body);
}
public string[] GetAllRemoteAddresses() {
HashSet<string> addrs = new();
2024-05-21 20:08:23 +00:00
foreach(ConnectionInfo conn in Connections)
2024-05-20 16:16:32 +00:00
addrs.Add(conn.RemoteAddress);
return addrs.ToArray();
}
public string[] GetAuthedRemoteAddresses() {
HashSet<string> addrs = new();
2024-05-21 20:08:23 +00:00
foreach(ConnectionInfo conn in AuthedConnections)
2024-05-20 16:16:32 +00:00
addrs.Add(conn.RemoteAddress);
return addrs.ToArray();
}
public string[] GetUserRemoteAddresses(long userId) {
if(!UserConnections.ContainsKey(userId))
return Array.Empty<string>();
HashSet<string> addrs = new();
2024-05-21 20:08:23 +00:00
foreach(ConnectionInfo conn in UserConnections[userId])
2024-05-20 16:16:32 +00:00
addrs.Add(conn.RemoteAddress);
return addrs.ToArray();
}
public string[] GetUserRemoteAddresses(UserInfo userInfo) {
return GetUserRemoteAddresses(userInfo.UserId);
}
2024-05-21 20:08:23 +00:00
public void Add(ConnectionInfo conn) {
2024-05-20 16:16:32 +00:00
if(Connections.Contains(conn))
return;
Connections.Add(conn);
if(conn.UserId > 0) {
AuthedConnections.Add(conn);
if(UserConnections.ContainsKey(conn.UserId))
UserConnections[conn.UserId].Add(conn);
else
UserConnections.Add(conn.UserId, new() { conn });
}
}
2024-05-21 20:08:23 +00:00
public void Remove(ConnectionInfo conn) {
2024-05-20 16:16:32 +00:00
if(Connections.Contains(conn))
Connections.Remove(conn);
if(AuthedConnections.Contains(conn))
AuthedConnections.Remove(conn);
if(conn.UserId > 0 && UserConnections.ContainsKey(conn.UserId)) {
UserConnections[conn.UserId].Remove(conn);
if(UserConnections[conn.UserId].Count < 1)
UserConnections.Remove(conn.UserId);
}
}
2024-05-21 20:08:23 +00:00
public void SetUser(ConnectionInfo conn, long userId) {
2024-05-20 16:16:32 +00:00
if(!Connections.Contains(conn))
return;
// so yeah this is implemented but SetUserId will throw an exception if we're trying to re-auth a connection
// will just leave this here but i'm not sure how to go forward with this
if(conn.UserId > 0) {
if(UserConnections[conn.UserId].Contains(conn))
UserConnections[conn.UserId].Remove(conn);
if(UserConnections[conn.UserId].Count < 1)
UserConnections.Remove(conn.UserId);
}
conn.SetUserId(userId);
if(conn.UserId > 0) {
if(UserConnections.ContainsKey(conn.UserId))
UserConnections[conn.UserId].Add(conn);
else
UserConnections.Add(conn.UserId, new() { conn });
}
if(conn.UserId > 0) {
if(!AuthedConnections.Contains(conn))
AuthedConnections.Add(conn);
} else {
if(AuthedConnections.Contains(conn))
AuthedConnections.Remove(conn);
}
}
2024-05-21 20:08:23 +00:00
public void SetUser(ConnectionInfo conn, UserInfo userInfo) {
2024-05-20 16:16:32 +00:00
SetUser(conn, userInfo.UserId);
}
}
}