This commit is contained in:
snltty
2025-03-10 17:55:18 +08:00
parent 64cba16fe0
commit b3194212b4
20 changed files with 380 additions and 186 deletions

View File

@@ -2,6 +2,5 @@
declare (strict_types=1); declare (strict_types=1);
return [ return [
'STATUS' => '1', 'STATUS' => '0'
'KeyId' => 'FAFAB92C-DFDF-1221-DEA2-40A0E915EB10',
]; ];

View File

@@ -43,7 +43,7 @@ namespace linker.messenger.relay
return true; return true;
} }
public List<RelayServerNodeReportInfo> Subscribe(ApiControllerParamsInfo param) public List<RelayServerNodeReportInfo170> Subscribe(ApiControllerParamsInfo param)
{ {
relayTestTransfer.Subscribe(); relayTestTransfer.Subscribe();
return relayTestTransfer.Nodes; return relayTestTransfer.Nodes;

View File

@@ -18,7 +18,7 @@ namespace linker.messenger.relay
private readonly ISignInClientStore signInClientStore; private readonly ISignInClientStore signInClientStore;
private readonly IRelayClientStore relayClientStore; private readonly IRelayClientStore relayClientStore;
public List<RelayServerNodeReportInfo> Nodes { get; private set; } = new List<RelayServerNodeReportInfo>(); public List<RelayServerNodeReportInfo170> Nodes { get; private set; } = new List<RelayServerNodeReportInfo170>();
public RelayClientTestTransfer(RelayClientTransfer relayTransfer, SignInClientState signInClientState, ISignInClientStore signInClientStore, IRelayClientStore relayClientStore) public RelayClientTestTransfer(RelayClientTransfer relayTransfer, SignInClientState signInClientState, ISignInClientStore signInClientStore, IRelayClientStore relayClientStore)
{ {

View File

@@ -47,7 +47,7 @@ namespace linker.messenger.relay.client.transport
/// </summary> /// </summary>
/// <param name="relayTestInfo"></param> /// <param name="relayTestInfo"></param>
/// <returns></returns> /// <returns></returns>
public Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo170 relayTestInfo); public Task<List<RelayServerNodeReportInfo170>> RelayTestAsync(RelayTestInfo170 relayTestInfo);
} }
/// <summary> /// <summary>

View File

@@ -44,7 +44,7 @@ namespace linker.messenger.relay.client.transport
try try
{ {
//问一下能不能中继 //问一下能不能中继
RelayAskResultInfo relayAskResultInfo = await RelayAsk(relayInfo); RelayAskResultInfo170 relayAskResultInfo = await RelayAsk(relayInfo);
relayInfo.FlowingId = relayAskResultInfo.FlowingId; relayInfo.FlowingId = relayAskResultInfo.FlowingId;
if (relayInfo.FlowingId == 0 || relayAskResultInfo.Nodes.Count == 0) if (relayInfo.FlowingId == 0 || relayAskResultInfo.Nodes.Count == 0)
{ {
@@ -119,7 +119,7 @@ namespace linker.messenger.relay.client.transport
return null; return null;
} }
private async Task<RelayAskResultInfo> RelayAsk(RelayInfo170 relayInfo) private async Task<RelayAskResultInfo170> RelayAsk(RelayInfo170 relayInfo)
{ {
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
@@ -130,15 +130,15 @@ namespace linker.messenger.relay.client.transport
}).ConfigureAwait(false); }).ConfigureAwait(false);
if (resp.Code != MessageResponeCodes.OK) if (resp.Code != MessageResponeCodes.OK)
{ {
return new RelayAskResultInfo(); return new RelayAskResultInfo170();
} }
RelayAskResultInfo result = serializer.Deserialize<RelayAskResultInfo>(resp.Data.Span); RelayAskResultInfo170 result = serializer.Deserialize<RelayAskResultInfo170>(resp.Data.Span);
return result; return result;
} }
private async Task<Socket> ConnectNodeServer(RelayInfo170 relayInfo, List<RelayServerNodeReportInfo> nodes) private async Task<Socket> ConnectNodeServer(RelayInfo170 relayInfo, List<RelayServerNodeReportInfo170> nodes)
{ {
byte[] buffer = ArrayPool<byte>.Shared.Rent(1 * 1024); byte[] buffer = ArrayPool<byte>.Shared.Rent(1 * 1024);
@@ -306,7 +306,7 @@ namespace linker.messenger.relay.client.transport
return null; return null;
} }
public async Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo170 relayTestInfo) public async Task<List<RelayServerNodeReportInfo170>> RelayTestAsync(RelayTestInfo170 relayTestInfo)
{ {
try try
{ {
@@ -320,13 +320,13 @@ namespace linker.messenger.relay.client.transport
if (resp.Code == MessageResponeCodes.OK) if (resp.Code == MessageResponeCodes.OK)
{ {
return serializer.Deserialize<List<RelayServerNodeReportInfo>>(resp.Data.Span); return serializer.Deserialize<List<RelayServerNodeReportInfo170>>(resp.Data.Span);
} }
} }
catch (Exception) catch (Exception)
{ {
} }
return new List<RelayServerNodeReportInfo>(); return new List<RelayServerNodeReportInfo170>();
} }
} }
} }

View File

