mirror of
https://github.com/snltty/linker.git
synced 2025-10-06 17:46:59 +08:00
126 lines
4.8 KiB
C#
126 lines
4.8 KiB
C#
using linker.libs;
|
|
using linker.messenger.relay.server.caching;
|
|
using System.Collections.Concurrent;
|
|
using System.Net;
|
|
|
|
namespace linker.messenger.relay.server
|
|
{
|
|
/// <summary>
|
|
/// 中继主机操作
|
|
/// </summary>
|
|
public class RelayServerMasterTransfer
|
|
{
|
|
|
|
private ulong relayFlowingId = 0;
|
|
private readonly ICrypto crypto;
|
|
private readonly ConcurrentDictionary<string, RelayServerNodeReportInfo> reports = new ConcurrentDictionary<string, RelayServerNodeReportInfo>();
|
|
|
|
|
|
private readonly IRelayServerCaching relayCaching;
|
|
private readonly ISerializer serializer;
|
|
public RelayServerMasterTransfer(IRelayServerCaching relayCaching, ISerializer serializer, IRelayServerMasterStore relayServerMasterStore)
|
|
{
|
|
this.relayCaching = relayCaching;
|
|
this.serializer = serializer;
|
|
crypto = CryptoFactory.CreateSymmetric(relayServerMasterStore.Master.SecretKey);
|
|
}
|
|
|
|
|
|
public ulong AddRelay(string fromid, string fromName, string toid, string toName, string groupid)
|
|
{
|
|
ulong flowingId = Interlocked.Increment(ref relayFlowingId);
|
|
|
|
RelayCacheInfo cache = new RelayCacheInfo
|
|
{
|
|
FlowId = flowingId,
|
|
FromId = fromid,
|
|
FromName = fromName,
|
|
ToId = toid,
|
|
ToName = toName,
|
|
GroupId = groupid
|
|
};
|
|
bool added = relayCaching.TryAdd($"{fromid}->{toid}->{flowingId}", cache, 15000);
|
|
if (added == false) return 0;
|
|
|
|
return flowingId;
|
|
}
|
|
|
|
public Memory<byte> TryGetRelayCache(string key)
|
|
{
|
|
if (relayCaching.TryGetValue(key, out RelayCacheInfo value))
|
|
{
|
|
byte[] bytes = crypto.Encode(serializer.Serialize(value));
|
|
return bytes;
|
|
}
|
|
return Helper.EmptyArray;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置节点
|
|
/// </summary>
|
|
/// <param name="ep"></param>
|
|
/// <param name="data"></param>
|
|
public void SetNodeReport(IPEndPoint ep, Memory<byte> data)
|
|
{
|
|
try
|
|
{
|
|
if (crypto == null) return;
|
|
data = crypto.Decode(data.ToArray());
|
|
RelayServerNodeReportInfo relayNodeReportInfo = serializer.Deserialize<RelayServerNodeReportInfo>(data.Span);
|
|
|
|
if (relayNodeReportInfo.Id == RelayServerNodeInfo.MASTER_NODE_ID)
|
|
{
|
|
relayNodeReportInfo.EndPoint = new IPEndPoint(IPAddress.Any, 0);
|
|
}
|
|
else if (relayNodeReportInfo.EndPoint.Address.Equals(IPAddress.Any))
|
|
{
|
|
relayNodeReportInfo.EndPoint.Address = ep.Address;
|
|
}
|
|
relayNodeReportInfo.LastTicks = Environment.TickCount64;
|
|
reports.AddOrUpdate(relayNodeReportInfo.Id, relayNodeReportInfo, (a, b) => relayNodeReportInfo);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if(LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
|
{
|
|
LoggerHelper.Instance.Error(ex);
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 获取节点列表
|
|
/// </summary>
|
|
/// <param name="validated">是否已认证</param>
|
|
/// <returns></returns>
|
|
public List<RelayServerNodeReportInfo> GetNodes(bool validated)
|
|
{
|
|
var result = reports.Values
|
|
.Where(c => c.Public || (c.Public == false && validated))
|
|
.Where(c => Environment.TickCount64 - c.LastTicks < 15000)
|
|
.Where(c => c.ConnectionRatio < 100 && (c.MaxGbTotal == 0 || (c.MaxGbTotal > 0 && c.MaxGbTotalLastBytes > 0)))
|
|
.OrderByDescending(c => c.LastTicks);
|
|
|
|
return result.OrderByDescending(x => x.MaxConnection == 0 ? int.MaxValue : x.MaxConnection)
|
|
.ThenBy(x => x.ConnectionRatio)
|
|
.ThenBy(x => x.BandwidthRatio)
|
|
.ThenByDescending(x => x.MaxBandwidth == 0 ? double.MaxValue : x.MaxBandwidth)
|
|
.ThenByDescending(x => x.MaxBandwidthTotal == 0 ? double.MaxValue : x.MaxBandwidthTotal)
|
|
.ThenByDescending(x => x.MaxGbTotal == 0 ? double.MaxValue : x.MaxGbTotal)
|
|
.ThenByDescending(x => x.MaxGbTotalLastBytes == 0 ? ulong.MaxValue : x.MaxGbTotalLastBytes)
|
|
.ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否需要认证
|
|
/// </summary>
|
|
/// <param name="nodeId"></param>
|
|
/// <returns></returns>
|
|
public bool NodeValidate(string nodeId)
|
|
{
|
|
return reports.TryGetValue(nodeId, out RelayServerNodeReportInfo relayNodeReportInfo) && relayNodeReportInfo.Public == false;
|
|
}
|
|
}
|
|
|
|
|
|
}
|