LumaTunnel
【WinUI】LumaTunnel 是一个面向个人多设备的 Windows 代理系统。客户端在本机提供 HTTP/HTTPS CONNECT 与 SOCKS5 TCP 代理,并通过一个受信任 TLS 证书保护的 WSS 会话,将多个 TCP 流复用到自建 Windows Server 节点。
关注
0
Fork
0
Star
0
using System.Collections.Concurrent;
using LumaTunnel.Server.Core.Persistence;
namespace LumaTunnel.Server.Core.Runtime;
public sealed class TrafficCounters
{
private readonly ConcurrentDictionary<string, DeviceTrafficCounter> _devices = new(StringComparer.Ordinal);
private long _activeConnections;
public TrafficCounters(IEnumerable<TrafficRecord>? initial = null)
{
if (initial is null) return;
foreach (var record in initial)
_devices[record.DeviceId] = new DeviceTrafficCounter(record.UploadBytes, record.DownloadBytes);
}
public int ActiveConnections => checked((int)Interlocked.Read(ref _activeConnections));
public DeviceTrafficCounter GetDevice(string deviceId) => _devices.GetOrAdd(deviceId, static _ => new DeviceTrafficCounter());
public void ConnectionOpened(string deviceId)
{
Interlocked.Increment(ref _activeConnections);
GetDevice(deviceId).ConnectionOpened();
}
public void ConnectionClosed(string deviceId)
{
Interlocked.Decrement(ref _activeConnections);
GetDevice(deviceId).ConnectionClosed();
}
public void AddUpload(string deviceId, int bytes) => GetDevice(deviceId).AddUpload(bytes);
public void AddDownload(string deviceId, int bytes) => GetDevice(deviceId).AddDownload(bytes);
public TrafficDatabase Snapshot() => new()
{
UpdatedAtUtc = DateTimeOffset.UtcNow,
Devices = _devices.OrderBy(static pair => pair.Key).Select(static pair => new TrafficRecord
{
DeviceId = pair.Key,
UploadBytes = pair.Value.UploadBytes,
DownloadBytes = pair.Value.DownloadBytes
}).ToList()
};
}
public sealed class DeviceTrafficCounter
{
private long _activeConnections;
private long _uploadBytes;
private long _downloadBytes;
public DeviceTrafficCounter(long uploadBytes = 0, long downloadBytes = 0)
{
_uploadBytes = uploadBytes;
_downloadBytes = downloadBytes;
}
public int ActiveConnections => checked((int)Interlocked.Read(ref _activeConnections));
public long UploadBytes => Interlocked.Read(ref _uploadBytes);
public long DownloadBytes => Interlocked.Read(ref _downloadBytes);
internal void ConnectionOpened() => Interlocked.Increment(ref _activeConnections);
internal void ConnectionClosed() => Interlocked.Decrement(ref _activeConnections);
internal void AddUpload(int bytes) => Interlocked.Add(ref _uploadBytes, bytes);
internal void AddDownload(int bytes) => Interlocked.Add(ref _downloadBytes, bytes);
}
using System.Collections.Concurrent;
using LumaTunnel.Server.Core.Persistence;
namespace LumaTunnel.Server.Core.Runtime;
public sealed class TrafficCounters
{
private readonly ConcurrentDictionary<string, DeviceTrafficCounter> _devices = new(StringComparer.Ordinal);
private long _activeConnections;
public TrafficCounters(IEnumerable<TrafficRecord>? initial = null)
{
if (initial is null) return;
foreach (var record in initial)
_devices[record.DeviceId] = new DeviceTrafficCounter(record.UploadBytes, record.DownloadBytes);
}
public int ActiveConnections => checked((int)Interlocked.Read(ref _activeConnections));
public DeviceTrafficCounter GetDevice(string deviceId) => _devices.GetOrAdd(deviceId, static _ => new DeviceTrafficCounter());
public void ConnectionOpened(string deviceId)
{
Interlocked.Increment(ref _activeConnections);
GetDevice(deviceId).ConnectionOpened();
}
public void ConnectionClosed(string deviceId)
{
Interlocked.Decrement(ref _activeConnections);
GetDevice(deviceId).ConnectionClosed();
}
public void AddUpload(string deviceId, int bytes) => GetDevice(deviceId).AddUpload(bytes);
public void AddDownload(string deviceId, int bytes) => GetDevice(deviceId).AddDownload(bytes);
public TrafficDatabase Snapshot() => new()
{
UpdatedAtUtc = DateTimeOffset.UtcNow,
Devices = _devices.OrderBy(static pair => pair.Key).Select(static pair => new TrafficRecord
{
DeviceId = pair.Key,
UploadBytes = pair.Value.UploadBytes,
DownloadBytes = pair.Value.DownloadBytes
}).ToList()
};
}
public sealed class DeviceTrafficCounter
{
private long _activeConnections;
private long _uploadBytes;
private long _downloadBytes;
public DeviceTrafficCounter(long uploadBytes = 0, long downloadBytes = 0)
{
_uploadBytes = uploadBytes;
_downloadBytes = downloadBytes;
}
public int ActiveConnections => checked((int)Interlocked.Read(ref _activeConnections));
public long UploadBytes => Interlocked.Read(ref _uploadBytes);
public long DownloadBytes => Interlocked.Read(ref _downloadBytes);
internal void ConnectionOpened() => Interlocked.Increment(ref _activeConnections);
internal void ConnectionClosed() => Interlocked.Decrement(ref _activeConnections);
internal void AddUpload(int bytes) => Interlocked.Add(ref _uploadBytes, bytes);
internal void AddDownload(int bytes) => Interlocked.Add(ref _downloadBytes, bytes);
}