@@ -70,15 +70,22 @@ namespace linker.messenger.relay.messenger
public async Task RelayTest(IConnection connection) public async Task RelayTest(IConnection connection)
{ {
RelayTestInfo info = serializer.Deserialize<RelayTestInfo>(connection.ReceiveRequestWrap.Payload.Span); RelayTestInfo info = serializer.Deserialize<RelayTestInfo>(connection.ReceiveRequestWrap.Payload.Span);
await RelayTest(connection, info); await RelayTest(connection, info, (validated) =>
{
List<RelayServerNodeReportInfo> list = relayServerTransfer.GetNodes(validated).Select(c => (RelayServerNodeReportInfo)c).ToList();
return serializer.Serialize(list);
});
} }
[MessengerId((ushort)RelayMessengerIds.RelayTest170)] [MessengerId((ushort)RelayMessengerIds.RelayTest170)]
public async Task RelayTest170(IConnection connection) public async Task RelayTest170(IConnection connection)
{ {
RelayTestInfo170 info = serializer.Deserialize<RelayTestInfo170>(connection.ReceiveRequestWrap.Payload.Span); RelayTestInfo170 info = serializer.Deserialize<RelayTestInfo170>(connection.ReceiveRequestWrap.Payload.Span);
await RelayTest(connection, info); await RelayTest(connection, info, (validated) =>
{
return serializer.Serialize(relayServerTransfer.GetNodes(validated));
});
} }
private async Task RelayTest(IConnection connection, RelayTestInfo info) private async Task RelayTest(IConnection connection, RelayTestInfo info, Func<bool, byte[]> data)
{ {
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false) if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{ {
@@ -94,8 +101,7 @@ namespace linker.messenger.relay.messenger
TransportName = "test", TransportName = "test",
}, cache, null); }, cache, null);
var nodes = relayServerTransfer.GetNodes(string.IsNullOrWhiteSpace(result)); connection.Write(data(string.IsNullOrWhiteSpace(result)));
connection.Write(serializer.Serialize(nodes));
} }
/// <summary> /// <summary>
@@ -106,18 +112,6 @@ namespace linker.messenger.relay.messenger
public async Task RelayAsk(IConnection connection) public async Task RelayAsk(IConnection connection)
{ {
RelayInfo info = serializer.Deserialize<RelayInfo>(connection.ReceiveRequestWrap.Payload.Span); RelayInfo info = serializer.Deserialize<RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
await RelayAsk(connection, info, new List<RelayServerCdkeyInfo>());
}
[MessengerId((ushort)RelayMessengerIds.RelayAsk170)]
public async Task RelayAsk170(IConnection connection)
{
RelayInfo170 info = serializer.Deserialize<RelayInfo170>(connection.ReceiveRequestWrap.Payload.Span);
List<RelayServerCdkeyInfo> cdkeys = (await relayServerCdkeyStore.GetAvailable(info.UserId)).Select(c => new RelayServerCdkeyInfo { Bandwidth = c.Bandwidth, CdkeyId = c.CdkeyId, LastBytes = c.LastBytes }).ToList();
await RelayAsk(connection, info, cdkeys);
}
public async Task RelayAsk(IConnection connection, RelayInfo info, List<RelayServerCdkeyInfo> cdkeys)
{
if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId) if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId)
{ {
connection.Write(serializer.Serialize(new RelayAskResultInfo { })); connection.Write(serializer.Serialize(new RelayAskResultInfo { }));
@@ -132,10 +126,39 @@ namespace linker.messenger.relay.messenger
RelayAskResultInfo result = new RelayAskResultInfo(); RelayAskResultInfo result = new RelayAskResultInfo();
string error = await relayValidatorTransfer.Validate(info, cacheFrom, cacheTo); string error = await relayValidatorTransfer.Validate(info, cacheFrom, cacheTo);
bool validated = string.IsNullOrWhiteSpace(error); bool validated = string.IsNullOrWhiteSpace(error);
result.Nodes = relayServerTransfer.GetNodes(validated).Select(c => (RelayServerNodeReportInfo)c).ToList();
if (result.Nodes.Count > 0)
{
result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId, validated, new List<RelayServerCdkeyInfo>());
}
connection.Write(serializer.Serialize(result));
}
[MessengerId((ushort)RelayMessengerIds.RelayAsk170)]
public async Task RelayAsk170(IConnection connection)
{
RelayInfo170 info = serializer.Deserialize<RelayInfo170>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId)
{
connection.Write(serializer.Serialize(new RelayAskResultInfo170 { }));
return;
}
info.RemoteMachineId = cacheTo.MachineId;
info.FromMachineId = cacheFrom.MachineId;
info.RemoteMachineName = cacheTo.MachineName;
info.FromMachineName = cacheFrom.MachineName;
RelayAskResultInfo170 result = new RelayAskResultInfo170();
string error = await relayValidatorTransfer.Validate(info, cacheFrom, cacheTo);
bool validated = string.IsNullOrWhiteSpace(error);
result.Nodes = relayServerTransfer.GetNodes(validated); result.Nodes = relayServerTransfer.GetNodes(validated);
if (result.Nodes.Count > 0) if (result.Nodes.Count > 0)
{ {
List<RelayServerCdkeyInfo> cdkeys = (await relayServerCdkeyStore.GetAvailable(info.UserId)).Select(c => new RelayServerCdkeyInfo { Bandwidth = c.Bandwidth, CdkeyId = c.CdkeyId, LastBytes = c.LastBytes }).ToList();
result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId, validated, cdkeys); result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId, validated, cdkeys);
} }
@@ -240,7 +263,7 @@ namespace linker.messenger.relay.messenger
[MessengerId((ushort)RelayMessengerIds.NodeReport)] [MessengerId((ushort)RelayMessengerIds.NodeReport)]
public void NodeReport(IConnection connection) public void NodeReport(IConnection connection)
{ {
RelayServerNodeReportInfo info = serializer.Deserialize<RelayServerNodeReportInfo>(connection.ReceiveRequestWrap.Payload.Span); RelayServerNodeReportInfo170 info = serializer.Deserialize<RelayServerNodeReportInfo170>(connection.ReceiveRequestWrap.Payload.Span);
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{ {
LoggerHelper.Instance.Debug($"relay node report : {info.ToJson()}"); LoggerHelper.Instance.Debug($"relay node report : {info.ToJson()}");
@@ -287,17 +310,26 @@ namespace linker.messenger.relay.messenger
/// <param name="connection"></param> /// <param name="connection"></param>
/// <returns></returns> /// <returns></returns>
[MessengerId((ushort)RelayMessengerIds.TrafficReport)] [MessengerId((ushort)RelayMessengerIds.TrafficReport)]
public async Task TrafficReport(IConnection connection) public void TrafficReport(IConnection connection)
{ {
RelayTrafficUpdateInfo info = serializer.Deserialize<RelayTrafficUpdateInfo>(connection.ReceiveRequestWrap.Payload.Span); RelayTrafficUpdateInfo info = serializer.Deserialize<RelayTrafficUpdateInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (relayServerStore.SecretKey != info.SecretKey) if (relayServerStore.SecretKey != info.SecretKey)
{ {
connection.Write(serializer.Serialize(new Dictionary<string, long>()));
return; return;
} }
Dictionary<long, long> result = await relayServerTransfer.AddTraffic(info); relayServerTransfer.AddTraffic(info.Dic);
connection.Write(serializer.Serialize(result));
} }
/// <summary>
/// 下发剩余流量
/// </summary>
/// <param name="connection"></param>
[MessengerId((ushort)RelayMessengerIds.SendLastBytes)]
public void SendLastBytes(IConnection connection)
{
Dictionary<long, long> info = serializer.Deserialize<Dictionary<long,long>>(connection.ReceiveRequestWrap.Payload.Span);
relayServerNodeTransfer.UpdateLastBytes(info);
}
/// <summary> /// <summary>

View File

@@ -35,6 +35,8 @@
RelayAsk170 = 2120, RelayAsk170 = 2120,
RelayForward170 = 2121, RelayForward170 = 2121,
SendLastBytes = 2122,
Max = 2199 Max = 2199
} }
} }

