diff --git a/src/linker.messenger.api/Config.cs b/src/linker.messenger.api/Config.cs index cc192046..a66cc4eb 100644 --- a/src/linker.messenger.api/Config.cs +++ b/src/linker.messenger.api/Config.cs @@ -160,6 +160,8 @@ namespace linker.messenger.api ForwardFlow = 50, [AccessDisplay("查看Socks5流量")] Socks5Flow = 51, + [AccessDisplay("查看隧道流量")] + TunnelFlow = 52, } public sealed class AccessTextInfo diff --git a/src/linker.messenger.flow/FlowApiController.cs b/src/linker.messenger.flow/FlowApiController.cs index 89c9dafd..19fd9095 100644 --- a/src/linker.messenger.flow/FlowApiController.cs +++ b/src/linker.messenger.flow/FlowApiController.cs @@ -18,10 +18,11 @@ namespace linker.messenger.flow private readonly FlowSForward sForwardFlow; private readonly FlowForward forwardFlow; private readonly FlowSocks5 socks5Flow; + private readonly FlowTunnel tunnelFlow; private DateTime start = DateTime.Now; - public FlowApiController(IMessengerSender messengerSender, SignInClientState signInClientState, ISerializer serializer, ISignInClientStore signInClientStore, FlowMessenger messengerFlow, FlowTransfer flowTransfer, FlowSForward sForwardFlow, FlowForward forwardFlow, FlowSocks5 socks5Flow) + public FlowApiController(IMessengerSender messengerSender, SignInClientState signInClientState, ISerializer serializer, ISignInClientStore signInClientStore, FlowMessenger messengerFlow, FlowTransfer flowTransfer, FlowSForward sForwardFlow, FlowForward forwardFlow, FlowSocks5 socks5Flow, FlowTunnel tunnelFlow) { this.messengerSender = messengerSender; this.signInClientState = signInClientState; @@ -32,6 +33,7 @@ namespace linker.messenger.flow this.sForwardFlow = sForwardFlow; this.forwardFlow = forwardFlow; this.socks5Flow = socks5Flow; + this.tunnelFlow = tunnelFlow; } public async Task GetFlows(ApiControllerParamsInfo param) @@ -200,6 +202,29 @@ namespace linker.messenger.flow } return new Socks5FlowResponseInfo(); } + + [Access(AccessValue.TunnelFlow)] + public async Task GetTunnelFlows(ApiControllerParamsInfo param) + { + TunnelFlowRequestInfo info = param.Content.DeJson(); + ushort messengerId = string.IsNullOrWhiteSpace(info.MachineId) ? (ushort)FlowMessengerIds.Tunnel : (ushort)FlowMessengerIds.TunnelForward; + if (info.MachineId == signInClientStore.Id) + { + return tunnelFlow.GetFlows(info); + } + + MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap + { + Connection = signInClientState.Connection, + MessengerId = messengerId, + Payload = serializer.Serialize(info) + }).ConfigureAwait(false); + if (resp.Code == MessageResponeCodes.OK && resp.Data.Length > 0) + { + return serializer.Deserialize(resp.Data.Span); + } + return new TunnelFlowResponseInfo(); + } } } diff --git a/src/linker.messenger.flow/FlowForward.cs b/src/linker.messenger.flow/FlowForward.cs index dca94d15..7ca1070a 100644 --- a/src/linker.messenger.flow/FlowForward.cs +++ b/src/linker.messenger.flow/FlowForward.cs @@ -1,5 +1,6 @@ using linker.libs; using linker.libs.extends; +using linker.libs.timer; using linker.messenger.forward.proxy; using linker.messenger.pcp; using linker.messenger.relay.client; @@ -9,6 +10,7 @@ using linker.tunnel; using linker.tunnel.connection; using System.Collections.Concurrent; using System.Net; +using System.Text.Json.Serialization; namespace linker.messenger.flow { @@ -45,6 +47,20 @@ namespace linker.messenger.flow public FlowForward() { + TimerHelper.SetIntervalLong(() => + { + if (lastTicksManager.DiffLessEqual(5000)) + { + foreach (var item in flows.Values) + { + item.DiffReceiveBytes = item.SendtBytes - item.OldSendtBytes; + item.DiffSendtBytes = item.ReceiveBytes - item.OldReceiveBytes; + + item.OldSendtBytes = item.SendtBytes; + item.OldReceiveBytes = item.ReceiveBytes; + } + } + }, () => lastTicksManager.DiffLessEqual(5000) ? 1000 : 30000); } public string GetItems() => flows.ToJson(); @@ -88,12 +104,24 @@ namespace linker.messenger.flow else items = items.OrderBy(x => x.SendtBytes); break; + case ForwardFlowOrder.DiffSendt: + if (info.OrderType == ForwardFlowOrderType.Desc) + items = items.OrderByDescending(x => x.DiffSendtBytes); + else + items = items.OrderBy(x => x.DiffSendtBytes); + break; case ForwardFlowOrder.Receive: if (info.OrderType == ForwardFlowOrderType.Desc) items = items.OrderByDescending(x => x.ReceiveBytes); else items = items.OrderBy(x => x.ReceiveBytes); break; + case ForwardFlowOrder.DiffRecive: + if (info.OrderType == ForwardFlowOrderType.Desc) + items = items.OrderByDescending(x => x.DiffReceiveBytes); + else + items = items.OrderBy(x => x.DiffReceiveBytes); + break; default: break; } @@ -113,6 +141,13 @@ namespace linker.messenger.flow { public string Key { get; set; } public IPEndPoint Target { get; set; } + + public long DiffReceiveBytes { get; set; } + public long DiffSendtBytes { get; set; } + [JsonIgnore] + public long OldReceiveBytes { get; set; } + [JsonIgnore] + public long OldSendtBytes { get; set; } } public sealed partial class ForwardFlowRequestInfo @@ -127,7 +162,9 @@ namespace linker.messenger.flow public enum ForwardFlowOrder : byte { Sendt = 1, - Receive = 2, + DiffSendt = 2, + Receive = 3, + DiffRecive = 4 } public enum ForwardFlowOrderType : byte { diff --git a/src/linker.messenger.flow/FlowSocks5.cs b/src/linker.messenger.flow/FlowSocks5.cs index 9a4f07a8..99f980b0 100644 --- a/src/linker.messenger.flow/FlowSocks5.cs +++ b/src/linker.messenger.flow/FlowSocks5.cs @@ -1,5 +1,6 @@ using linker.libs; using linker.libs.extends; +using linker.libs.timer; using linker.messenger.pcp; using linker.messenger.relay.client; using linker.messenger.signin; @@ -9,6 +10,7 @@ using linker.tunnel; using linker.tunnel.connection; using System.Collections.Concurrent; using System.Net; +using System.Text.Json.Serialization; namespace linker.messenger.flow { @@ -46,6 +48,20 @@ namespace linker.messenger.flow public FlowSocks5() { + TimerHelper.SetIntervalLong(() => + { + if (lastTicksManager.DiffLessEqual(5000)) + { + foreach (var item in flows.Values) + { + item.DiffReceiveBytes = item.SendtBytes - item.OldSendtBytes; + item.DiffSendtBytes = item.ReceiveBytes - item.OldReceiveBytes; + + item.OldSendtBytes = item.SendtBytes; + item.OldReceiveBytes = item.ReceiveBytes; + } + } + }, () => lastTicksManager.DiffLessEqual(5000) ? 1000 : 30000); } public string GetItems() => flows.ToJson(); @@ -89,12 +105,24 @@ namespace linker.messenger.flow else items = items.OrderBy(x => x.SendtBytes); break; + case Socks5FlowOrder.DiffSendt: + if (info.OrderType == Socks5FlowOrderType.Desc) + items = items.OrderByDescending(x => x.DiffSendtBytes); + else + items = items.OrderBy(x => x.DiffSendtBytes); + break; case Socks5FlowOrder.Receive: if (info.OrderType == Socks5FlowOrderType.Desc) items = items.OrderByDescending(x => x.ReceiveBytes); else items = items.OrderBy(x => x.ReceiveBytes); break; + case Socks5FlowOrder.DiffRecive: + if (info.OrderType == Socks5FlowOrderType.Desc) + items = items.OrderByDescending(x => x.DiffReceiveBytes); + else + items = items.OrderBy(x => x.DiffReceiveBytes); + break; default: break; } @@ -114,6 +142,13 @@ namespace linker.messenger.flow { public string Key { get; set; } public IPEndPoint Target { get; set; } + + public long DiffReceiveBytes { get; set; } + public long DiffSendtBytes { get; set; } + [JsonIgnore] + public long OldReceiveBytes { get; set; } + [JsonIgnore] + public long OldSendtBytes { get; set; } } public sealed partial class Socks5FlowRequestInfo @@ -128,7 +163,9 @@ namespace linker.messenger.flow public enum Socks5FlowOrder : byte { Sendt = 1, - Receive = 2, + DiffSendt = 2, + Receive = 3, + DiffRecive = 4 } public enum Socks5FlowOrderType : byte { diff --git a/src/linker.messenger.flow/messenger/FlowMessenger.cs b/src/linker.messenger.flow/messenger/FlowMessenger.cs index f146d661..419b14d9 100644 --- a/src/linker.messenger.flow/messenger/FlowMessenger.cs +++ b/src/linker.messenger.flow/messenger/FlowMessenger.cs @@ -269,6 +269,33 @@ namespace linker.messenger.flow.messenger }); } } + + [MessengerId((ushort)FlowMessengerIds.TunnelForward)] + public void TunnelForward(IConnection connection) + { + TunnelFlowRequestInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + if (signCaching.TryGet(connection.Id, info.MachineId, out SignCacheInfo from, out SignCacheInfo to)) + { + uint requestid = connection.ReceiveRequestWrap.RequestId; + _ = messengerSender.SendReply(new MessageRequestWrap + { + Connection = to.Connection, + MessengerId = (ushort)FlowMessengerIds.Tunnel, + Payload = connection.ReceiveRequestWrap.Payload, + }).ContinueWith(async (result) => + { + if (result.Result.Code == MessageResponeCodes.OK && result.Result.Data.Length > 0) + { + await messengerSender.ReplyOnly(new MessageResponseWrap + { + Connection = connection, + Payload = result.Result.Data, + RequestId = requestid, + }, (ushort)FlowMessengerIds.TunnelForward).ConfigureAwait(false); + } + }); + } + } } @@ -279,17 +306,19 @@ namespace linker.messenger.flow.messenger private readonly FlowSForward sForwardFlow; private readonly FlowForward forwardFlow; private readonly FlowSocks5 socks5Flow; + private readonly FlowTunnel tunnelFlow; private readonly FlowTransfer flowTransfer; private DateTime start = DateTime.Now; - public FlowClientMessenger(flow.FlowMessenger messengerFlow, ISerializer serializer, FlowSForward sForwardFlow, FlowForward forwardFlow, FlowSocks5 socks5Flow, FlowTransfer flowTransfer) + public FlowClientMessenger(flow.FlowMessenger messengerFlow, ISerializer serializer, FlowSForward sForwardFlow, FlowForward forwardFlow, FlowSocks5 socks5Flow, FlowTunnel tunnelFlow, FlowTransfer flowTransfer) { this.messengerFlow = messengerFlow; this.serializer = serializer; this.sForwardFlow = sForwardFlow; this.forwardFlow = forwardFlow; this.socks5Flow = socks5Flow; + this.tunnelFlow = tunnelFlow; this.flowTransfer = flowTransfer; } @@ -341,5 +370,13 @@ namespace linker.messenger.flow.messenger Socks5FlowRequestInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); connection.Write(serializer.Serialize(socks5Flow.GetFlows(info))); } + + [MessengerId((ushort)FlowMessengerIds.Tunnel)] + public void Tunnel(IConnection connection) + { + tunnelFlow.Update(); + TunnelFlowRequestInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + connection.Write(serializer.Serialize(tunnelFlow.GetFlows(info))); + } } } diff --git a/src/linker.messenger.flow/messenger/FlowMessengerIds.cs b/src/linker.messenger.flow/messenger/FlowMessengerIds.cs index 0ea22bd1..1f2818f3 100644 --- a/src/linker.messenger.flow/messenger/FlowMessengerIds.cs +++ b/src/linker.messenger.flow/messenger/FlowMessengerIds.cs @@ -25,6 +25,12 @@ Socks5Forward = 2714, Socks5 = 2715, + TuntapForward = 2716, + Tuntap = 2717, + + TunnelForward = 2718, + Tunnel = 2719, + Max = 2799 } } diff --git a/src/linker.messenger.serializer.memorypack/Entry.cs b/src/linker.messenger.serializer.memorypack/Entry.cs index c1bcd8c4..255ce68f 100644 --- a/src/linker.messenger.serializer.memorypack/Entry.cs +++ b/src/linker.messenger.serializer.memorypack/Entry.cs @@ -123,6 +123,15 @@ namespace linker.messenger.serializer.memorypack MemoryPackFormatterProvider.Register(new SForwardFlowItemInfoFormatter()); MemoryPackFormatterProvider.Register(new SForwardFlowRequestInfoFormatter()); MemoryPackFormatterProvider.Register(new SForwardFlowResponseInfoFormatter()); + MemoryPackFormatterProvider.Register(new ForwardFlowItemInfoFormatter()); + MemoryPackFormatterProvider.Register(new ForwardFlowRequestInfoFormatter()); + MemoryPackFormatterProvider.Register(new ForwardFlowResponseInfoFormatter()); + MemoryPackFormatterProvider.Register(new Socks5FlowItemInfoFormatter()); + MemoryPackFormatterProvider.Register(new Socks5FlowRequestInfoFormatter()); + MemoryPackFormatterProvider.Register(new Socks5FlowResponseInfoFormatter()); + MemoryPackFormatterProvider.Register(new TunnelFlowItemInfoFormatter()); + MemoryPackFormatterProvider.Register(new TunnelFlowRequestInfoFormatter()); + MemoryPackFormatterProvider.Register(new TunnelFlowResponseInfoFormatter()); MemoryPackFormatterProvider.Register(new TuntapVeaLanIPAddressFormatter()); MemoryPackFormatterProvider.Register(new TuntapVeaLanIPAddressListFormatter()); diff --git a/src/linker.messenger.serializer.memorypack/FlowSerializer.cs b/src/linker.messenger.serializer.memorypack/FlowSerializer.cs index 2edf3ce6..7484a6bd 100644 --- a/src/linker.messenger.serializer.memorypack/FlowSerializer.cs +++ b/src/linker.messenger.serializer.memorypack/FlowSerializer.cs @@ -1,6 +1,7 @@ using MemoryPack; using linker.messenger.flow; using System.Net; +using linker.tunnel.connection; namespace linker.messenger.serializer.memorypack { @@ -602,6 +603,13 @@ namespace linker.messenger.serializer.memorypack [MemoryPackInclude] long SendtBytes => info.SendtBytes; + [MemoryPackInclude] + long DiffReceiveBytes => info.DiffReceiveBytes; + + [MemoryPackInclude] + long DiffSendtBytes => info.DiffSendtBytes; + + [MemoryPackInclude] string Key => info.Key; @@ -609,12 +617,14 @@ namespace linker.messenger.serializer.memorypack IPEndPoint Target => info.Target; [MemoryPackConstructor] - SerializableForwardFlowItemInfo(long receiveBytes, long sendtBytes, string key, IPEndPoint target) + SerializableForwardFlowItemInfo(long receiveBytes, long sendtBytes, long diffReceiveBytes, long diffSendtBytes, string key, IPEndPoint target) { var info = new ForwardFlowItemInfo { ReceiveBytes = receiveBytes, SendtBytes = sendtBytes, + DiffReceiveBytes = diffReceiveBytes, + DiffSendtBytes = diffSendtBytes, Key = key, Target = target }; @@ -782,4 +792,415 @@ namespace linker.messenger.serializer.memorypack value = wrapped.info; } } + + + + + [MemoryPackable] + public readonly partial struct SerializableSocks5FlowItemInfo + { + [MemoryPackIgnore] + public readonly Socks5FlowItemInfo info; + + [MemoryPackInclude] + long ReceiveBytes => info.ReceiveBytes; + + [MemoryPackInclude] + long SendtBytes => info.SendtBytes; + + [MemoryPackInclude] + long DiffReceiveBytes => info.DiffReceiveBytes; + + [MemoryPackInclude] + long DiffSendtBytes => info.DiffSendtBytes; + + + [MemoryPackInclude] + string Key => info.Key; + + [MemoryPackInclude, MemoryPackAllowSerialize] + IPEndPoint Target => info.Target; + + [MemoryPackConstructor] + SerializableSocks5FlowItemInfo(long receiveBytes, long sendtBytes, long diffReceiveBytes, long diffSendtBytes, string key, IPEndPoint target) + { + var info = new Socks5FlowItemInfo + { + ReceiveBytes = receiveBytes, + SendtBytes = sendtBytes, + DiffReceiveBytes = diffReceiveBytes, + DiffSendtBytes = diffSendtBytes, + Key = key, + Target = target + }; + this.info = info; + } + + public SerializableSocks5FlowItemInfo(Socks5FlowItemInfo info) + { + this.info = info; + } + } + public class Socks5FlowItemInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref Socks5FlowItemInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableSocks5FlowItemInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref Socks5FlowItemInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + [MemoryPackable] + public readonly partial struct SerializableSocks5FlowRequestInfo + { + [MemoryPackIgnore] + public readonly Socks5FlowRequestInfo info; + + [MemoryPackInclude] + string MachineId => info.MachineId; + + [MemoryPackInclude] + int Page => info.Page; + + [MemoryPackInclude] + int PageSize => info.PageSize; + + [MemoryPackInclude] + Socks5FlowOrder Order => info.Order; + + [MemoryPackInclude] + Socks5FlowOrderType OrderType => info.OrderType; + + [MemoryPackConstructor] + SerializableSocks5FlowRequestInfo(string machineId, int page, int pageSize, Socks5FlowOrder order, Socks5FlowOrderType orderType) + { + var info = new Socks5FlowRequestInfo + { + MachineId = machineId, + Order = order, + OrderType = orderType, + Page = page, + PageSize = pageSize + }; + this.info = info; + } + + public SerializableSocks5FlowRequestInfo(Socks5FlowRequestInfo info) + { + this.info = info; + } + } + public class Socks5FlowRequestInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref Socks5FlowRequestInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableSocks5FlowRequestInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref Socks5FlowRequestInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + [MemoryPackable] + public readonly partial struct SerializableSocks5FlowResponseInfo + { + [MemoryPackIgnore] + public readonly Socks5FlowResponseInfo info; + + [MemoryPackInclude] + int Page => info.Page; + + [MemoryPackInclude] + int PageSize => info.PageSize; + + [MemoryPackInclude] + int Count => info.Count; + + [MemoryPackInclude] + List Data => info.Data; + + [MemoryPackConstructor] + SerializableSocks5FlowResponseInfo(int page, int pageSize, int count, List data) + { + var info = new Socks5FlowResponseInfo + { + Page = page, + PageSize = pageSize, + Count = count, + Data = data + }; + this.info = info; + } + + public SerializableSocks5FlowResponseInfo(Socks5FlowResponseInfo info) + { + this.info = info; + } + } + public class Socks5FlowResponseInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref Socks5FlowResponseInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableSocks5FlowResponseInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref Socks5FlowResponseInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + + + [MemoryPackable] + public readonly partial struct SerializableTunnelFlowItemInfo + { + [MemoryPackIgnore] + public readonly TunnelFlowItemInfo info; + + [MemoryPackInclude] + long ReceiveBytes => info.ReceiveBytes; + + [MemoryPackInclude] + long SendtBytes => info.SendtBytes; + + + [MemoryPackInclude] + string Key => info.Key; + + [MemoryPackInclude] + string TransitionId => info.TransitionId; + + [MemoryPackInclude] + TunnelDirection Direction => info.Direction; + [MemoryPackInclude] + TunnelType Type => info.Type; + [MemoryPackInclude] + TunnelMode Mode => info.Mode; + + [MemoryPackConstructor] + SerializableTunnelFlowItemInfo(long receiveBytes, long sendtBytes, string key, string transitionId, TunnelDirection direction, TunnelType type, TunnelMode mode) + { + var info = new TunnelFlowItemInfo + { + ReceiveBytes = receiveBytes, + SendtBytes = sendtBytes, + Key = key, + TransitionId = transitionId, + Direction = direction, + Type = type, + Mode = mode + }; + this.info = info; + } + + public SerializableTunnelFlowItemInfo(TunnelFlowItemInfo info) + { + this.info = info; + } + } + public class TunnelFlowItemInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref TunnelFlowItemInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableTunnelFlowItemInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref TunnelFlowItemInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + [MemoryPackable] + public readonly partial struct SerializableTunnelFlowRequestInfo + { + [MemoryPackIgnore] + public readonly TunnelFlowRequestInfo info; + + [MemoryPackInclude] + string MachineId => info.MachineId; + + [MemoryPackInclude] + int Page => info.Page; + + [MemoryPackInclude] + int PageSize => info.PageSize; + + [MemoryPackInclude] + TunnelFlowOrder Order => info.Order; + + [MemoryPackInclude] + TunnelFlowOrderType OrderType => info.OrderType; + + [MemoryPackConstructor] + SerializableTunnelFlowRequestInfo(string machineId, int page, int pageSize, TunnelFlowOrder order, TunnelFlowOrderType orderType) + { + var info = new TunnelFlowRequestInfo + { + MachineId = machineId, + Order = order, + OrderType = orderType, + Page = page, + PageSize = pageSize + }; + this.info = info; + } + + public SerializableTunnelFlowRequestInfo(TunnelFlowRequestInfo info) + { + this.info = info; + } + } + public class TunnelFlowRequestInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref TunnelFlowRequestInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableTunnelFlowRequestInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref TunnelFlowRequestInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + [MemoryPackable] + public readonly partial struct SerializableTunnelFlowResponseInfo + { + [MemoryPackIgnore] + public readonly TunnelFlowResponseInfo info; + + [MemoryPackInclude] + int Page => info.Page; + + [MemoryPackInclude] + int PageSize => info.PageSize; + + [MemoryPackInclude] + int Count => info.Count; + + [MemoryPackInclude] + List Data => info.Data; + + [MemoryPackConstructor] + SerializableTunnelFlowResponseInfo(int page, int pageSize, int count, List data) + { + var info = new TunnelFlowResponseInfo + { + Page = page, + PageSize = pageSize, + Count = count, + Data = data + }; + this.info = info; + } + + public SerializableTunnelFlowResponseInfo(TunnelFlowResponseInfo info) + { + this.info = info; + } + } + public class TunnelFlowResponseInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref TunnelFlowResponseInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableTunnelFlowResponseInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref TunnelFlowResponseInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } } diff --git a/src/linker.web/src/apis/flow.js b/src/linker.web/src/apis/flow.js index a96d5bc1..2b7869cc 100644 --- a/src/linker.web/src/apis/flow.js +++ b/src/linker.web/src/apis/flow.js @@ -1,10 +1,10 @@ import { sendWebsocketMsg } from './request' -export const getFlows = () => { - return sendWebsocketMsg('flow/GetFlows'); +export const getFlows = (machineId) => { + return sendWebsocketMsg('flow/GetFlows',machineId); } -export const getMessengerFlows = () => { - return sendWebsocketMsg('flow/GetMessengerFlows'); +export const getMessengerFlows = (machineId) => { + return sendWebsocketMsg('flow/GetMessengerFlows',machineId); } export const getSForwardFlows = (data) => { return sendWebsocketMsg('flow/GetSForwardFlows', data); @@ -15,6 +15,15 @@ export const getRelayFlows = (data) => { export const getCitys = () => { return sendWebsocketMsg('flow/GetCitys'); } -export const getStopwatch = (id) => { - return sendWebsocketMsg('flow/GetStopwatch',id); +export const getStopwatch = (machineId) => { + return sendWebsocketMsg('flow/GetStopwatch',machineId); +} +export const getForwardFlows = (data) => { + return sendWebsocketMsg('flow/GetForwardFlows', data); +} +export const getSocks5Flows = (data) => { + return sendWebsocketMsg('flow/GetSocks5Flows', data); +} +export const getTunnelFlows = (data) => { + return sendWebsocketMsg('flow/GetTunnelFlows', data); } \ No newline at end of file diff --git a/version.txt b/version.txt index 7c39bc38..8915929f 100644 --- a/version.txt +++ b/version.txt @@ -1,5 +1,5 @@ v1.8.6 -2025-07-07 11:37:56 +2025-07-07 17:50:09 1. 一些累计更新 2. 白名单 3. 优化防火墙