重构中继

This commit is contained in:
snltty
2025-11-27 16:41:58 +08:00
parent fd532d3705
commit a90ed16721
24 changed files with 288 additions and 165 deletions

View File

@@ -1,5 +1,5 @@
v1.9.6 v1.9.6
2025-11-26 17:37:42 2025-11-27 16:41:58
1. 一些累计更新一些BUG修复 1. 一些累计更新一些BUG修复
2. 优化客户端数据同步,减少服务器流量 2. 优化客户端数据同步,减少服务器流量
3. 去除cdkey改为发电解锁中继速度 3. 去除cdkey改为发电解锁中继速度

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace linker.libs.web namespace linker.libs.web
{ {
@@ -20,7 +21,7 @@ namespace linker.libs.web
public interface IWebApiController public interface IWebApiController
{ {
public string Path { get; } public string Path { get; }
public Memory<byte> Handle(string query); public Task<Memory<byte>> Handle(string query);
public void Free(); public void Free();
} }

View File

@@ -88,7 +88,7 @@ namespace linker.libs.web
if (dic.TryGetValue(path, out IWebApiController controller)) if (dic.TryGetValue(path, out IWebApiController controller))
{ {
Memory<byte> memory = controller.Handle(query); Memory<byte> memory = await controller.Handle(query);
response.ContentLength64 = memory.Length; response.ContentLength64 = memory.Length;
response.ContentType = "application/json"; response.ContentType = "application/json";
await response.OutputStream.WriteAsync(memory); await response.OutputStream.WriteAsync(memory);

View File

@@ -226,7 +226,7 @@ namespace linker.messenger.action
} }
return string.Empty; return string.Empty;
} }
public async Task<List<RelayServerNodeReportInfo>> Validate(string userid, SignCacheInfo fromMachine, List<RelayServerNodeReportInfo> nodes) public async Task<List<RelayNodeStoreInfo>> Validate(string userid, SignCacheInfo fromMachine, List<RelayNodeStoreInfo> nodes)
{ {
if (string.IsNullOrWhiteSpace(actionServerStore.RelayNodeUrl) == false) if (string.IsNullOrWhiteSpace(actionServerStore.RelayNodeUrl) == false)
{ {
@@ -242,7 +242,7 @@ namespace linker.messenger.action
FromMachineName = fromMachine.MachineName, FromMachineName = fromMachine.MachineName,
Nodes = nodes.Select(c => new JsonArgRelayNodeItemInfo Nodes = nodes.Select(c => new JsonArgRelayNodeItemInfo
{ {
Id = c.Id, Id = c.NodeId,
Name = c.Name, Name = c.Name,
Public = c.Public Public = c.Public
}).ToList() ?? [] }).ToList() ?? []
@@ -261,7 +261,7 @@ namespace linker.messenger.action
string ids = await actionTransfer.ExcuteActions(Replace(replace, str), actionServerStore.RelayNodeUrl).ConfigureAwait(false); string ids = await actionTransfer.ExcuteActions(Replace(replace, str), actionServerStore.RelayNodeUrl).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(ids)) return []; if (string.IsNullOrWhiteSpace(ids)) return [];
return nodes.Where(c => ids.Split(',').Contains(c.Id)).ToList(); return nodes.Where(c => ids.Split(',').Contains(c.NodeId)).ToList();
} }
return nodes; return nodes;
} }

View File