View File

@@ -1,4 +1,7 @@
namespace linker.messenger.relay.server using linker.libs;
using System.Net;
namespace linker.messenger.relay.server
{ {
public interface IRelayServerCdkeyStore public interface IRelayServerCdkeyStore
{ {
@@ -54,6 +57,12 @@
/// <returns></returns> /// <returns></returns>
public Task<bool> Traffic(Dictionary<long, long> dic); public Task<bool> Traffic(Dictionary<long, long> dic);
/// <summary> /// <summary>
/// 获取剩余流量
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public Task<Dictionary<long, long>> GetLastBytes(List<long> ids);
/// <summary>
/// 分页 /// 分页
/// </summary> /// </summary>
/// <param name="relayServerCdkeyPageRequestInfo"></param> /// <param name="relayServerCdkeyPageRequestInfo"></param>
@@ -66,7 +75,11 @@
/// <summary> /// <summary>
/// 加解密密钥 /// 加解密密钥
/// </summary> /// </summary>
#if DEBUG
public string SecretKey { get; set; } = Helper.GlobalString;
#else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper(); public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif
} }
public sealed partial class RelayServerCdkeyPageRequestInfo public sealed partial class RelayServerCdkeyPageRequestInfo

View File

@@ -103,7 +103,7 @@ namespace linker.messenger.relay.server
public string Url { get; set; } = "https://linker-doc.snltty.com"; public string Url { get; set; } = "https://linker-doc.snltty.com";
} }
public sealed partial class RelayServerNodeReportInfo public partial class RelayServerNodeReportInfo
{ {
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;
@@ -124,7 +124,9 @@ namespace linker.messenger.relay.server
public IPEndPoint EndPoint { get; set; } public IPEndPoint EndPoint { get; set; }
public long LastTicks { get; set; } public long LastTicks { get; set; }
}
public sealed partial class RelayServerNodeReportInfo170: RelayServerNodeReportInfo
{
public string Url { get; set; } = "https://linker-doc.snltty.com"; public string Url { get; set; } = "https://linker-doc.snltty.com";
[JsonIgnore] [JsonIgnore]
@@ -138,4 +140,10 @@ namespace linker.messenger.relay.server
public List<RelayServerNodeReportInfo> Nodes { get; set; } = new List<RelayServerNodeReportInfo>(); public List<RelayServerNodeReportInfo> Nodes { get; set; } = new List<RelayServerNodeReportInfo>();
} }
public sealed partial class RelayAskResultInfo170
{
public ulong FlowingId { get; set; }
public List<RelayServerNodeReportInfo170> Nodes { get; set; } = new List<RelayServerNodeReportInfo170>();
}
} }

View File

