mirror of
https://github.com/snltty/linker.git
synced 2025-12-17 17:06:47 +08:00
cdkey
This commit is contained in:
@@ -2,6 +2,5 @@
|
||||
declare (strict_types=1);
|
||||
|
||||
return [
|
||||
'STATUS' => '1',
|
||||
'KeyId' => 'FAFAB92C-DFDF-1221-DEA2-40A0E915EB10',
|
||||
'STATUS' => '0'
|
||||
];
|
||||
@@ -43,7 +43,7 @@ namespace linker.messenger.relay
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<RelayServerNodeReportInfo> Subscribe(ApiControllerParamsInfo param)
|
||||
public List<RelayServerNodeReportInfo170> Subscribe(ApiControllerParamsInfo param)
|
||||
{
|
||||
relayTestTransfer.Subscribe();
|
||||
return relayTestTransfer.Nodes;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace linker.messenger.relay
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace linker.messenger.relay.client.transport
|
||||
/// </summary>
|
||||
/// <param name="relayTestInfo"></param>
|
||||
/// <returns></returns>
|
||||
public Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo170 relayTestInfo);
|
||||
public Task<List<RelayServerNodeReportInfo170>> RelayTestAsync(RelayTestInfo170 relayTestInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace linker.messenger.relay.client.transport
|
||||
try
|
||||
{
|
||||
//问一下能不能中继
|
||||
RelayAskResultInfo relayAskResultInfo = await RelayAsk(relayInfo);
|
||||
RelayAskResultInfo170 relayAskResultInfo = await RelayAsk(relayInfo);
|
||||
relayInfo.FlowingId = relayAskResultInfo.FlowingId;
|
||||
if (relayInfo.FlowingId == 0 || relayAskResultInfo.Nodes.Count == 0)
|
||||
{
|
||||
@@ -119,7 +119,7 @@ namespace linker.messenger.relay.client.transport
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<RelayAskResultInfo> RelayAsk(RelayInfo170 relayInfo)
|
||||
private async Task<RelayAskResultInfo170> RelayAsk(RelayInfo170 relayInfo)
|
||||
{
|
||||
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
@@ -130,15 +130,15 @@ namespace linker.messenger.relay.client.transport
|
||||
}).ConfigureAwait(false);
|
||||
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;
|
||||
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -306,7 +306,7 @@ namespace linker.messenger.relay.client.transport
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo170 relayTestInfo)
|
||||
public async Task<List<RelayServerNodeReportInfo170>> RelayTestAsync(RelayTestInfo170 relayTestInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -320,13 +320,13 @@ namespace linker.messenger.relay.client.transport
|
||||
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<List<RelayServerNodeReportInfo>>(resp.Data.Span);
|
||||
return serializer.Deserialize<List<RelayServerNodeReportInfo170>>(resp.Data.Span);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
return new List<RelayServerNodeReportInfo>();
|
||||
return new List<RelayServerNodeReportInfo170>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,15 +70,22 @@ namespace linker.messenger.relay.messenger
|
||||
public async Task RelayTest(IConnection connection)
|
||||
{
|
||||
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)]
|
||||
public async Task RelayTest170(IConnection connection)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -94,8 +101,7 @@ namespace linker.messenger.relay.messenger
|
||||
TransportName = "test",
|
||||
}, cache, null);
|
||||
|
||||
var nodes = relayServerTransfer.GetNodes(string.IsNullOrWhiteSpace(result));
|
||||
connection.Write(serializer.Serialize(nodes));
|
||||
connection.Write(data(string.IsNullOrWhiteSpace(result)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -106,18 +112,6 @@ namespace linker.messenger.relay.messenger
|
||||
public async Task RelayAsk(IConnection connection)
|
||||
{
|
||||
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)
|
||||
{
|
||||
connection.Write(serializer.Serialize(new RelayAskResultInfo { }));
|
||||
@@ -132,10 +126,39 @@ namespace linker.messenger.relay.messenger
|
||||
RelayAskResultInfo result = new RelayAskResultInfo();
|
||||
string error = await relayValidatorTransfer.Validate(info, cacheFrom, cacheTo);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -240,7 +263,7 @@ namespace linker.messenger.relay.messenger
|
||||
[MessengerId((ushort)RelayMessengerIds.NodeReport)]
|
||||
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)
|
||||
{
|
||||
LoggerHelper.Instance.Debug($"relay node report : {info.ToJson()}");
|
||||
@@ -287,17 +310,26 @@ namespace linker.messenger.relay.messenger
|
||||
/// <param name="connection"></param>
|
||||
/// <returns></returns>
|
||||
[MessengerId((ushort)RelayMessengerIds.TrafficReport)]
|
||||
public async Task TrafficReport(IConnection connection)
|
||||
public void TrafficReport(IConnection connection)
|
||||
{
|
||||
RelayTrafficUpdateInfo info = serializer.Deserialize<RelayTrafficUpdateInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (relayServerStore.SecretKey != info.SecretKey)
|
||||
{
|
||||
connection.Write(serializer.Serialize(new Dictionary<string, long>()));
|
||||
return;
|
||||
}
|
||||
Dictionary<long, long> result = await relayServerTransfer.AddTraffic(info);
|
||||
connection.Write(serializer.Serialize(result));
|
||||
relayServerTransfer.AddTraffic(info.Dic);
|
||||
}
|
||||
/// <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>
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
RelayAsk170 = 2120,
|
||||
RelayForward170 = 2121,
|
||||
|
||||
SendLastBytes = 2122,
|
||||
|
||||
Max = 2199
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace linker.messenger.relay.server
|
||||
using linker.libs;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.messenger.relay.server
|
||||
{
|
||||
public interface IRelayServerCdkeyStore
|
||||
{
|
||||
@@ -54,6 +57,12 @@
|
||||
/// <returns></returns>
|
||||
public Task<bool> Traffic(Dictionary<long, long> dic);
|
||||
/// <summary>
|
||||
/// 获取剩余流量
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
public Task<Dictionary<long, long>> GetLastBytes(List<long> ids);
|
||||
/// <summary>
|
||||
/// 分页
|
||||
/// </summary>
|
||||
/// <param name="relayServerCdkeyPageRequestInfo"></param>
|
||||
@@ -66,7 +75,11 @@
|
||||
/// <summary>
|
||||
/// 加解密密钥
|
||||
/// </summary>
|
||||
#if DEBUG
|
||||
public string SecretKey { get; set; } = Helper.GlobalString;
|
||||
#else
|
||||
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
|
||||
#endif
|
||||
}
|
||||
|
||||
public sealed partial class RelayServerCdkeyPageRequestInfo
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace linker.messenger.relay.server
|
||||
|
||||
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 Name { get; set; } = string.Empty;
|
||||
@@ -124,7 +124,9 @@ namespace linker.messenger.relay.server
|
||||
public IPEndPoint EndPoint { get; set; }
|
||||
|
||||
public long LastTicks { get; set; }
|
||||
|
||||
}
|
||||
public sealed partial class RelayServerNodeReportInfo170: RelayServerNodeReportInfo
|
||||
{
|
||||
public string Url { get; set; } = "https://linker-doc.snltty.com";
|
||||
|
||||
[JsonIgnore]
|
||||
@@ -138,4 +140,10 @@ namespace linker.messenger.relay.server
|
||||
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>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,9 @@ namespace linker.messenger.relay.server
|
||||
{
|
||||
|
||||
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<List<long>> trafficIdsQueue = new ConcurrentQueue<List<long>>();
|
||||
|
||||
private readonly IRelayServerCaching relayCaching;
|
||||
private readonly ISerializer serializer;
|
||||
@@ -61,7 +62,7 @@ namespace linker.messenger.relay.server
|
||||
/// </summary>
|
||||
/// <param name="ep"></param>
|
||||
/// <param name="data"></param>
|
||||
public void SetNodeReport(IConnection connection, RelayServerNodeReportInfo info)
|
||||
public void SetNodeReport(IConnection connection, RelayServerNodeReportInfo170 info)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -93,7 +94,7 @@ namespace linker.messenger.relay.server
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -109,7 +110,7 @@ namespace linker.messenger.relay.server
|
||||
/// </summary>
|
||||
/// <param name="validated">是否已认证</param>
|
||||
/// <returns></returns>
|
||||
public List<RelayServerNodeReportInfo> GetNodes(bool validated)
|
||||
public List<RelayServerNodeReportInfo170> GetNodes(bool validated)
|
||||
{
|
||||
var result = reports.Values
|
||||
.Where(c => c.Public || validated)
|
||||
@@ -134,7 +135,7 @@ namespace linker.messenger.relay.server
|
||||
/// <returns></returns>
|
||||
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>
|
||||
@@ -142,16 +143,10 @@ namespace linker.messenger.relay.server
|
||||
/// </summary>
|
||||
/// <param name="relayTrafficUpdateInfo"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Dictionary<long, long>> AddTraffic(RelayTrafficUpdateInfo relayTrafficUpdateInfo)
|
||||
public void AddTraffic(Dictionary<long,long> dic)
|
||||
{
|
||||
if (relayTrafficUpdateInfo.Dic.Count > 0)
|
||||
trafficQueue.Enqueue(relayTrafficUpdateInfo.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);
|
||||
if (dic.Count > 0)
|
||||
trafficQueue.Enqueue(dic);
|
||||
}
|
||||
private void TrafficTask()
|
||||
{
|
||||
@@ -159,10 +154,50 @@ namespace linker.messenger.relay.server
|
||||
{
|
||||
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;
|
||||
}, 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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace linker.messenger.relay.server
|
||||
/// </summary>
|
||||
public class RelayServerNodeTransfer
|
||||
{
|
||||
public string Id=>relayServerNodeStore.Node.Id;
|
||||
public string Id => relayServerNodeStore.Node.Id;
|
||||
|
||||
private uint connectionNum = 0;
|
||||
private IConnection localConnection;
|
||||
@@ -23,7 +23,6 @@ namespace linker.messenger.relay.server
|
||||
private long lastBytes = 0;
|
||||
private RelaySpeedLimit limitTotal = new RelaySpeedLimit();
|
||||
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 IRelayServerNodeStore relayServerNodeStore;
|
||||
@@ -169,10 +168,6 @@ namespace linker.messenger.relay.server
|
||||
public void RemoveTrafficCache(RelayTrafficCacheInfo relayCache)
|
||||
{
|
||||
trafficDict.TryRemove(relayCache.Cache.FlowId, out _);
|
||||
foreach (var item in relayCache.Cache.Cdkey)
|
||||
{
|
||||
cdkeyLastBytes.TryRemove(item.CdkeyId, out _);
|
||||
}
|
||||
}
|
||||
/// <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();
|
||||
//有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.Limit.SetLimit((uint)Math.Ceiling((relayCache.CurrentCdkey.Bandwidth * 1024 * 1024) / 8.0));
|
||||
return;
|
||||
}
|
||||
|
||||
relayCache.CurrentCdkey = null;
|
||||
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()
|
||||
{
|
||||
foreach (var cache in trafficDict.Values.Where(c => c.CurrentCdkey == null))
|
||||
{
|
||||
long length = cache.Sendt;
|
||||
Interlocked.Exchange(ref cache.Sendt, 0);
|
||||
long length = Interlocked.Exchange(ref cache.Sendt, 0);
|
||||
|
||||
if (relayServerNodeStore.Node.MaxGbTotalLastBytes >= length)
|
||||
relayServerNodeStore.SetMaxGbTotalLastBytes(relayServerNodeStore.Node.MaxGbTotalLastBytes - length);
|
||||
else relayServerNodeStore.SetMaxGbTotalLastBytes(0);
|
||||
@@ -239,106 +251,56 @@ namespace linker.messenger.relay.server
|
||||
}
|
||||
relayServerNodeStore.Confirm();
|
||||
}
|
||||
private void DownloadBytes()
|
||||
private async Task UploadBytes()
|
||||
{
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
List<long> ids = trafficDict.Values.SelectMany(c => c.Cache.Cdkey).Select(c => c.CdkeyId).Distinct().ToList();
|
||||
while (ids.Count > 0)
|
||||
{
|
||||
//分批更新,可能数量很大
|
||||
List<long> id = ids.Take(100).ToList();
|
||||
ids.RemoveRange(0, id.Count);
|
||||
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; }));
|
||||
if (id2sent.Count == 0) return;
|
||||
|
||||
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection,
|
||||
MessengerId = (ushort)RelayMessengerIds.TrafficReport,
|
||||
Payload = serializer.Serialize(new RelayTrafficUpdateInfo
|
||||
{
|
||||
Dic = [],
|
||||
Ids = id,
|
||||
SecretKey = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID
|
||||
bool result = await messengerSender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
Connection = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection,
|
||||
MessengerId = (ushort)RelayMessengerIds.TrafficReport,
|
||||
Payload = serializer.Serialize(new RelayTrafficUpdateInfo
|
||||
{
|
||||
Dic = id2sent,
|
||||
SecretKey = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID
|
||||
? relayServerMasterStore.Master.SecretKey
|
||||
: relayServerNodeStore.Node.MasterSecretKey
|
||||
}),
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
Timeout = 4000
|
||||
});
|
||||
}
|
||||
private void UploadBytes()
|
||||
{
|
||||
TimerHelper.Async(async () =>
|
||||
|
||||
if (result)
|
||||
{
|
||||
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
//成功报告了流量,就重新计数
|
||||
foreach (var cache in cdkeys)
|
||||
{
|
||||
Connection = relayServerNodeStore.Node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? localConnection : remoteConnection,
|
||||
MessengerId = (ushort)RelayMessengerIds.TrafficReport,
|
||||
Payload = serializer.Serialize(new RelayTrafficUpdateInfo
|
||||
{
|
||||
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)
|
||||
Interlocked.Add(ref cache.Sendt, -cache.SendtCache);
|
||||
Interlocked.Exchange(ref cache.SendtCache, 0);
|
||||
//当前cdkey流量用完了,就重新找找新的cdkey
|
||||
if (cache.CurrentCdkey.LastBytes <= 0)
|
||||
{
|
||||
SetLimit(cache);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
private void TrafficTask()
|
||||
{
|
||||
TimerHelper.SetIntervalLong(() =>
|
||||
TimerHelper.SetIntervalLong(async () =>
|
||||
{
|
||||
UploadBytes();
|
||||
DownloadBytes();
|
||||
|
||||
ResetNodeBytes();
|
||||
|
||||
try
|
||||
{
|
||||
ResetNodeBytes();
|
||||
await UploadBytes();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
return true;
|
||||
}, 5000);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
private void ReportTask()
|
||||
@@ -377,7 +339,7 @@ namespace linker.messenger.relay.server
|
||||
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);
|
||||
|
||||
RelayServerNodeReportInfo relayNodeReportInfo = new RelayServerNodeReportInfo
|
||||
RelayServerNodeReportInfo170 relayNodeReportInfo = new RelayServerNodeReportInfo170
|
||||
{
|
||||
Id = node.Id,
|
||||
Name = node.Name,
|
||||
@@ -389,7 +351,8 @@ namespace linker.messenger.relay.server
|
||||
MaxGbTotalLastBytes = node.MaxGbTotalLastBytes,
|
||||
MaxConnection = node.MaxConnection,
|
||||
ConnectionRatio = Math.Round(connectionNum / 2.0),
|
||||
EndPoint = endPoint
|
||||
EndPoint = endPoint,
|
||||
Url = node.Url
|
||||
};
|
||||
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
@@ -465,10 +428,6 @@ namespace linker.messenger.relay.server
|
||||
/// cdkey id 和 流量
|
||||
/// </summary>
|
||||
public Dictionary<long, long> Dic { get; set; }
|
||||
/// <summary>
|
||||
/// 需要知道哪些cdkey的剩余流量
|
||||
/// </summary>
|
||||
public List<long> Ids { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -104,9 +104,14 @@ namespace linker.messenger.relay.server
|
||||
}
|
||||
relayWrap.Tcs.SetResult();
|
||||
|
||||
RelaySpeedLimit limit = new RelaySpeedLimit();
|
||||
_ = CopyToAsync(relayCache, limit, socket, relayWrap.Socket);
|
||||
_ = CopyToAsync(relayCache, limit, relayWrap.Socket, socket);
|
||||
RelayTrafficCacheInfo trafficCacheInfo = new RelayTrafficCacheInfo { Cache = relayCache, Sendt = 0, Limit = new RelaySpeedLimit() };
|
||||
relayServerNodeTransfer.AddTrafficCache(trafficCacheInfo);
|
||||
relayServerNodeTransfer.IncrementConnectionNum();
|
||||
_ = Task.WhenAll(CopyToAsync(trafficCacheInfo, socket, relayWrap.Socket), CopyToAsync(trafficCacheInfo, relayWrap.Socket, socket)).ContinueWith((result) =>
|
||||
{
|
||||
relayServerNodeTransfer.DecrementConnectionNum();
|
||||
relayServerNodeTransfer.RemoveTrafficCache(trafficCacheInfo);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -139,15 +144,11 @@ namespace linker.messenger.relay.server
|
||||
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];
|
||||
try
|
||||
{
|
||||
relayServerNodeTransfer.IncrementConnectionNum();
|
||||
relayServerNodeTransfer.AddTrafficCache(trafficCacheInfo);
|
||||
|
||||
int bytesRead;
|
||||
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;
|
||||
limit.TryLimit(ref length);
|
||||
trafficCacheInfo.Limit.TryLimit(ref length);
|
||||
while (length > 0)
|
||||
{
|
||||
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);
|
||||
AddSendt(cache.FromId, cache.FromName, cache.ToName, cache.GroupId, bytesRead);
|
||||
AddReceive(trafficCacheInfo.Cache.FromId, trafficCacheInfo.Cache.FromName, trafficCacheInfo.Cache.ToName, trafficCacheInfo.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);
|
||||
}
|
||||
}
|
||||
@@ -191,8 +192,6 @@ namespace linker.messenger.relay.server
|
||||
}
|
||||
finally
|
||||
{
|
||||
relayServerNodeTransfer.DecrementConnectionNum();
|
||||
relayServerNodeTransfer.RemoveTrafficCache(trafficCacheInfo);
|
||||
source.SafeClose();
|
||||
destination.SafeClose();
|
||||
}
|
||||
@@ -264,6 +263,7 @@ namespace linker.messenger.relay.server
|
||||
public sealed class RelayTrafficCacheInfo
|
||||
{
|
||||
public long Sendt;
|
||||
public long SendtCache;
|
||||
public RelaySpeedLimit Limit { get; set; }
|
||||
public RelayCacheInfo Cache { get; set; }
|
||||
public RelayServerCdkeyInfo CurrentCdkey { get; set; }
|
||||
|
||||
@@ -55,7 +55,9 @@ namespace linker.messenger.serializer.memorypack
|
||||
MemoryPackFormatterProvider.Register(new RelayInfo170Formatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateInfoFormatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfo170Formatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayAskResultInfo170Formatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
|
||||
MemoryPackFormatterProvider.Register(new RelayServerCdkeyInfoFormatter());
|
||||
|
||||
@@ -456,8 +456,6 @@ namespace linker.messenger.serializer.memorypack
|
||||
IPEndPoint EndPoint => info.EndPoint;
|
||||
[MemoryPackInclude]
|
||||
long LastTicks => info.LastTicks;
|
||||
[MemoryPackInclude]
|
||||
string Url => info.Url;
|
||||
|
||||
|
||||
[MemoryPackConstructor]
|
||||
@@ -467,7 +465,7 @@ namespace linker.messenger.serializer.memorypack
|
||||
double maxGbTotal, long maxGbTotalLastBytes,
|
||||
double connectionRatio, double bandwidthRatio,
|
||||
bool Public, int delay,
|
||||
IPEndPoint endPoint, long lastTicks, string url)
|
||||
IPEndPoint endPoint, long lastTicks)
|
||||
{
|
||||
var info = new RelayServerNodeReportInfo
|
||||
{
|
||||
@@ -483,8 +481,7 @@ namespace linker.messenger.serializer.memorypack
|
||||
MaxGbTotal = maxGbTotal,
|
||||
MaxGbTotalLastBytes = maxGbTotalLastBytes,
|
||||
Name = name,
|
||||
Public = Public,
|
||||
Url = url
|
||||
Public = Public
|
||||
};
|
||||
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]
|
||||
@@ -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]
|
||||
public readonly partial struct SerializableRelayCacheInfo
|
||||
@@ -1150,17 +1293,14 @@ namespace linker.messenger.serializer.memorypack
|
||||
[MemoryPackInclude]
|
||||
Dictionary<long, long> Dic => info.Dic;
|
||||
[MemoryPackInclude]
|
||||
List<long> Ids => info.Ids;
|
||||
[MemoryPackInclude]
|
||||
string SecretKey => info.SecretKey;
|
||||
|
||||
[MemoryPackConstructor]
|
||||
SerializableRelayTrafficUpdateInfo(Dictionary<long, long> dic, List<long> ids, string secretKey)
|
||||
SerializableRelayTrafficUpdateInfo(Dictionary<long, long> dic, string secretKey)
|
||||
{
|
||||
var info = new RelayTrafficUpdateInfo
|
||||
{
|
||||
Dic = dic,
|
||||
Ids = ids,
|
||||
SecretKey = secretKey
|
||||
};
|
||||
this.info = info;
|
||||
|
||||
@@ -168,10 +168,14 @@ namespace linker.messenger.store.file.relay
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -184,11 +188,11 @@ namespace linker.messenger.store.file.relay
|
||||
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
|
||||
1
src/linker.web/public/archlinux.svg
Normal file
1
src/linker.web/public/archlinux.svg
Normal 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 |
@@ -1,6 +1,5 @@
|
||||
import { getTunnelInfo, refreshTunnel } from "@/apis/tunnel";
|
||||
import { injectGlobalData } from "@/provide";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { inject, provide, ref } from "vue";
|
||||
|
||||
const tunnelSymbol = Symbol();
|
||||
|
||||
@@ -16,7 +16,7 @@ export const provideTuntap = () => {
|
||||
provide(tuntapSymbol, tuntap);
|
||||
|
||||
const systems = {
|
||||
linux: ['debian', 'ubuntu', 'alpine', 'rocky', 'centos', 'fedora'],
|
||||
linux: ['debian', 'ubuntu', 'alpine', 'rocky', 'centos', 'fedora', 'archlinux'],
|
||||
openwrt: ['openwrt'],
|
||||
ubuntu: ['ubuntu'],
|
||||
windows: ['windows'],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div>
|
||||
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto">
|
||||
<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 :label="$t('server.relayCdkeyBandwidth')" prop="Bandwidth">
|
||||
<el-input-number size="small" v-model="state.ruleForm.Bandwidth" :min="1" :max="102400" />Mbps
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
v1.6.9
|
||||
2025-03-09 18:12:09
|
||||
2025-03-10 17:55:18
|
||||
1. 优化linux下路由跟踪问题
|
||||
2. 优化linux下获取本机IP问题
|
||||
3. 增加ICS,让win7+、win server2008+支持NAT
|
||||
|
||||
Reference in New Issue
Block a user