@@ -32,8 +32,8 @@ namespace linker.messenger.flow
public sealed class RelayReportResolverFlow : RelayServerReportResolver public sealed class RelayReportResolverFlow : RelayServerReportResolver
{ {
private readonly RelayReportFlow relayReportFlow; private readonly RelayReportFlow relayReportFlow;
public RelayReportResolverFlow(RelayReportFlow relayReportFlow, RelayServerMasterTransfer relayServerTransfer, IMessengerResolver messengerResolver) public RelayReportResolverFlow(RelayReportFlow relayReportFlow, IMessengerResolver messengerResolver)
: base(relayServerTransfer, messengerResolver) : base( messengerResolver)
{ {
this.relayReportFlow = relayReportFlow; this.relayReportFlow = relayReportFlow;
} }

View File

@@ -1,5 +1,6 @@
using linker.libs.extends; using linker.libs.extends;
using linker.libs.web; using linker.libs.web;
using System.Threading.Tasks;
namespace linker.messenger.flow.webapi namespace linker.messenger.flow.webapi
{ {
public sealed class WebApiCitysController : IWebApiController public sealed class WebApiCitysController : IWebApiController
@@ -11,9 +12,9 @@ namespace linker.messenger.flow.webapi
{ {
this.flowResolver = flowResolver; this.flowResolver = flowResolver;
} }
public Memory<byte> Handle(string query) public async Task<Memory<byte>> Handle(string query)
{ {
return flowResolver.GetCitys().ToJson().ToBytes(); return await Task.FromResult(flowResolver.GetCitys().ToJson().ToBytes()).ConfigureAwait(false);
} }
public void Free() public void Free()

View File

@@ -1,6 +1,7 @@
using linker.libs.extends; using linker.libs.extends;
using linker.libs.web; using linker.libs.web;
using linker.messenger.signin; using linker.messenger.signin;
using System.Threading.Tasks;
namespace linker.messenger.flow.webapi namespace linker.messenger.flow.webapi
{ {
public sealed class WebApiOnlineController : IWebApiController public sealed class WebApiOnlineController : IWebApiController
@@ -14,10 +15,10 @@ namespace linker.messenger.flow.webapi
this.signCaching = signCaching; this.signCaching = signCaching;
this.flowResolver = flowResolver; this.flowResolver = flowResolver;
} }
public Memory<byte> Handle(string query) public async Task<Memory<byte>> Handle(string query)
{ {
signCaching.GetOnline(out int all, out int online); signCaching.GetOnline(out int all, out int online);
return new return await Task.FromResult(new
{ {
CurrentServer = new CurrentServer = new
{ {
@@ -30,7 +31,7 @@ namespace linker.messenger.flow.webapi
Online = flowResolver.ReceiveBytes >> 32, Online = flowResolver.ReceiveBytes >> 32,
Server = flowResolver.SendtBytes, Server = flowResolver.SendtBytes,
} }
}.ToJson().ToBytes(); }.ToJson().ToBytes()).ConfigureAwait(false);
} }
public void Free() public void Free()

View File

@@ -1,5 +1,6 @@
using linker.libs.extends; using linker.libs.extends;
using linker.libs.web; using linker.libs.web;
using System.Threading.Tasks;
namespace linker.messenger.flow.webapi namespace linker.messenger.flow.webapi
{ {
public sealed class WebApiSystemsController : IWebApiController public sealed class WebApiSystemsController : IWebApiController
@@ -11,9 +12,9 @@ namespace linker.messenger.flow.webapi
{ {
this.flowResolver = flowResolver; this.flowResolver = flowResolver;
} }
public Memory<byte> Handle(string query) public async Task<Memory<byte>> Handle(string query)
{ {
return flowResolver.GetSystems().ToJson().ToBytes(); return await Task.FromResult(flowResolver.GetSystems().ToJson().ToBytes()).ConfigureAwait(false);
} }
public void Free() public void Free()

View File

@@ -33,7 +33,7 @@ namespace linker.messenger.relay.client
this.tunnelTransfer = tunnelTransfer; this.tunnelTransfer = tunnelTransfer;
} }
public List<RelayServerNodeReportInfo> Subscribe(ApiControllerParamsInfo param) public List<RelayNodeStoreInfo> Subscribe(ApiControllerParamsInfo param)
{ {
relayTestTransfer.Subscribe(); relayTestTransfer.Subscribe();
return relayTestTransfer.Nodes; return relayTestTransfer.Nodes;

View File

@@ -13,10 +13,10 @@ namespace linker.messenger.relay.client
/// </summary> /// </summary>
public sealed class RelayClientTestTransfer public sealed class RelayClientTestTransfer
{ {
private readonly TransportRelay transportRelay; private readonly TransportRelay transportRelay;
private readonly SignInClientState signInClientState; private readonly SignInClientState signInClientState;
public List<RelayServerNodeReportInfo> Nodes { get; private set; } = new List<RelayServerNodeReportInfo>(); public List<RelayNodeStoreInfo> Nodes { get; private set; } = new List<RelayNodeStoreInfo>();
public RelayClientTestTransfer(TransportRelay transportRelay, SignInClientState signInClientState) public RelayClientTestTransfer(TransportRelay transportRelay, SignInClientState signInClientState)
{ {
@@ -39,10 +39,11 @@ namespace linker.messenger.relay.client
Nodes = await transportRelay.RelayTestAsync().ConfigureAwait(false); Nodes = await transportRelay.RelayTestAsync().ConfigureAwait(false);
var tasks = Nodes.Select(async (c) => var tasks = Nodes.Select(async (c) =>
{ {
c.EndPoint = c.EndPoint == null || c.EndPoint.Address.Equals(IPAddress.Any) ? signInClientState.Connection.Address : c.EndPoint; IPEndPoint ep = NetworkHelper.GetEndPoint(c.Host, 1802);
IPAddress ip = ep.Address.Equals(IPAddress.Any) || ep.Address.Equals(IPAddress.Loopback) ? signInClientState.Connection.Address.Address : ep.Address;
using Ping ping = new Ping(); using Ping ping = new Ping();
var resp = await ping.SendPingAsync(c.EndPoint.Address, 1000); var resp = await ping.SendPingAsync(ip, 1000);
c.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : -1; c.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : -1;
}); });
await Task.WhenAll(tasks).ConfigureAwait(false); await Task.WhenAll(tasks).ConfigureAwait(false);

View File

@@ -46,10 +46,10 @@ namespace linker.messenger.relay.messenger
{ {
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false) if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{ {
connection.Write(serializer.Serialize(new List<RelayServerNodeReportInfo> { })); connection.Write(serializer.Serialize(new List<RelayNodeStoreInfo> { }));
return; return;
} }
List<RelayServerNodeReportInfo> nodes = await GetNodes(cache); List<RelayNodeStoreInfo> nodes = await GetNodes(cache);
connection.Write(serializer.Serialize(nodes)); connection.Write(serializer.Serialize(nodes));
} }
@@ -72,9 +72,9 @@ namespace linker.messenger.relay.messenger
return; return;
} }
connection.Write(serializer.Serialize(new RelayAskResultInfo { Nodes = nodes, MasterId = relayServerNodeStore.Node.Id })); connection.Write(serializer.Serialize(new RelayAskResultInfo { Nodes = nodes, MasterId = relayServerNodeStore.Node.NodeId }));
} }
private async Task<List<RelayServerNodeReportInfo>> GetNodes(SignCacheInfo from) private async Task<List<RelayNodeStoreInfo>> GetNodes(SignCacheInfo from)
{ {
return await relayServerTransfer.GetNodes(from.Super, from.UserId, from.MachineId); return await relayServerTransfer.GetNodes(from.Super, from.UserId, from.MachineId);
} }
@@ -97,5 +97,19 @@ namespace linker.messenger.relay.messenger
} }
} }
[MessengerId((ushort)RelayMessengerIds.NodeReport)]
public void NodeReport188(IConnection connection)
{
try
{
relayServerReportResolver.Add(connection.ReceiveRequestWrap.Payload.Length, 0);
RelayServerNodeReportInfoOld info = serializer.Deserialize<RelayServerNodeReportInfoOld>(connection.ReceiveRequestWrap.Payload.Span);
}
catch (Exception)
{
}
connection.Write(serializer.Serialize(VersionHelper.Version));
}
} }
} }