@@ -13,8 +13,9 @@ namespace linker.messenger.relay.server
{ {
private ulong relayFlowingId = 0; private ulong relayFlowingId = 0;
private readonly ConcurrentDictionary<string, RelayServerNodeReportInfo> reports = new ConcurrentDictionary<string, RelayServerNodeReportInfo>(); private readonly ConcurrentDictionary<string, RelayServerNodeReportInfo170> reports = new ConcurrentDictionary<string, RelayServerNodeReportInfo170>();
private readonly ConcurrentQueue<Dictionary<long, long>> trafficQueue = new ConcurrentQueue<Dictionary<long, long>>(); private readonly ConcurrentQueue<Dictionary<long, long>> trafficQueue = new ConcurrentQueue<Dictionary<long, long>>();
private readonly ConcurrentQueue<List<long>> trafficIdsQueue = new ConcurrentQueue<List<long>>();
private readonly IRelayServerCaching relayCaching; private readonly IRelayServerCaching relayCaching;
private readonly ISerializer serializer; private readonly ISerializer serializer;
@@ -61,7 +62,7 @@ namespace linker.messenger.relay.server
/// </summary> /// </summary>
/// <param name="ep"></param> /// <param name="ep"></param>
/// <param name="data"></param> /// <param name="data"></param>
public void SetNodeReport(IConnection connection, RelayServerNodeReportInfo info) public void SetNodeReport(IConnection connection, RelayServerNodeReportInfo170 info)
{ {
try try
{ {
@@ -93,7 +94,7 @@ namespace linker.messenger.relay.server
{ {
if (RelayServerNodeInfo.MASTER_NODE_ID == info.Id) return; if (RelayServerNodeInfo.MASTER_NODE_ID == info.Id) return;
if (reports.TryGetValue(info.Id, out RelayServerNodeReportInfo cache)) if (reports.TryGetValue(info.Id, out RelayServerNodeReportInfo170 cache))
{ {
await messengerSender.SendOnly(new MessageRequestWrap await messengerSender.SendOnly(new MessageRequestWrap
{ {
@@ -109,7 +110,7 @@ namespace linker.messenger.relay.server
/// </summary> /// </summary>
/// <param name="validated">是否已认证</param> /// <param name="validated">是否已认证</param>
/// <returns></returns> /// <returns></returns>
public List<RelayServerNodeReportInfo> GetNodes(bool validated) public List<RelayServerNodeReportInfo170> GetNodes(bool validated)
{ {
var result = reports.Values var result = reports.Values
.Where(c => c.Public || validated) .Where(c => c.Public || validated)
@@ -134,7 +135,7 @@ namespace linker.messenger.relay.server
/// <returns></returns> /// <returns></returns>
public bool NodeValidate(string nodeId) public bool NodeValidate(string nodeId)
{ {
return reports.TryGetValue(nodeId, out RelayServerNodeReportInfo relayNodeReportInfo) && relayNodeReportInfo.Public == false; return reports.TryGetValue(nodeId, out RelayServerNodeReportInfo170 relayNodeReportInfo) && relayNodeReportInfo.Public == false;
} }
/// <summary> /// <summary>
@@ -142,16 +143,10 @@ namespace linker.messenger.relay.server
/// </summary> /// </summary>
/// <param name="relayTrafficUpdateInfo"></param> /// <param name="relayTrafficUpdateInfo"></param>
/// <returns></returns> /// <returns></returns>
public async Task<Dictionary<long, long>> AddTraffic(RelayTrafficUpdateInfo relayTrafficUpdateInfo) public void AddTraffic(Dictionary<long,long> dic)
{ {
if (relayTrafficUpdateInfo.Dic.Count > 0) if (dic.Count > 0)
trafficQueue.Enqueue(relayTrafficUpdateInfo.Dic); trafficQueue.Enqueue(dic);
if (relayTrafficUpdateInfo.Ids == null || relayTrafficUpdateInfo.Ids.Count == 0)
{
return new Dictionary<long, long>();
}
return (await relayServerCdkeyStore.Get(relayTrafficUpdateInfo.Ids)).ToDictionary(c => c.CdkeyId, c => c.LastBytes);
} }
private void TrafficTask() private void TrafficTask()
{ {
@@ -159,10 +154,50 @@ namespace linker.messenger.relay.server
{ {
while (trafficQueue.TryDequeue(out Dictionary<long, long> dic)) while (trafficQueue.TryDequeue(out Dictionary<long, long> dic))
{ {
await relayServerCdkeyStore.Traffic(dic).ConfigureAwait(false); try
{
await relayServerCdkeyStore.Traffic(dic).ConfigureAwait(false);
var ids = dic.Keys.ToList();
while (ids.Count > 0)
{
var id = ids.Take(100).ToList();
trafficIdsQueue.Enqueue(id);
ids.RemoveRange(0, id.Count);
}
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
} }
return true; return true;
}, 3000); }, 500);
TimerHelper.SetIntervalLong(async () =>
{
while (trafficIdsQueue.TryDequeue(out List<long> ids))
{
try
{
Dictionary<long, long> id2last = await relayServerCdkeyStore.GetLastBytes(ids).ConfigureAwait(false);
if (id2last.Count == 0) continue;
byte[] bytes = serializer.Serialize(id2last);
await Task.WhenAll(reports.Values.Select(c => messengerSender.SendOnly(new MessageRequestWrap
{
Connection = c.Connection,
MessengerId = (ushort)RelayMessengerIds.SendLastBytes,
Payload = bytes,
})).ToList());
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
}
return true;
}, 500);
} }
} }
} }

View File

@@ -13,7 +13,7 @@ namespace linker.messenger.relay.server
/// </summary> /// </summary>
public class RelayServerNodeTransfer public class RelayServerNodeTransfer
{ {
public string Id=>relayServerNodeStore.Node.Id; public string Id => relayServerNodeStore.Node.Id;
private uint connectionNum = 0; private uint connectionNum = 0;
private IConnection localConnection; private IConnection localConnection;
@@ -23,7 +23,6 @@ namespace linker.messenger.relay.server
private long lastBytes = 0; private long lastBytes = 0;
private RelaySpeedLimit limitTotal = new RelaySpeedLimit(); private RelaySpeedLimit limitTotal = new RelaySpeedLimit();
private readonly ConcurrentDictionary<ulong, RelayTrafficCacheInfo> trafficDict = new ConcurrentDictionary<ulong, RelayTrafficCacheInfo>(); private readonly ConcurrentDictionary<ulong, RelayTrafficCacheInfo> trafficDict = new ConcurrentDictionary<ulong, RelayTrafficCacheInfo>();
private readonly ConcurrentDictionary<long, long> cdkeyLastBytes = new ConcurrentDictionary<long, long>();
private readonly ISerializer serializer; private readonly ISerializer serializer;
private readonly IRelayServerNodeStore relayServerNodeStore; private readonly IRelayServerNodeStore relayServerNodeStore;
@@ -169,10 +168,6 @@ namespace linker.messenger.relay.server
public void RemoveTrafficCache(RelayTrafficCacheInfo relayCache) public void RemoveTrafficCache(RelayTrafficCacheInfo relayCache)
{ {
trafficDict.TryRemove(relayCache.Cache.FlowId, out _); trafficDict.TryRemove(relayCache.Cache.FlowId, out _);
foreach (var item in relayCache.Cache.Cdkey)
{
cdkeyLastBytes.TryRemove(item.CdkeyId, out _);
}
} }
/// <summary> /// <summary>
/// 消耗流量 /// 消耗流量
@@ -211,23 +206,40 @@ namespace linker.messenger.relay.server
RelayServerCdkeyInfo currentCdkey = relayCache.Cache.Cdkey.Where(c => c.LastBytes > 0).OrderByDescending(c => c.Bandwidth).FirstOrDefault(); RelayServerCdkeyInfo currentCdkey = relayCache.Cache.Cdkey.Where(c => c.LastBytes > 0).OrderByDescending(c => c.Bandwidth).FirstOrDefault();
//有cdkey且带宽大于节点带宽就用cdkey的带宽 //有cdkey且带宽大于节点带宽就用cdkey的带宽
if (currentCdkey != null && (currentCdkey.Bandwidth == 0 || currentCdkey.Bandwidth > relayServerNodeStore.Node.MaxBandwidth)) if (currentCdkey != null && (currentCdkey.Bandwidth == 0 || currentCdkey.Bandwidth >= relayServerNodeStore.Node.MaxBandwidth || relayServerNodeStore.Node.MaxGbTotalLastBytes == 0))
{ {
relayCache.CurrentCdkey = currentCdkey; relayCache.CurrentCdkey = currentCdkey;
relayCache.Limit.SetLimit((uint)Math.Ceiling((relayCache.CurrentCdkey.Bandwidth * 1024 * 1024) / 8.0)); relayCache.Limit.SetLimit((uint)Math.Ceiling((relayCache.CurrentCdkey.Bandwidth * 1024 * 1024) / 8.0));
return; return;
} }
relayCache.CurrentCdkey = null; relayCache.CurrentCdkey = null;
relayCache.Limit.SetLimit((uint)Math.Ceiling((relayServerNodeStore.Node.MaxBandwidth * 1024 * 1024) / 8.0)); relayCache.Limit.SetLimit((uint)Math.Ceiling((relayServerNodeStore.Node.MaxBandwidth * 1024 * 1024) / 8.0));
} }
/// <summary>
/// 更新剩余流量
/// </summary>
/// <param name="dic"></param>
public void UpdateLastBytes(Dictionary<long, long> dic)
{
if (dic.Count == 0) return;
Dictionary<long, RelayServerCdkeyInfo> cdkeys = trafficDict.Values.SelectMany(c => c.Cache.Cdkey).ToDictionary(c => c.CdkeyId, c => c);
//更新剩余流量
foreach (KeyValuePair<long, long> item in dic)
{
if (cdkeys.TryGetValue(item.Key, out RelayServerCdkeyInfo info))
{
info.LastBytes = item.Value;
}
}
}
private void ResetNodeBytes() private void ResetNodeBytes()
{ {
foreach (var cache in trafficDict.Values.Where(c => c.CurrentCdkey == null)) foreach (var cache in trafficDict.Values.Where(c => c.CurrentCdkey == null))
{ {
long length = cache.Sendt; long length = Interlocked.Exchange(ref cache.Sendt, 0);
Interlocked.Exchange(ref cache.Sendt, 0);
if (relayServerNodeStore.Node.MaxGbTotalLastBytes >= length) if (relayServerNodeStore.Node.MaxGbTotalLastBytes >= length)
relayServerNodeStore.SetMaxGbTotalLastBytes(relayServerNodeStore.Node.MaxGbTotalLastBytes - length); relayServerNodeStore.SetMaxGbTotalLastBytes(relayServerNodeStore.Node.MaxGbTotalLastBytes - length);
else relayServerNodeStore.SetMaxGbTotalLastBytes(0); else relayServerNodeStore.SetMaxGbTotalLastBytes(0);
@@ -239,106 +251,56 @@ namespace linker.messenger.relay.server
} }
relayServerNodeStore.Confirm(); relayServerNodeStore.Confirm();
} }
private void DownloadBytes() private async Task UploadBytes()
{ {
TimerHelper.Async(async () => var cdkeys = trafficDict.Values.Where(c => c.CurrentCdkey != null && c.Sendt > 0).ToList();
{ Dictionary<long, long> id2sent = cdkeys.GroupBy(c => c.CurrentCdkey.CdkeyId).ToDictionary(c => c.Key, d => d.Sum(d => { d.SendtCache = d.Sendt; return d.SendtCache; }));
List<long> ids = trafficDict.Values.SelectMany(c => c.Cache.Cdkey).Select(c => c.CdkeyId).Distinct().ToList(); if (id2sent.Count == 0) return;
while (ids.Count > 0)
{
//分批更新,可能数量很大
List<long> id = ids.Take(100).ToList();
ids.RemoveRange(0, id.Count);
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap bool result = await messengerSender.SendOnly(new MessageRequestWrap
{ {
Connection = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection, Connection = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection,
MessengerId = (ushort)RelayMessengerIds.TrafficReport, MessengerId = (ushort)RelayMessengerIds.TrafficReport,
Payload = serializer.Serialize(new RelayTrafficUpdateInfo Payload = serializer.Serialize(new RelayTrafficUpdateInfo
{ {
Dic = [], Dic = id2sent,
Ids = id, SecretKey = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID
SecretKey = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID
? relayServerMasterStore.Master.SecretKey ? relayServerMasterStore.Master.SecretKey
: relayServerNodeStore.Node.MasterSecretKey : relayServerNodeStore.Node.MasterSecretKey
}), }),
Timeout = 4000 Timeout = 4000
});
if (resp.Code == MessageResponeCodes.OK && resp.Data.Length > 0)
{
Dictionary<long, long> dic = serializer.Deserialize<Dictionary<long, long>>(resp.Data.Span);
//更新剩余流量
foreach (KeyValuePair<long, long> item in dic)
{
cdkeyLastBytes.AddOrUpdate(item.Key, item.Value, (a, b) => item.Value);
}
//查不到的,归零
foreach (long item in id.Except(dic.Keys))
{
cdkeyLastBytes.AddOrUpdate(item, 0, (a, b) => 0);
}
}
}
}); });
}
private void UploadBytes() if (result)
{
TimerHelper.Async(async () =>
{ {
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap //成功报告了流量,就重新计数
foreach (var cache in cdkeys)
{ {
Connection = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection, Interlocked.Add(ref cache.Sendt, -cache.SendtCache);
MessengerId = (ushort)RelayMessengerIds.TrafficReport, Interlocked.Exchange(ref cache.SendtCache, 0);
Payload = serializer.Serialize(new RelayTrafficUpdateInfo //当前cdkey流量用完了就重新找找新的cdkey
{ if (cache.CurrentCdkey.LastBytes <= 0)
Dic = trafficDict.Values.Where(c => c.CurrentCdkey != null && c.Sendt > 0).GroupBy(c => c.CurrentCdkey.CdkeyId).ToDictionary(c => c.Key, d => d.Sum(d => d.Sendt)),
Ids = [],
SecretKey = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID
? relayServerMasterStore.Master.SecretKey
: relayServerNodeStore.Node.MasterSecretKey
}),
Timeout = 4000
});
if (resp.Code == MessageResponeCodes.OK)
{
try
{
serializer.Deserialize<Dictionary<string, ulong>>(resp.Data.Span);
//成功报告了流量,就重新计数
foreach (var cache in trafficDict.Values.Where(c => c.CurrentCdkey != null))
{
Interlocked.Exchange(ref cache.Sendt, 0);
//检查一下是不是需要更新剩余流量
if (cdkeyLastBytes.TryGetValue(cache.CurrentCdkey.CdkeyId, out long value))
{
cache.CurrentCdkey.LastBytes = value;
}
//当前cdkey流量用完了就重新找找新的cdkey
if (cache.CurrentCdkey.LastBytes <= 0)
{
SetLimit(cache);
}
}
}
catch (Exception)
{ {
SetLimit(cache);
} }
} }
}); }
} }
private void TrafficTask() private void TrafficTask()
{ {
TimerHelper.SetIntervalLong(() => TimerHelper.SetIntervalLong(async () =>
{ {
UploadBytes(); try
DownloadBytes(); {
ResetNodeBytes();
ResetNodeBytes(); await UploadBytes();
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
return true; return true;
}, 5000); }, 3000);
} }
private void ReportTask() private void ReportTask()
@@ -377,7 +339,7 @@ namespace linker.messenger.relay.server
IConnection connection = node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection; IConnection connection = node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection;
IPEndPoint endPoint = await NetworkHelper.GetEndPointAsync(node.Host, relayServerNodeStore.ServicePort) ?? new IPEndPoint(IPAddress.Any, relayServerNodeStore.ServicePort); IPEndPoint endPoint = await NetworkHelper.GetEndPointAsync(node.Host, relayServerNodeStore.ServicePort) ?? new IPEndPoint(IPAddress.Any, relayServerNodeStore.ServicePort);
RelayServerNodeReportInfo relayNodeReportInfo = new RelayServerNodeReportInfo RelayServerNodeReportInfo170 relayNodeReportInfo = new RelayServerNodeReportInfo170
{ {
Id = node.Id, Id = node.Id,
Name = node.Name, Name = node.Name,
@@ -389,7 +351,8 @@ namespace linker.messenger.relay.server
MaxGbTotalLastBytes = node.MaxGbTotalLastBytes, MaxGbTotalLastBytes = node.MaxGbTotalLastBytes,
MaxConnection = node.MaxConnection, MaxConnection = node.MaxConnection,
ConnectionRatio = Math.Round(connectionNum / 2.0), ConnectionRatio = Math.Round(connectionNum / 2.0),
EndPoint = endPoint EndPoint = endPoint,
Url = node.Url
}; };
await messengerSender.SendOnly(new MessageRequestWrap await messengerSender.SendOnly(new MessageRequestWrap
@@ -465,10 +428,6 @@ namespace linker.messenger.relay.server
/// cdkey id 和 流量 /// cdkey id 和 流量
/// </summary> /// </summary>
public Dictionary<long, long> Dic { get; set; } public Dictionary<long, long> Dic { get; set; }
/// <summary>
/// 需要知道哪些cdkey的剩余流量
/// </summary>
public List<long> Ids { get; set; }
public string SecretKey { get; set; } public string SecretKey { get; set; }
} }

View File

@@ -104,9 +104,14 @@ namespace linker.messenger.relay.server
} }
relayWrap.Tcs.SetResult(); relayWrap.Tcs.SetResult();
RelaySpeedLimit limit = new RelaySpeedLimit(); RelayTrafficCacheInfo trafficCacheInfo = new RelayTrafficCacheInfo { Cache = relayCache, Sendt = 0, Limit = new RelaySpeedLimit() };
_ = CopyToAsync(relayCache, limit, socket, relayWrap.Socket); relayServerNodeTransfer.AddTrafficCache(trafficCacheInfo);
_ = CopyToAsync(relayCache, limit, relayWrap.Socket, socket); relayServerNodeTransfer.IncrementConnectionNum();
_ = Task.WhenAll(CopyToAsync(trafficCacheInfo, socket, relayWrap.Socket), CopyToAsync(trafficCacheInfo, relayWrap.Socket, socket)).ContinueWith((result) =>
{
relayServerNodeTransfer.DecrementConnectionNum();
relayServerNodeTransfer.RemoveTrafficCache(trafficCacheInfo);
});
} }
break; break;
default: default:
@@ -139,15 +144,11 @@ namespace linker.messenger.relay.server
ArrayPool<byte>.Shared.Return(buffer); ArrayPool<byte>.Shared.Return(buffer);
} }
} }
private async Task CopyToAsync(RelayCacheInfo cache, RelaySpeedLimit limit, Socket source, Socket destination) private async Task CopyToAsync(RelayTrafficCacheInfo trafficCacheInfo, Socket source, Socket destination)
{ {
RelayTrafficCacheInfo trafficCacheInfo = new RelayTrafficCacheInfo { Cache = cache, Sendt = 0, Limit = limit };
byte[] buffer = new byte[8 * 1024]; byte[] buffer = new byte[8 * 1024];
try try
{ {
relayServerNodeTransfer.IncrementConnectionNum();
relayServerNodeTransfer.AddTrafficCache(trafficCacheInfo);
int bytesRead; int bytesRead;
while ((bytesRead = await source.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).ConfigureAwait(false)) != 0) while ((bytesRead = await source.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).ConfigureAwait(false)) != 0)
{ {
@@ -170,19 +171,19 @@ namespace linker.messenger.relay.server
} }
} }
//单个速度 //单个速度
if (limit.NeedLimit()) if (trafficCacheInfo.Limit.NeedLimit())
{ {
int length = bytesRead; int length = bytesRead;
limit.TryLimit(ref length); trafficCacheInfo.Limit.TryLimit(ref length);
while (length > 0) while (length > 0)
{ {
await Task.Delay(30).ConfigureAwait(false); await Task.Delay(30).ConfigureAwait(false);
limit.TryLimit(ref length); trafficCacheInfo.Limit.TryLimit(ref length);
} }
} }
AddReceive(cache.FromId, cache.FromName, cache.ToName, cache.GroupId, bytesRead); AddReceive(trafficCacheInfo.Cache.FromId, trafficCacheInfo.Cache.FromName, trafficCacheInfo.Cache.ToName, trafficCacheInfo.Cache.GroupId, bytesRead);
AddSendt(cache.FromId, cache.FromName, cache.ToName, cache.GroupId, bytesRead); AddSendt(trafficCacheInfo.Cache.FromId, trafficCacheInfo.Cache.FromName, trafficCacheInfo.Cache.ToName, trafficCacheInfo.Cache.GroupId, bytesRead);
await destination.SendAsync(buffer.AsMemory(0, bytesRead), SocketFlags.None).ConfigureAwait(false); await destination.SendAsync(buffer.AsMemory(0, bytesRead), SocketFlags.None).ConfigureAwait(false);
} }
} }
@@ -191,8 +192,6 @@ namespace linker.messenger.relay.server
} }
finally finally
{ {
relayServerNodeTransfer.DecrementConnectionNum();
relayServerNodeTransfer.RemoveTrafficCache(trafficCacheInfo);
source.SafeClose(); source.SafeClose();
destination.SafeClose(); destination.SafeClose();
} }
@@ -264,6 +263,7 @@ namespace linker.messenger.relay.server
public sealed class RelayTrafficCacheInfo public sealed class RelayTrafficCacheInfo
{ {
public long Sendt; public long Sendt;
public long SendtCache;
public RelaySpeedLimit Limit { get; set; } public RelaySpeedLimit Limit { get; set; }
public RelayCacheInfo Cache { get; set; } public RelayCacheInfo Cache { get; set; }
public RelayServerCdkeyInfo CurrentCdkey { get; set; } public RelayServerCdkeyInfo CurrentCdkey { get; set; }

View File

@@ -55,7 +55,9 @@ namespace linker.messenger.serializer.memorypack
MemoryPackFormatterProvider.Register(new RelayInfo170Formatter()); MemoryPackFormatterProvider.Register(new RelayInfo170Formatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfo170Formatter());
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayAskResultInfo170Formatter());
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerCdkeyInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayServerCdkeyInfoFormatter());

View File

@@ -456,8 +456,6 @@ namespace linker.messenger.serializer.memorypack
IPEndPoint EndPoint => info.EndPoint; IPEndPoint EndPoint => info.EndPoint;
[MemoryPackInclude] [MemoryPackInclude]
long LastTicks => info.LastTicks; long LastTicks => info.LastTicks;
[MemoryPackInclude]
string Url => info.Url;
[MemoryPackConstructor] [MemoryPackConstructor]
@@ -467,7 +465,7 @@ namespace linker.messenger.serializer.memorypack
double maxGbTotal, long maxGbTotalLastBytes, double maxGbTotal, long maxGbTotalLastBytes,
double connectionRatio, double bandwidthRatio, double connectionRatio, double bandwidthRatio,
bool Public, int delay, bool Public, int delay,
IPEndPoint endPoint, long lastTicks, string url) IPEndPoint endPoint, long lastTicks)
{ {
var info = new RelayServerNodeReportInfo var info = new RelayServerNodeReportInfo
{ {
@@ -483,8 +481,7 @@ namespace linker.messenger.serializer.memorypack
MaxGbTotal = maxGbTotal, MaxGbTotal = maxGbTotal,
MaxGbTotalLastBytes = maxGbTotalLastBytes, MaxGbTotalLastBytes = maxGbTotalLastBytes,
Name = name, Name = name,
Public = Public, Public = Public
Url = url
}; };
this.info = info; this.info = info;
} }
@@ -521,7 +518,102 @@ namespace linker.messenger.serializer.memorypack
} }
} }
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeReportInfo170
{
[MemoryPackIgnore]
public readonly RelayServerNodeReportInfo170 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;
[MemoryPackConstructor]
SerializableRelayServerNodeReportInfo170(
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)
{
var info = new RelayServerNodeReportInfo170
{
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
};
this.info = info;
}
public SerializableRelayServerNodeReportInfo170(RelayServerNodeReportInfo170 info)
{
this.info = info;
}
}
public class RelayServerNodeReportInfo170Formatter : MemoryPackFormatter<RelayServerNodeReportInfo170>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeReportInfo170 value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerNodeReportInfo170(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeReportInfo170 value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerNodeReportInfo170>();
value = wrapped.info;
}
}
[MemoryPackable] [MemoryPackable]
@@ -576,6 +668,57 @@ namespace linker.messenger.serializer.memorypack
[MemoryPackable]
public readonly partial struct SerializableRelayAskResultInfo170
{
[MemoryPackIgnore]
public readonly RelayAskResultInfo170 info;
[MemoryPackInclude]
ulong FlowingId => info.FlowingId;
[MemoryPackInclude]
List<RelayServerNodeReportInfo170> Nodes => info.Nodes;
[MemoryPackConstructor]
SerializableRelayAskResultInfo170(ulong flowingId, List<RelayServerNodeReportInfo170> nodes)
{
var info = new RelayAskResultInfo170 { FlowingId = flowingId, Nodes = nodes };
this.info = info;
}
public SerializableRelayAskResultInfo170(RelayAskResultInfo170 info)
{
this.info = info;
}
}
public class RelayAskResultInfo170Formatter : MemoryPackFormatter<RelayAskResultInfo170>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayAskResultInfo170 value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayAskResultInfo170(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayAskResultInfo170 value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayAskResultInfo170>();
value = wrapped.info;
}
}
[MemoryPackable] [MemoryPackable]
public readonly partial struct SerializableRelayCacheInfo public readonly partial struct SerializableRelayCacheInfo
@@ -1150,17 +1293,14 @@ namespace linker.messenger.serializer.memorypack
[MemoryPackInclude] [MemoryPackInclude]
Dictionary<long, long> Dic => info.Dic; Dictionary<long, long> Dic => info.Dic;
[MemoryPackInclude] [MemoryPackInclude]
List<long> Ids => info.Ids;
[MemoryPackInclude]
string SecretKey => info.SecretKey; string SecretKey => info.SecretKey;
[MemoryPackConstructor] [MemoryPackConstructor]
SerializableRelayTrafficUpdateInfo(Dictionary<long, long> dic, List<long> ids, string secretKey) SerializableRelayTrafficUpdateInfo(Dictionary<long, long> dic, string secretKey)
{ {
var info = new RelayTrafficUpdateInfo var info = new RelayTrafficUpdateInfo
{ {
Dic = dic, Dic = dic,
Ids = ids,
SecretKey = secretKey SecretKey = secretKey
}; };
this.info = info; this.info = info;

View File

@@ -168,10 +168,14 @@ namespace linker.messenger.store.file.relay
} }
return await Task.FromResult(true); return await Task.FromResult(true);
} }
public async Task<Dictionary<long,long>> GetLastBytes(List<long> ids)
{
return await Task.FromResult(liteCollection.Find(c => ids.Contains(c.CdkeyId)).ToDictionary(c => c.CdkeyId, c => c.LastBytes));
}
public async Task<List<RelayServerCdkeyStoreInfo>> GetAvailable(string userid) public async Task<List<RelayServerCdkeyStoreInfo>> GetAvailable(string userid)
{ {
return await Task.FromResult(liteCollection.Find(x => x.UserId == userid && x.LastBytes > 0 && x.StartTime <= DateTime.Now && x.EndTime < DateTime.Now && x.Deleted == false).ToList()); return await Task.FromResult(liteCollection.Find(x => x.UserId == userid && x.LastBytes > 0 && x.StartTime <= DateTime.Now && x.EndTime >= DateTime.Now && x.Deleted == false).ToList());
} }
public async Task<List<RelayServerCdkeyStoreInfo>> Get(List<long> ids) public async Task<List<RelayServerCdkeyStoreInfo>> Get(List<long> ids)
{ {
@@ -184,11 +188,11 @@ namespace linker.messenger.store.file.relay
if (info.Flag.HasFlag(RelayServerCdkeyPageRequestFlag.TimeIn)) if (info.Flag.HasFlag(RelayServerCdkeyPageRequestFlag.TimeIn))
{ {
query = query.Where(x => x.EndTime > DateTime.Now); query = query.Where(x => x.StartTime <= DateTime.Now && x.EndTime >= DateTime.Now);
} }
if (info.Flag.HasFlag(RelayServerCdkeyPageRequestFlag.TimeOut)) if (info.Flag.HasFlag(RelayServerCdkeyPageRequestFlag.TimeOut))
{ {
query = query.Where(x => x.EndTime < DateTime.Now); query = query.Where(x =>x.StartTime > DateTime.Now || x.EndTime < DateTime.Now);
} }
if (info.Flag.HasFlag(RelayServerCdkeyPageRequestFlag.BytesIn)) if (info.Flag.HasFlag(RelayServerCdkeyPageRequestFlag.BytesIn))
{ {

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1741539824301" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3477" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M511.904 0c-45.588 111.744-73.08 184.84-123.836 293.26 31.12 32.98 69.316 71.384 131.348 114.76-66.692-27.436-112.18-54.984-146.176-83.568C308.28 459.968 206.52 653 0 1024c162.316-93.688 288.14-151.452 405.4-173.492a297.056 297.056 0 0 1-7.704-69.512l0.196-5.2c2.576-103.968 56.672-183.92 120.752-178.496 64.08 5.428 113.892 94.168 111.32 198.14-0.488 19.56-2.696 38.384-6.552 55.84C739.404 873.96 863.88 931.576 1024 1024c-31.572-58.116-59.752-110.504-86.664-160.4-42.392-32.848-86.608-75.6-176.8-121.88 61.992 16.1 106.38 34.68 140.976 55.452C627.892 287.832 605.736 220.152 511.904 0z" fill="#1793D1" p-id="3478"></path></svg>

After

Width:  |  Height:  |  Size: 962 B

View File

@@ -1,6 +1,5 @@
import { getTunnelInfo, refreshTunnel } from "@/apis/tunnel"; import { getTunnelInfo, refreshTunnel } from "@/apis/tunnel";
import { injectGlobalData } from "@/provide"; import { injectGlobalData } from "@/provide";
import { ElMessage } from "element-plus";
import { inject, provide, ref } from "vue"; import { inject, provide, ref } from "vue";
const tunnelSymbol = Symbol(); const tunnelSymbol = Symbol();

View File

@@ -16,7 +16,7 @@ export const provideTuntap = () => {
provide(tuntapSymbol, tuntap); provide(tuntapSymbol, tuntap);
const systems = { const systems = {
linux: ['debian', 'ubuntu', 'alpine', 'rocky', 'centos', 'fedora'], linux: ['debian', 'ubuntu', 'alpine', 'rocky', 'centos', 'fedora', 'archlinux'],
openwrt: ['openwrt'], openwrt: ['openwrt'],
ubuntu: ['ubuntu'], ubuntu: ['ubuntu'],
windows: ['windows'], windows: ['windows'],

View File

@@ -3,7 +3,7 @@
<div> <div>
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto"> <el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto">
<el-form-item :label="$t('server.relayCdkeyUserId')" prop="UserId"> <el-form-item :label="$t('server.relayCdkeyUserId')" prop="UserId">
<el-input maxlength="32" show-word-limit v-model="state.ruleForm.UserId" /> <el-input maxlength="36" show-word-limit v-model="state.ruleForm.UserId" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('server.relayCdkeyBandwidth')" prop="Bandwidth"> <el-form-item :label="$t('server.relayCdkeyBandwidth')" prop="Bandwidth">
<el-input-number size="small" v-model="state.ruleForm.Bandwidth" :min="1" :max="102400" />Mbps <el-input-number size="small" v-model="state.ruleForm.Bandwidth" :min="1" :max="102400" />Mbps

View File

@@ -1,5 +1,5 @@
v1.6.9 v1.6.9
2025-03-09 18:12:09 2025-03-10 17:55:18
1. 优化linux下路由跟踪问题 1. 优化linux下路由跟踪问题
2. 优化linux下获取本机IP问题 2. 优化linux下获取本机IP问题
3. 增加ICS让win7+、win server2008+支持NAT 3. 增加ICS让win7+、win server2008+支持NAT