View File

@@ -9,6 +9,7 @@
Nodes = 2105, Nodes = 2105,
NodeGetCache = 2112, NodeGetCache = 2112,
NodeReport = 2128,
Hosts = 2133, Hosts = 2133,

View File

@@ -0,0 +1,20 @@
namespace linker.messenger.relay.server
{
public interface IRelayServerMasterStore
{
public Task<List<RelayNodeStoreInfo>> GetAll();
}
public sealed class RelayNodeStoreInfo : RelayServerNodeReportInfo
{
public int Id { get; set; }
public int BandwidthEachConnection { get; set; } = 50;
public bool Public { get; set; }
public int Delay { get; set; }
public long LastTicks { get; set; }
}
}

View File

@@ -39,52 +39,33 @@ namespace linker.messenger.relay.server
public void Confirm(); public void Confirm();
} }
public sealed class RelayServerNodeInfo public class RelayServerNodeInfo
{ {
private string id = Guid.NewGuid().ToString().ToUpper(); private string nodeId = Guid.NewGuid().ToString().ToUpper();
public string Id public string NodeId { get => nodeId; set { nodeId = value.SubStr(0, 36); } }
{
get => id; set
{
id = value.SubStr(0, 36);
}
}
private string name = Dns.GetHostName().SubStr(0, 32); private string name = Dns.GetHostName().SubStr(0, 32);
public string Name public string Name { get => name; set { name = value.SubStr(0, 32); } }
{
get => name; set
{
name = value.SubStr(0, 32);
}
}
public string Host { get; set; } = string.Empty; public string Host { get; set; } = string.Empty;
public int MaxConnection { get; set; } public TunnelProtocolType Protocol { get; set; } = TunnelProtocolType.Tcp;
public double MaxBandwidth { get; set; } public int Connections { get; set; } = 1000;
public double MaxBandwidthTotal { get; set; } public int Bandwidth { get; set; } = 50;
public double MaxGbTotal { get; set; } public int DataEachMonth { get; set; } = 100;
public long MaxGbTotalLastBytes { get; set; } public long DataRemain { get; set; }
public int MaxGbTotalMonth { get; set; } public int DataMonth { get; set; }
public string Url { get; set; } = "https://linker.snltty.com";
public bool Public { get; set; } public string Logo { get; set; } = "https://linker.snltty.com/img/logo.png";
public string MasterHost { get; set; } = string.Empty;
#if DEBUG
public string MasterSecretKey { get; set; } = Helper.GlobalString;
#else
public string MasterSecretKey { get; set; } = string.Empty;
#endif
public string Url { get; set; } = "https://linker-doc.snltty.com";
public bool AllowTcp { get; set; } = true;
public bool AllowUdp { get; set; }
public bool Sync2Server { get; set; }
public string[] MasterHosts { get; set; } = [];
} }
public partial class RelayServerNodeReportInfo public class RelayServerNodeReportInfo : RelayServerNodeInfo
{
public string Version { get; set; } = string.Empty;
public int ConnectionsRatio { get; set; }
public int BandwidthRatio { get; set; }
}
public partial class RelayServerNodeReportInfoOld
{ {
public string Id { get; set; } = string.Empty; public string Id { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
@@ -101,9 +82,7 @@ namespace linker.messenger.relay.server
public bool Public { get; set; } public bool Public { get; set; }
public int Delay { get; set; } public int Delay { get; set; }
public IPEndPoint EndPoint { get; set; } public IPEndPoint EndPoint { get; set; }
public long LastTicks { get; set; } public long LastTicks { get; set; }
/// <summary> /// <summary>
@@ -121,5 +100,5 @@ namespace linker.messenger.relay.server
[JsonIgnore] [JsonIgnore]
public IConnection Connection { get; set; } public IConnection Connection { get; set; }
} }
} }

View File

@@ -1,6 +1,5 @@
 
using linker.messenger.signin; using linker.messenger.signin;
using System.Collections.Concurrent;
namespace linker.messenger.relay.server namespace linker.messenger.relay.server
{ {
@@ -9,16 +8,15 @@ namespace linker.messenger.relay.server
/// </summary> /// </summary>
public class RelayServerMasterTransfer public class RelayServerMasterTransfer
{ {
private readonly ConcurrentDictionary<string, RelayServerNodeReportInfo> reports = new ConcurrentDictionary<string, RelayServerNodeReportInfo>();
private readonly IRelayServerCaching relayCaching; private readonly IRelayServerCaching relayCaching;
private readonly IRelayServerWhiteListStore relayServerWhiteListStore; private readonly IRelayServerWhiteListStore relayServerWhiteListStore;
private readonly IRelayServerMasterStore relayServerMasterStore;
public RelayServerMasterTransfer(IRelayServerCaching relayCaching, IRelayServerWhiteListStore relayServerWhiteListStore) public RelayServerMasterTransfer(IRelayServerCaching relayCaching, IRelayServerWhiteListStore relayServerWhiteListStore, IRelayServerMasterStore relayServerMasterStore)
{ {
this.relayCaching = relayCaching; this.relayCaching = relayCaching;
this.relayServerWhiteListStore = relayServerWhiteListStore; this.relayServerWhiteListStore = relayServerWhiteListStore;
this.relayServerMasterStore = relayServerMasterStore;
} }
@@ -40,9 +38,9 @@ namespace linker.messenger.relay.server
public async Task<RelayCacheInfo> TryGetRelayCache(string key, string nodeid) public async Task<RelayCacheInfo> TryGetRelayCache(string key, string nodeid)
{ {
if (relayCaching.TryGetValue(key, out RelayCacheInfo cache) && reports.TryGetValue(nodeid, out var node)) if (relayCaching.TryGetValue(key, out RelayCacheInfo cache))
{ {
List<double> bandwidth = await relayServerWhiteListStore.GetBandwidth(cache.UserId, cache.FromId, cache.ToId, node.Id); List<double> bandwidth = await relayServerWhiteListStore.GetBandwidth(cache.UserId, cache.FromId, cache.ToId, nodeid);
if (bandwidth.Any(c => c < 0)) if (bandwidth.Any(c => c < 0))
{ {
return null; return null;
@@ -61,42 +59,42 @@ namespace linker.messenger.relay.server
/// </summary> /// </summary>
/// <param name="validated">是否已认证</param> /// <param name="validated">是否已认证</param>
/// <returns></returns> /// <returns></returns>
public async Task<List<RelayServerNodeReportInfo>> GetNodes(bool validated, string userid, string machineId) public async Task<List<RelayNodeStoreInfo>> GetNodes(bool validated, string userid, string machineId)
{ {
var nodes = (await relayServerWhiteListStore.GetNodes(userid, machineId)).Where(c => c.Bandwidth >= 0).SelectMany(c => c.Nodes); var nodes = (await relayServerWhiteListStore.GetNodes(userid, machineId)).Where(c => c.Bandwidth >= 0).SelectMany(c => c.Nodes);
var result = reports.Values var result = (await relayServerMasterStore.GetAll())
.Where(c => Environment.TickCount64 - c.LastTicks < 15000) .Where(c => Environment.TickCount64 - c.LastTicks < 15000)
.Where(c => .Where(c =>
{ {
return validated || nodes.Contains(c.Id) || nodes.Contains("*") return validated || nodes.Contains(c.NodeId) || nodes.Contains("*")
|| (c.Public && c.ConnectionRatio < c.MaxConnection && (c.MaxGbTotal == 0 || (c.MaxGbTotal > 0 && c.MaxGbTotalLastBytes > 0))); || (c.Public && c.ConnectionsRatio < c.Connections && (c.DataEachMonth == 0 || (c.DataEachMonth > 0 && c.DataRemain > 0)));
}) })
.OrderByDescending(c => c.LastTicks); .OrderByDescending(c => c.LastTicks);
return result.OrderByDescending(x => x.MaxConnection == 0 ? int.MaxValue : x.MaxConnection) return result.OrderByDescending(x => x.Connections == 0 ? int.MaxValue : x.Connections)
.ThenBy(x => x.ConnectionRatio) .ThenBy(x => x.ConnectionsRatio)
.ThenBy(x => x.BandwidthRatio) .ThenBy(x => x.BandwidthRatio)
.ThenByDescending(x => x.MaxBandwidth == 0 ? double.MaxValue : x.MaxBandwidth) .ThenByDescending(x => x.BandwidthEachConnection == 0 ? int.MaxValue : x.BandwidthEachConnection)
.ThenByDescending(x => x.MaxBandwidthTotal == 0 ? double.MaxValue : x.MaxBandwidthTotal) .ThenByDescending(x => x.Bandwidth == 0 ? int.MaxValue : x.Bandwidth)
.ThenByDescending(x => x.MaxGbTotal == 0 ? double.MaxValue : x.MaxGbTotal) .ThenByDescending(x => x.DataEachMonth == 0 ? int.MaxValue : x.DataEachMonth)
.ThenByDescending(x => x.MaxGbTotalLastBytes == 0 ? long.MaxValue : x.MaxGbTotalLastBytes) .ThenByDescending(x => x.DataRemain == 0 ? long.MaxValue : x.DataRemain)
.ToList(); .ToList();
} }
public List<RelayServerNodeReportInfo> GetPublicNodes() public async Task<List<RelayNodeStoreInfo>> GetPublicNodes()
{ {
var result = reports.Values var result = (await relayServerMasterStore.GetAll())
.Where(c => Environment.TickCount64 - c.LastTicks < 15000) .Where(c => Environment.TickCount64 - c.LastTicks < 15000)
.Where(c => c.Public) .Where(c => c.Public)
.OrderByDescending(c => c.LastTicks); .OrderByDescending(c => c.LastTicks);
return result.OrderByDescending(x => x.MaxConnection == 0 ? int.MaxValue : x.MaxConnection) return result.OrderByDescending(x => x.Connections == 0 ? int.MaxValue : x.Connections)
.ThenBy(x => x.ConnectionRatio) .ThenBy(x => x.ConnectionsRatio)
.ThenBy(x => x.BandwidthRatio) .ThenBy(x => x.BandwidthRatio)
.ThenByDescending(x => x.MaxBandwidth == 0 ? double.MaxValue : x.MaxBandwidth) .ThenByDescending(x => x.BandwidthEachConnection == 0 ? int.MaxValue : x.BandwidthEachConnection)
.ThenByDescending(x => x.MaxBandwidthTotal == 0 ? double.MaxValue : x.MaxBandwidthTotal) .ThenByDescending(x => x.Bandwidth == 0 ? int.MaxValue : x.Bandwidth)
.ThenByDescending(x => x.MaxGbTotal == 0 ? double.MaxValue : x.MaxGbTotal) .ThenByDescending(x => x.DataEachMonth == 0 ? int.MaxValue : x.DataEachMonth)
.ThenByDescending(x => x.MaxGbTotalLastBytes == 0 ? long.MaxValue : x.MaxGbTotalLastBytes) .ThenByDescending(x => x.DataRemain == 0 ? long.MaxValue : x.DataRemain)
.ToList(); .ToList();
} }

View File

@@ -36,7 +36,7 @@ namespace linker.messenger.relay.server
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.relayServerConnectionTransfer = relayServerConnectionTransfer; this.relayServerConnectionTransfer = relayServerConnectionTransfer;
limitTotal.SetLimit((uint)Math.Ceiling((Node.MaxBandwidthTotal * 1024 * 1024) / 8.0)); limitTotal.SetLimit((uint)Math.Ceiling((Node.Bandwidth * 1024 * 1024) / 8.0));
TrafficTask(); TrafficTask();
} }
@@ -56,7 +56,7 @@ namespace linker.messenger.relay.server
{ {
Connection = connection, Connection = connection,
MessengerId = (ushort)RelayMessengerIds.NodeGetCache, MessengerId = (ushort)RelayMessengerIds.NodeGetCache,
Payload = serializer.Serialize(new ValueTuple<string, string>(key, Node.Id)), Payload = serializer.Serialize(new ValueTuple<string, string>(key, Node.NodeId)),
Timeout = 1000 Timeout = 1000
}).ConfigureAwait(false); }).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK && resp.Data.Length > 0) if (resp.Code == MessageResponeCodes.OK && resp.Data.Length > 0)
@@ -75,9 +75,6 @@ namespace linker.messenger.relay.server
public bool Validate(TunnelProtocolType tunnelProtocolType) public bool Validate(TunnelProtocolType tunnelProtocolType)
{ {
if (tunnelProtocolType == TunnelProtocolType.Udp && Node.AllowUdp == false) return false;
if (tunnelProtocolType == TunnelProtocolType.Tcp && Node.AllowTcp == false) return false;
return true; return true;
} }
/// <summary> /// <summary>
@@ -94,9 +91,9 @@ namespace linker.messenger.relay.server
/// <returns></returns> /// <returns></returns>
private bool ValidateConnection(RelayCacheInfo relayCache) private bool ValidateConnection(RelayCacheInfo relayCache)
{ {
bool res = Node.MaxConnection == 0 || Node.MaxConnection * 2 > connectionNum; bool res = Node.Connections == 0 || Node.Connections * 2 > connectionNum;
if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay ValidateConnection false,{connectionNum}/{Node.MaxConnection * 2}"); LoggerHelper.Instance.Debug($"relay ValidateConnection false,{connectionNum}/{Node.Connections * 2}");
return res; return res;
} }
@@ -106,11 +103,11 @@ namespace linker.messenger.relay.server
/// <returns></returns> /// <returns></returns>
private bool ValidateBytes(RelayCacheInfo relayCache) private bool ValidateBytes(RelayCacheInfo relayCache)
{ {
bool res = Node.MaxGbTotal == 0 bool res = Node.DataEachMonth == 0
|| (Node.MaxGbTotal > 0 && Node.MaxGbTotalLastBytes > 0); || (Node.DataEachMonth > 0 && Node.DataRemain > 0);
if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay ValidateBytes false,{Node.MaxGbTotalLastBytes}bytes/{Node.MaxGbTotal}gb"); LoggerHelper.Instance.Debug($"relay ValidateBytes false,{Node.DataRemain}bytes/{Node.DataEachMonth}gb");
return res; return res;
} }
@@ -184,11 +181,11 @@ namespace linker.messenger.relay.server
{ {
Interlocked.Add(ref bytes, length); Interlocked.Add(ref bytes, length);
if (Node.MaxGbTotal == 0) return true; if (Node.DataEachMonth == 0) return true;
Interlocked.Add(ref cache.Sendt, length); Interlocked.Add(ref cache.Sendt, length);
return Node.MaxGbTotalLastBytes > 0; return Node.DataRemain > 0;
} }
/// <summary> /// <summary>
@@ -204,32 +201,25 @@ namespace linker.messenger.relay.server
return; return;
} }
//无限制 relayCache.Limit.SetLimit((uint)Math.Ceiling(Node.Bandwidth * 1024 * 1024 / 8.0));
if (relayCache.Cache.Super || Node.MaxBandwidth == 0)
{
relayCache.Limit.SetLimit(0);
return;
}
relayCache.Limit.SetLimit((uint)Math.Ceiling(Node.MaxBandwidth * 1024 * 1024 / 8.0));
} }
private void ResetNodeBytes() private void ResetNodeBytes()
{ {
if (Node.MaxGbTotal == 0) return; if (Node.DataEachMonth == 0) return;
foreach (var cache in trafficDict.Values) foreach (var cache in trafficDict.Values)
{ {
long length = Interlocked.Exchange(ref cache.Sendt, 0); long length = Interlocked.Exchange(ref cache.Sendt, 0);
if (Node.MaxGbTotalLastBytes >= length) if (Node.DataRemain >= length)
relayServerNodeStore.SetMaxGbTotalLastBytes(Node.MaxGbTotalLastBytes - length); relayServerNodeStore.SetMaxGbTotalLastBytes(Node.DataRemain - length);
else relayServerNodeStore.SetMaxGbTotalLastBytes(0); else relayServerNodeStore.SetMaxGbTotalLastBytes(0);
} }
if (Node.MaxGbTotalMonth != DateTime.Now.Month) if (Node.DataMonth != DateTime.Now.Month)
{ {
relayServerNodeStore.SetMaxGbTotalMonth(DateTime.Now.Month); relayServerNodeStore.SetMaxGbTotalMonth(DateTime.Now.Month);
relayServerNodeStore.SetMaxGbTotalLastBytes((long)(Node.MaxGbTotal * 1024 * 1024 * 1024)); relayServerNodeStore.SetMaxGbTotalLastBytes((long)(Node.DataEachMonth * 1024 * 1024 * 1024));
} }
relayServerNodeStore.Confirm(); relayServerNodeStore.Confirm();
} }

View File

@@ -13,12 +13,10 @@ namespace linker.messenger.relay.server
{ {
public byte Type => (byte)ResolverType.RelayReport; public byte Type => (byte)ResolverType.RelayReport;
private readonly RelayServerMasterTransfer relayServerTransfer;
private readonly IMessengerResolver messengerResolver; private readonly IMessengerResolver messengerResolver;
public RelayServerReportResolver(RelayServerMasterTransfer relayServerTransfer, IMessengerResolver messengerResolver) public RelayServerReportResolver(IMessengerResolver messengerResolver)
{ {
this.relayServerTransfer = relayServerTransfer;
this.messengerResolver = messengerResolver; this.messengerResolver = messengerResolver;
} }
@@ -31,23 +29,9 @@ namespace linker.messenger.relay.server
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024); byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);
try try
{ {
await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).ConfigureAwait(false);
await socket.ReceiveAsync(buffer.AsMemory(0, 1), SocketFlags.None).ConfigureAwait(false); await messengerResolver.BeginReceiveServer(socket, Helper.EmptyArray).ConfigureAwait(false);
int length = buffer[0];
Add(memory.Length,length);
await socket.ReceiveAsync(buffer.AsMemory(0, length), SocketFlags.None).ConfigureAwait(false);
string key = buffer.AsMemory(0, length).GetString();
/*
if (relayServerMasterStore.Master.SecretKey.Sha256() == key)
{
await messengerResolver.BeginReceiveServer(socket, Helper.EmptyArray).ConfigureAwait(false);
}
else*/
{
socket.SafeClose();
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -23,6 +23,6 @@ namespace linker.messenger.relay.server.validator
/// <param name="fromMachine"></param> /// <param name="fromMachine"></param>
/// <param name="nodes"></param> /// <param name="nodes"></param>
/// <returns></returns> /// <returns></returns>
public Task<List<RelayServerNodeReportInfo>> Validate(string userid, SignCacheInfo from, List<RelayServerNodeReportInfo> nodes); public Task<List<RelayNodeStoreInfo>> Validate(string userid, SignCacheInfo from, List<RelayNodeStoreInfo> nodes);
} }
} }

View File

@@ -59,7 +59,7 @@ namespace linker.messenger.relay.server.validator
} }
return string.Empty; return string.Empty;
} }
public async Task<List<RelayServerNodeReportInfo>> Validate(string userid, SignCacheInfo fromMachine, List<RelayServerNodeReportInfo> nodes) public async Task<List<RelayNodeStoreInfo>> Validate(string userid, SignCacheInfo fromMachine, List<RelayNodeStoreInfo> nodes)
{ {
foreach (var item in validators) foreach (var item in validators)
{ {

View File

@@ -62,7 +62,7 @@ namespace linker.tunnel.transport
{ {
//问一下能不能中继 //问一下能不能中继
RelayAskResultInfo ask = await RelayAsk(tunnelTransportInfo).ConfigureAwait(false); RelayAskResultInfo ask = await RelayAsk(tunnelTransportInfo).ConfigureAwait(false);
List<RelayServerNodeReportInfo> nodes = ask.Nodes; List<RelayNodeStoreInfo> nodes = ask.Nodes;
if (ask.Nodes.Count == 0) if (ask.Nodes.Count == 0)
{ {
return null; return null;
@@ -149,7 +149,7 @@ namespace linker.tunnel.transport
}).ConfigureAwait(false); }).ConfigureAwait(false);
if (resp.Code != MessageResponeCodes.OK) if (resp.Code != MessageResponeCodes.OK)
{ {
return new RelayAskResultInfo { Info = relayInfo, Nodes = new List<RelayServerNodeReportInfo>() }; return new RelayAskResultInfo { Info = relayInfo, Nodes = new List<RelayNodeStoreInfo>() };
} }
RelayAskResultInfo ask = serializer.Deserialize<RelayAskResultInfo>(resp.Data.Span); RelayAskResultInfo ask = serializer.Deserialize<RelayAskResultInfo>(resp.Data.Span);
ask.Info = relayInfo; ask.Info = relayInfo;
@@ -164,12 +164,12 @@ namespace linker.tunnel.transport
try try
{ {
foreach (var node in ask.Nodes.Where(c => c.Id == ask.Info.NodeId).Concat(ask.Nodes.Where(c => c.Id != ask.Info.NodeId))) foreach (var node in ask.Nodes.Where(c => c.NodeId == ask.Info.NodeId).Concat(ask.Nodes.Where(c => c.NodeId != ask.Info.NodeId)))
{ {
try try
{ {
IPEndPoint ep = node.EndPoint; IPEndPoint ep = NetworkHelper.GetEndPoint(node.Host,1802);
if (ep == null || ep.Address.Equals(IPAddress.Any)) if (ep == null || ep.Address.Equals(IPAddress.Any) || ep.Address.Equals(IPAddress.Loopback))
{ {
ep = signInClientState.Connection.Address; ep = signInClientState.Connection.Address;
} }
@@ -198,8 +198,8 @@ namespace linker.tunnel.transport
}; };
if(await SendMessage(socket, relayMessage).ConfigureAwait(false)) if(await SendMessage(socket, relayMessage).ConfigureAwait(false))
{ {
ask.Info.Node = node.EndPoint; ask.Info.Node = ep;
ask.Info.NodeId = node.Id; ask.Info.NodeId = node.NodeId;
return socket; return socket;
} }
socket.SafeClose(); socket.SafeClose();
@@ -355,7 +355,7 @@ namespace linker.tunnel.transport
{ {
} }
public async Task<List<RelayServerNodeReportInfo>> RelayTestAsync() public async Task<List<RelayNodeStoreInfo>> RelayTestAsync()
{ {
try try
{ {
@@ -368,13 +368,13 @@ namespace linker.tunnel.transport
if (resp.Code == MessageResponeCodes.OK) if (resp.Code == MessageResponeCodes.OK)
{ {
return serializer.Deserialize<List<RelayServerNodeReportInfo>>(resp.Data.Span); return serializer.Deserialize<List<RelayNodeStoreInfo>>(resp.Data.Span);
} }
} }
catch (Exception) catch (Exception)
{ {
} }
return new List<RelayServerNodeReportInfo>(); return new List<RelayNodeStoreInfo>();
} }
} }
@@ -391,7 +391,7 @@ namespace linker.tunnel.transport
{ {
public RelayInfo Info { get; set; } public RelayInfo Info { get; set; }
public string MasterId { get; set; } public string MasterId { get; set; }
public List<RelayServerNodeReportInfo> Nodes { get; set; } = new List<RelayServerNodeReportInfo>(); public List<RelayNodeStoreInfo> Nodes { get; set; } = new List<RelayNodeStoreInfo>();
} }
public sealed partial class RelayMessageInfo public sealed partial class RelayMessageInfo
{ {

View File

@@ -13,29 +13,28 @@ namespace linker.messenger.relay.webapi
{ {
this.relayServerMasterTransfer = relayServerMasterTransfer; this.relayServerMasterTransfer = relayServerMasterTransfer;
} }
public Memory<byte> Handle(string query) public async Task<Memory<byte>> Handle(string query)
{ {
return relayServerMasterTransfer.GetPublicNodes().Select(c => return (await relayServerMasterTransfer.GetPublicNodes().ConfigureAwait(false)).Select(c =>
{ {
return new return new
{ {
AllowProtocol = c.AllowProtocol, AllowProtocol = c.Protocol,
Name = c.Name, Name = c.Name,
Version = c.Version, Version = c.Version,
BandwidthMaxMbps = c.MaxBandwidthTotal, BandwidthMaxMbps = c.Bandwidth,
BandwidthConnMbps = c.MaxBandwidth, BandwidthConnMbps = c.BandwidthEachConnection,
BandwidthCurrentMbps = c.BandwidthRatio, BandwidthCurrentMbps = c.BandwidthRatio,
BandwidthGbMonth = c.MaxGbTotal, BandwidthGbMonth = c.DataEachMonth,
BandwidthByteAvailable = c.MaxGbTotalLastBytes, BandwidthByteAvailable = c.DataRemain,
ConnectionMaxNum = c.MaxConnection, ConnectionMaxNum = c.Connections,
ConnectionCurrentNum = c.ConnectionRatio, ConnectionCurrentNum = c.ConnectionsRatio,
EndPoint = c.EndPoint,
Url = c.Url, Url = c.Url,
Logo = c.Logo,
}; };
}).ToJson().ToBytes(); }).ToJson().ToBytes();
} }

View File

@@ -64,7 +64,8 @@ namespace linker.messenger.serializer.memorypack
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
MemoryPackFormatterProvider.Register(new AccessUpdateInfoFormatter()); MemoryPackFormatterProvider.Register(new AccessUpdateInfoFormatter());
MemoryPackFormatterProvider.Register(new AccessBitsUpdateInfoFormatter()); MemoryPackFormatterProvider.Register(new AccessBitsUpdateInfoFormatter());

View File

@@ -1,6 +1,8 @@
using linker.messenger.relay.server; using linker.messenger.relay.server;
using linker.tunnel.connection;
using linker.tunnel.transport; using linker.tunnel.transport;
using MemoryPack; using MemoryPack;
using System.Net;
namespace linker.messenger.serializer.memorypack namespace linker.messenger.serializer.memorypack
{ {
@@ -14,10 +16,10 @@ namespace linker.messenger.serializer.memorypack
[MemoryPackInclude] [MemoryPackInclude]
string MasterId => info.MasterId; string MasterId => info.MasterId;
[MemoryPackInclude] [MemoryPackInclude]
List<RelayServerNodeReportInfo> Nodes => info.Nodes; List<RelayNodeStoreInfo> Nodes => info.Nodes;
[MemoryPackConstructor] [MemoryPackConstructor]
SerializableRelayAskResultInfo(string masterId, List<RelayServerNodeReportInfo> nodes) SerializableRelayAskResultInfo(string masterId, List<RelayNodeStoreInfo> nodes)
{ {
var info = new RelayAskResultInfo { MasterId = masterId, Nodes = nodes }; var info = new RelayAskResultInfo { MasterId = masterId, Nodes = nodes };
this.info = info; this.info = info;
@@ -53,7 +55,7 @@ namespace linker.messenger.serializer.memorypack
reader.TryReadObjectHeader(out byte count); reader.TryReadObjectHeader(out byte count);
value.MasterId = reader.ReadValue<string>(); value.MasterId = reader.ReadValue<string>();
if (count > 1) if (count > 1)
value.Nodes = reader.ReadValue<List<RelayServerNodeReportInfo>>(); value.Nodes = reader.ReadValue<List<RelayNodeStoreInfo>>();
} }
} }
@@ -214,4 +216,134 @@ namespace linker.messenger.serializer.memorypack
} }
} }
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeReportInfo
{
[MemoryPackIgnore]
public readonly RelayServerNodeReportInfoOld info;
[MemoryPackInclude]
string Id => info.Id;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
int MaxConnection => info.MaxConnection;
[MemoryPackInclude]
double MaxBandwidth => info.MaxBandwidth;
[MemoryPackInclude]
double MaxBandwidthTotal => info.MaxBandwidthTotal;
[MemoryPackInclude]
double MaxGbTotal => info.MaxGbTotal;
[MemoryPackInclude]
long MaxGbTotalLastBytes => info.MaxGbTotalLastBytes;
[MemoryPackInclude]
double ConnectionRatio => info.ConnectionRatio;
[MemoryPackInclude]
double BandwidthRatio => info.BandwidthRatio;
[MemoryPackInclude]
bool Public => info.Public;
[MemoryPackInclude]
int Delay => info.Delay;
[MemoryPackInclude, MemoryPackAllowSerialize]
IPEndPoint EndPoint => info.EndPoint;
[MemoryPackInclude]
long LastTicks => info.LastTicks;
[MemoryPackInclude]
string Url => info.Url;
[MemoryPackInclude]
TunnelProtocolType AllowProtocol => info.AllowProtocol;
[MemoryPackInclude]
bool Sync2Server => info.Sync2Server;
[MemoryPackInclude]
string Version => info.Version;
[MemoryPackConstructor]
SerializableRelayServerNodeReportInfo(
string id, string name,
int maxConnection, double maxBandwidth, double maxBandwidthTotal,
double maxGbTotal, long maxGbTotalLastBytes,
double connectionRatio, double bandwidthRatio,
bool Public, int delay,
IPEndPoint endPoint, long lastTicks, string url, TunnelProtocolType allowProtocol, bool sync2Server, string version)
{
var info = new RelayServerNodeReportInfoOld
{
BandwidthRatio = bandwidthRatio,
ConnectionRatio = connectionRatio,
Delay = delay,
EndPoint = endPoint,
Id = id,
LastTicks = lastTicks,
MaxBandwidth = maxBandwidth,
MaxBandwidthTotal = maxBandwidthTotal,
MaxConnection = maxConnection,
MaxGbTotal = maxGbTotal,
MaxGbTotalLastBytes = maxGbTotalLastBytes,
Name = name,
Public = Public,
Url = url,
AllowProtocol = allowProtocol,
Sync2Server = sync2Server,
Version = version
};
this.info = info;
}
public SerializableRelayServerNodeReportInfo(RelayServerNodeReportInfoOld info)
{
this.info = info;
}
}
public class RelayServerNodeReportInfoFormatter : MemoryPackFormatter<RelayServerNodeReportInfoOld>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeReportInfoOld value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerNodeReportInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeReportInfoOld value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
value = new RelayServerNodeReportInfoOld();
reader.TryReadObjectHeader(out byte count);
value.Id = reader.ReadValue<string>();
value.Name = reader.ReadValue<string>();
value.MaxConnection = reader.ReadValue<int>();
value.MaxBandwidth = reader.ReadValue<double>();
value.MaxBandwidthTotal = reader.ReadValue<double>();
value.MaxGbTotal = reader.ReadValue<double>();
value.MaxGbTotalLastBytes = reader.ReadValue<long>();
value.ConnectionRatio = reader.ReadValue<double>();
value.BandwidthRatio = reader.ReadValue<double>();
value.Public = reader.ReadValue<bool>();
value.Delay = reader.ReadValue<int>();
value.EndPoint = reader.ReadValue<IPEndPoint>();
value.LastTicks = reader.ReadValue<long>();
if (count > 13)
value.Url = reader.ReadValue<string>();
if (count > 14)
value.AllowProtocol = reader.ReadValue<TunnelProtocolType>();
if (count > 15)
value.Sync2Server = reader.ReadValue<bool>();
if (count > 16)
value.Version = reader.ReadValue<string>();
}
}
} }

View File

@@ -24,12 +24,12 @@ namespace linker.messenger.store.file.relay
} }
public void SetMaxGbTotalLastBytes(long value) public void SetMaxGbTotalLastBytes(long value)
{ {
config.Data.Server.Relay.Distributed.Node.MaxGbTotalLastBytes = value; config.Data.Server.Relay.Distributed.Node.DataRemain = value;
} }
public void SetMaxGbTotalMonth(int month) public void SetMaxGbTotalMonth(int month)
{ {
config.Data.Server.Relay.Distributed.Node.MaxGbTotalMonth = month; config.Data.Server.Relay.Distributed.Node.DataMonth = month;
} }