mirror of
https://github.com/snltty/linker.git
synced 2025-12-24 12:38:04 +08:00
重构管理页面代码
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
v1.9.6
|
||||
2025-11-15 19:45:45
|
||||
2025-11-16 20:01:56
|
||||
1. 一些累计更新,一些BUG修复
|
||||
2. 优化客户端数据同步,减少服务器流量
|
||||
3. 去除cdkey,改为发电解锁中继速度
|
||||
|
||||
@@ -22,24 +22,30 @@ namespace linker.libs
|
||||
{
|
||||
public ConcurrentDictionary<string, bool> StringKeyValue=> dicOperating;
|
||||
|
||||
public VersionManager DataVersion { get; } = new VersionManager();
|
||||
|
||||
private readonly ConcurrentDictionary<string, bool> dicOperating = new ConcurrentDictionary<string, bool>();
|
||||
private readonly ConcurrentDictionary<uint, bool> dicOperating1 = new ConcurrentDictionary<uint, bool>();
|
||||
|
||||
public bool StartOperation(string key)
|
||||
{
|
||||
DataVersion.Increment();
|
||||
return dicOperating.TryAdd(key, true);
|
||||
}
|
||||
public void StopOperation(string key)
|
||||
{
|
||||
DataVersion.Increment();
|
||||
dicOperating.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
public bool StartOperation(uint key)
|
||||
{
|
||||
DataVersion.Increment();
|
||||
return dicOperating1.TryAdd(key, true);
|
||||
}
|
||||
public void StopOperation(uint key)
|
||||
{
|
||||
DataVersion.Increment();
|
||||
dicOperating1.TryRemove(key, out _);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,93 @@
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.signin;
|
||||
using linker.libs.timer;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.messenger.channel
|
||||
{
|
||||
public class Channel
|
||||
public sealed class ChannelConnectionCaching
|
||||
{
|
||||
public VersionManager Version { get; } = new VersionManager();
|
||||
public ConcurrentDictionary<string, ConcurrentDictionary<string, ITunnelConnection>> Connections { get; } = new();
|
||||
|
||||
public ConcurrentDictionary<string, ITunnelConnection> this[string transactionId]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Connections.TryGetValue(transactionId, out ConcurrentDictionary<string, ITunnelConnection> _connections) == false)
|
||||
{
|
||||
_connections = new ConcurrentDictionary<string, ITunnelConnection>();
|
||||
Connections.TryAdd(transactionId, _connections);
|
||||
}
|
||||
return _connections;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetValue(string machineId, string transactionId, out ITunnelConnection connection)
|
||||
{
|
||||
connection = null;
|
||||
if (Connections.TryGetValue(transactionId, out ConcurrentDictionary<string, ITunnelConnection> _connections))
|
||||
{
|
||||
return _connections.TryGetValue(machineId, out connection);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void Add(ITunnelConnection connection)
|
||||
{
|
||||
if (Connections.TryGetValue(connection.TransactionId, out ConcurrentDictionary<string, ITunnelConnection> _connections) == false)
|
||||
{
|
||||
_connections = new ConcurrentDictionary<string, ITunnelConnection>();
|
||||
Connections.TryAdd(connection.TransactionId, _connections);
|
||||
}
|
||||
_connections.AddOrUpdate(connection.RemoteMachineId, connection, (a, b) => connection);
|
||||
Version.Increment();
|
||||
}
|
||||
public void Remove(string machineId, string transactionId)
|
||||
{
|
||||
if (Connections.TryGetValue(transactionId, out ConcurrentDictionary<string, ITunnelConnection> _connections))
|
||||
{
|
||||
if (_connections.TryRemove(machineId, out ITunnelConnection _connection))
|
||||
{
|
||||
try
|
||||
{
|
||||
_connection.Dispose();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
Version.Increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public class Channel
|
||||
{
|
||||
public VersionManager Version => channelConnectionCaching.Version;
|
||||
public ConcurrentDictionary<string, ITunnelConnection> Connections => channelConnectionCaching[TransactionId];
|
||||
|
||||
protected virtual string TransactionId { get; }
|
||||
protected readonly ConcurrentDictionary<string, ITunnelConnection> connections = new ConcurrentDictionary<string, ITunnelConnection>();
|
||||
|
||||
private readonly TunnelTransfer tunnelTransfer;
|
||||
private readonly RelayClientTransfer relayTransfer;
|
||||
private readonly PcpTransfer pcpTransfer;
|
||||
private readonly SignInClientTransfer signInClientTransfer;
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
private readonly IRelayClientStore relayClientStore;
|
||||
private readonly ChannelConnectionCaching channelConnectionCaching;
|
||||
|
||||
public Channel(TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, SignInClientTransfer signInClientTransfer, ISignInClientStore signInClientStore, IRelayClientStore relayClientStore)
|
||||
public Channel(TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, ISignInClientStore signInClientStore, ChannelConnectionCaching channelConnectionCaching)
|
||||
{
|
||||
this.tunnelTransfer = tunnelTransfer;
|
||||
this.relayTransfer = relayTransfer;
|
||||
this.pcpTransfer = pcpTransfer;
|
||||
this.signInClientTransfer = signInClientTransfer;
|
||||
this.signInClientStore = signInClientStore;
|
||||
this.relayClientStore = relayClientStore;
|
||||
this.channelConnectionCaching = channelConnectionCaching;
|
||||
|
||||
//监听打洞成功
|
||||
tunnelTransfer.SetConnectedCallback(TransactionId, OnConnected);
|
||||
@@ -54,15 +110,11 @@ namespace linker.messenger.channel
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
LoggerHelper.Instance.Warning($"{TransactionId} add connection {connection.GetHashCode()} {connection.ToJson()}");
|
||||
|
||||
if (connections.TryGetValue(connection.RemoteMachineId, out ITunnelConnection connectionOld) && connection.Equals(connectionOld) == false)
|
||||
if (channelConnectionCaching.TryGetValue(connection.RemoteMachineId, TransactionId, out ITunnelConnection connectionOld) && connection.Equals(connectionOld) == false)
|
||||
{
|
||||
connections.AddOrUpdate(connection.RemoteMachineId, connection, (a, b) => connection);
|
||||
TimerHelper.SetTimeout(connectionOld.Dispose, 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
connections.AddOrUpdate(connection.RemoteMachineId, connection, (a, b) => connection);
|
||||
}
|
||||
channelConnectionCaching.Add(connection);
|
||||
Version.Increment();
|
||||
|
||||
Connected(connection);
|
||||
@@ -86,7 +138,7 @@ namespace linker.messenger.channel
|
||||
return null;
|
||||
}
|
||||
//之前这个客户端已经连接过
|
||||
if (connections.TryGetValue(machineId, out ITunnelConnection connection) && connection.Connected)
|
||||
if (channelConnectionCaching.TryGetValue(machineId, TransactionId, out ITunnelConnection connection) && connection.Connected)
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
@@ -99,7 +151,7 @@ namespace linker.messenger.channel
|
||||
}
|
||||
|
||||
//获得锁再次看看之前有没有连接成功
|
||||
if (connections.TryGetValue(machineId, out connection) && connection.Connected)
|
||||
if (channelConnectionCaching.TryGetValue(machineId, TransactionId, out connection) && connection.Connected)
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
@@ -113,7 +165,7 @@ namespace linker.messenger.channel
|
||||
|
||||
if (connection != null)
|
||||
{
|
||||
connections.AddOrUpdate(machineId, connection, (a, b) => connection);
|
||||
channelConnectionCaching.Add(connection);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -148,7 +200,7 @@ namespace linker.messenger.channel
|
||||
//后台打洞
|
||||
tunnelTransfer.StartBackground(machineId, TransactionId, denyProtocols, () =>
|
||||
{
|
||||
return connections.TryGetValue(machineId, out ITunnelConnection connection) && connection.Connected && connection.Type == TunnelType.P2P;
|
||||
return channelConnectionCaching.TryGetValue(machineId, TransactionId, out ITunnelConnection connection) && connection.Connected && connection.Type == TunnelType.P2P;
|
||||
}, async (_connection) =>
|
||||
{
|
||||
//后台打洞失败,pcp
|
||||
@@ -181,31 +233,5 @@ namespace linker.messenger.channel
|
||||
return connection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取隧道
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ConcurrentDictionary<string, ITunnelConnection> GetConnections()
|
||||
{
|
||||
return connections;
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除隧道
|
||||
/// </summary>
|
||||
/// <param name="machineId"></param>
|
||||
public void RemoveConnection(string machineId)
|
||||
{
|
||||
if (connections.TryRemove(machineId, out ITunnelConnection _connection))
|
||||
{
|
||||
try
|
||||
{
|
||||
_connection.Dispose();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
Version.Increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
53
src/linker.messenger.channel/ChannelApiController.cs
Normal file
53
src/linker.messenger.channel/ChannelApiController.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using linker.libs.extends;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.tunnel.connection;
|
||||
using linker.messenger.api;
|
||||
using linker.libs.web;
|
||||
|
||||
namespace linker.messenger.channel
|
||||
{
|
||||
public sealed class ChannelApiController : IApiController
|
||||
{
|
||||
private readonly ChannelConnectionCaching channelConnectionCaching;
|
||||
public ChannelApiController(ChannelConnectionCaching channelConnectionCaching)
|
||||
{
|
||||
this.channelConnectionCaching = channelConnectionCaching;
|
||||
}
|
||||
|
||||
public ConnectionListInfo Get(ApiControllerParamsInfo param)
|
||||
{
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (channelConnectionCaching.Version.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new ConnectionListInfo
|
||||
{
|
||||
List = channelConnectionCaching.Connections,
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
return new ConnectionListInfo { HashCode = version };
|
||||
}
|
||||
|
||||
[Access(AccessValue.TunnelRemove)]
|
||||
public void Remove(ApiControllerParamsInfo param)
|
||||
{
|
||||
RemoveInfo info = param.Content.DeJson<RemoveInfo>();
|
||||
channelConnectionCaching.Remove(info.MachineId, info.TransactionId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public sealed class RemoveInfo
|
||||
{
|
||||
public string MachineId { get; set; }
|
||||
public string TransactionId { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ConnectionListInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, ConcurrentDictionary<string, ITunnelConnection>> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
23
src/linker.messenger.channel/Entry.cs
Normal file
23
src/linker.messenger.channel/Entry.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using linker.libs.web;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Text.Json;
|
||||
namespace linker.messenger.channel
|
||||
{
|
||||
public static class Entry
|
||||
{
|
||||
public static ServiceCollection AddChannelClient(this ServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddSingleton<ChannelApiController>();
|
||||
serviceCollection.AddSingleton<ChannelConnectionCaching>();
|
||||
|
||||
return serviceCollection;
|
||||
}
|
||||
public static ServiceProvider UseChannelClient(this ServiceProvider serviceProvider, JsonDocument json = default)
|
||||
{
|
||||
linker.messenger.api.IWebServer apiServer = serviceProvider.GetService<linker.messenger.api.IWebServer>();
|
||||
apiServer.AddPlugins(new List<IApiController> { serviceProvider.GetService<ChannelApiController>() });
|
||||
|
||||
return serviceProvider;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ using System.Text.Json;
|
||||
using linker.messenger.firewall;
|
||||
using linker.messenger.wakeup;
|
||||
using linker.messenger.wlist;
|
||||
using linker.messenger.channel;
|
||||
|
||||
namespace linker.messenger.entry
|
||||
{
|
||||
@@ -68,7 +69,7 @@ namespace linker.messenger.entry
|
||||
.AddPcpClient().AddPcpServer()
|
||||
//中继
|
||||
.AddRelayClient().AddRelayServer()
|
||||
|
||||
|
||||
//服务器穿透
|
||||
.AddSForwardClient().AddSForwardServer()
|
||||
//登录
|
||||
@@ -104,7 +105,9 @@ namespace linker.messenger.entry
|
||||
.AddWakeupClient().AddWakeupServer()
|
||||
|
||||
//白名单
|
||||
.AddWhiteListClient().AddWhiteListServer();
|
||||
.AddWhiteListClient().AddWhiteListServer()
|
||||
|
||||
.AddChannelClient();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
@@ -160,8 +163,6 @@ namespace linker.messenger.entry
|
||||
|
||||
ICommonStore commonStore = serviceProvider.GetService<ICommonStore>();
|
||||
|
||||
|
||||
|
||||
serviceProvider.UseMessenger();
|
||||
|
||||
if ((modules & ExcludeModule.StoreFile) != ExcludeModule.StoreFile)
|
||||
@@ -228,6 +229,8 @@ namespace linker.messenger.entry
|
||||
serviceProvider.UseSignInClient();
|
||||
|
||||
serviceProvider.UsePlanClient();
|
||||
|
||||
serviceProvider.UseChannelClient();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.forward.proxy;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
@@ -18,7 +19,8 @@ namespace linker.messenger.flow
|
||||
private readonly FlowForward forwardFlow;
|
||||
private readonly FlowTunnel flowTunnel;
|
||||
public FlowForwardProxy(FlowForward forwardFlow, FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore) : base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, relayClientStore)
|
||||
SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, channelConnectionCaching)
|
||||
{
|
||||
this.forwardFlow = forwardFlow;
|
||||
this.flowTunnel = flowTunnel;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
@@ -19,7 +20,8 @@ namespace linker.messenger.flow
|
||||
private readonly FlowTunnel flowTunnel;
|
||||
|
||||
public FlowSocks5Proxy(FlowSocks5 flowSocks5, FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore, Socks5CidrDecenterManager socks5CidrDecenterManager) : base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, relayClientStore, socks5CidrDecenterManager)
|
||||
SignInClientTransfer signInClientTransfer, Socks5CidrDecenterManager socks5CidrDecenterManager, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, socks5CidrDecenterManager, channelConnectionCaching)
|
||||
{
|
||||
this.flowSocks5 = flowSocks5;
|
||||
this.flowTunnel = flowTunnel;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
@@ -18,11 +19,11 @@ namespace linker.messenger.flow
|
||||
private readonly FlowTunnel flowTunnel;
|
||||
|
||||
public FlowTuntapProxy(FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore, TuntapConfigTransfer tuntapConfigTransfer,
|
||||
SignInClientTransfer signInClientTransfer, TuntapConfigTransfer tuntapConfigTransfer,
|
||||
TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager,
|
||||
TuntapCidrMapfileManager tuntapCidrMapfileManager,TuntapDecenter tuntapDecenter)
|
||||
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, relayClientStore,
|
||||
tuntapConfigTransfer, tuntapCidrConnectionManager, tuntapCidrDecenterManager, tuntapCidrMapfileManager, tuntapDecenter)
|
||||
TuntapCidrMapfileManager tuntapCidrMapfileManager,TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer,
|
||||
tuntapConfigTransfer, tuntapCidrConnectionManager, tuntapCidrDecenterManager, tuntapCidrMapfileManager, tuntapDecenter, channelConnectionCaching)
|
||||
{
|
||||
this.flowTunnel = flowTunnel;
|
||||
}
|
||||
|
||||
@@ -31,35 +31,7 @@ namespace linker.messenger.forward
|
||||
this.serializer = serializer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取隧道连接
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public ConnectionListInfo Connections(ApiControllerParamsInfo param)
|
||||
{
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (forwardProxy.Version.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new ConnectionListInfo
|
||||
{
|
||||
List = forwardProxy.GetConnections(),
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
return new ConnectionListInfo { HashCode = version };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除隧道连接
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
[Access(AccessValue.TunnelRemove)]
|
||||
public void RemoveConnection(ApiControllerParamsInfo param)
|
||||
{
|
||||
forwardProxy.RemoveConnection(param.Content);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取绑定IP列表
|
||||
/// </summary>
|
||||
@@ -165,14 +137,4 @@ namespace linker.messenger.forward
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ForwardListInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, int> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
public sealed class ConnectionListInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, ITunnelConnection> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace linker.messenger.forward.proxy
|
||||
protected override string TransactionId => "forward";
|
||||
|
||||
public ForwardProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, relayClientStore)
|
||||
SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
{
|
||||
TaskUdp();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using linker.messenger.relay.messenger;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.sync;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
@@ -72,10 +73,20 @@ namespace linker.messenger.relay.client
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public ConcurrentDictionary<string, bool> Operating(ApiControllerParamsInfo param)
|
||||
public RelayOperatingInfo Operating(ApiControllerParamsInfo param)
|
||||
{
|
||||
return relayTransfer.Operating;
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (relayTransfer.OperatingVersion.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new RelayOperatingInfo
|
||||
{
|
||||
List = relayTransfer.Operating,
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
return new RelayOperatingInfo { HashCode = version };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接
|
||||
/// </summary>
|
||||
@@ -146,6 +157,14 @@ namespace linker.messenger.relay.client
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public sealed class RelayOperatingInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, bool> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
|
||||
public sealed class UpdateInfo
|
||||
{
|
||||
public string Key { get; set; }
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace linker.messenger.relay.client
|
||||
{
|
||||
public List<IRelayClientTransport> Transports { get; private set; }
|
||||
|
||||
|
||||
public VersionManager OperatingVersion => operating.DataVersion;
|
||||
public ConcurrentDictionary<string, bool> Operating => operating.StringKeyValue;
|
||||
private OperatingMultipleManager operating = new OperatingMultipleManager();
|
||||
private readonly OperatingMultipleManager operating = new OperatingMultipleManager();
|
||||
|
||||
private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>();
|
||||
|
||||
@@ -77,7 +77,6 @@ namespace linker.messenger.relay.client
|
||||
if (string.IsNullOrWhiteSpace(nodeId)) nodeId = relayClientStore.DefaultNodeId;
|
||||
if(protocol == TunnelProtocolType.None) protocol = relayClientStore.DefaultProtocol;
|
||||
|
||||
|
||||
if (operating.StartOperation(BuildKey(remoteMachineId, transactionId)) == false)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -30,26 +30,6 @@ namespace linker.messenger.socks5
|
||||
this.accessStore = accessStore;
|
||||
}
|
||||
|
||||
public ConnectionListInfo Connections(ApiControllerParamsInfo param)
|
||||
{
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (tunnelProxy.Version.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new ConnectionListInfo
|
||||
{
|
||||
List = tunnelProxy.GetConnections(),
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
return new ConnectionListInfo { HashCode = version };
|
||||
}
|
||||
|
||||
[Access(AccessValue.TunnelRemove)]
|
||||
public void RemoveConnection(ApiControllerParamsInfo param)
|
||||
{
|
||||
tunnelProxy.RemoveConnection(param.Content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有客户端的信息
|
||||
/// </summary>
|
||||
@@ -164,9 +144,4 @@ namespace linker.messenger.socks5
|
||||
public ConcurrentDictionary<string, Socks5Info> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
public sealed class ConnectionListInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, ITunnelConnection> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace linker.messenger.socks5
|
||||
private readonly Socks5CidrDecenterManager socks5CidrDecenterManager;
|
||||
|
||||
public Socks5Proxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore, Socks5CidrDecenterManager socks5CidrDecenterManager)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, relayClientStore)
|
||||
SignInClientTransfer signInClientTransfer, Socks5CidrDecenterManager socks5CidrDecenterManager, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
{
|
||||
this.socks5CidrDecenterManager = socks5CidrDecenterManager;
|
||||
TaskUdp();
|
||||
|
||||
@@ -72,9 +72,18 @@ namespace linker.messenger.tunnel
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public ConcurrentDictionary<string, bool> Operating(ApiControllerParamsInfo param)
|
||||
public TunnelOperatingInfo Operating(ApiControllerParamsInfo param)
|
||||
{
|
||||
return tunnelTransfer.Operating;
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (tunnelTransfer.OperatingVersion.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new TunnelOperatingInfo
|
||||
{
|
||||
List = tunnelTransfer.Operating,
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
return new TunnelOperatingInfo { HashCode = version };
|
||||
}
|
||||
/// <summary>
|
||||
/// 连接
|
||||
@@ -187,6 +196,11 @@ namespace linker.messenger.tunnel
|
||||
return new TunnelLocalNetworkInfo();
|
||||
}
|
||||
|
||||
public sealed class TunnelOperatingInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, bool> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
public sealed class TunnelListInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, TunnelRouteLevelInfo> List { get; set; }
|
||||
|
||||
@@ -46,36 +46,6 @@ namespace linker.messenger.tuntap
|
||||
this.tuntapProxy = tuntapProxy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public ConnectionListInfo Connections(ApiControllerParamsInfo param)
|
||||
{
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (tuntapProxy.Version.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new ConnectionListInfo
|
||||
{
|
||||
List = tuntapProxy.GetConnections(),
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
return new ConnectionListInfo { HashCode = version };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除连接
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
[Access(AccessValue.TunnelRemove)]
|
||||
public void RemoveConnection(ApiControllerParamsInfo param)
|
||||
{
|
||||
tuntapProxy.RemoveConnection(param.Content);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 路由表
|
||||
/// </summary>
|
||||
@@ -363,12 +333,6 @@ namespace linker.messenger.tuntap
|
||||
public ConcurrentDictionary<string, TuntapInfo> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
public sealed class ConnectionListInfo
|
||||
{
|
||||
public ConcurrentDictionary<string, ITunnelConnection> List { get; set; }
|
||||
public ulong HashCode { get; set; }
|
||||
}
|
||||
|
||||
public sealed class NetworkParamInfo
|
||||
{
|
||||
public IPAddress IP { get; set; }
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace linker.messenger.tuntap
|
||||
var items = tuntapDecenter.Infos.Values.Where(c => c.IP != null && c.IP.Equals(IPAddress.Any) == false && (c.Status & TuntapStatus.Running) == TuntapStatus.Running);
|
||||
if ((tuntapConfigTransfer.Info.Switch & TuntapSwitch.AutoConnect) != TuntapSwitch.AutoConnect)
|
||||
{
|
||||
var connections = tuntapProxy.GetConnections();
|
||||
var connections = tuntapProxy.Connections;
|
||||
items = items.Where(c => connections.TryGetValue(c.MachineId, out ITunnelConnection connection) && connection.Connected || c.MachineId == signInClientStore.Id);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using System.Buffers.Binary;
|
||||
using linker.libs;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.tuntap.cidr;
|
||||
using linker.nat;
|
||||
using linker.tun.device;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
namespace linker.messenger.tuntap
|
||||
{
|
||||
@@ -31,8 +32,10 @@ namespace linker.messenger.tuntap
|
||||
|
||||
public TuntapProxy(ISignInClientStore signInClientStore,
|
||||
TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore, TuntapConfigTransfer tuntapConfigTransfer, TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager, TuntapCidrMapfileManager tuntapCidrMapfileManager, TuntapDecenter tuntapDecenter)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, relayClientStore)
|
||||
SignInClientTransfer signInClientTransfer, TuntapConfigTransfer tuntapConfigTransfer,
|
||||
TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager,
|
||||
TuntapCidrMapfileManager tuntapCidrMapfileManager, TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
{
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
this.tuntapCidrConnectionManager = tuntapCidrConnectionManager;
|
||||
@@ -85,9 +88,9 @@ namespace linker.messenger.tuntap
|
||||
public async Task InputPacket(LinkerTunDevicPacket packet)
|
||||
{
|
||||
//IPV4广播组播、IPV6 多播
|
||||
if ((packet.IPV4Broadcast || packet.IPV6Multicast) && tuntapConfigTransfer.Info.Multicast == false && connections.IsEmpty == false)
|
||||
if ((packet.IPV4Broadcast || packet.IPV6Multicast) && tuntapConfigTransfer.Info.Multicast == false && Connections.IsEmpty == false)
|
||||
{
|
||||
await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Buffer, packet.Offset, packet.Length)));
|
||||
await Task.WhenAll(Connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Buffer, packet.Offset, packet.Length))).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace linker.tunnel
|
||||
private readonly TunnelWanPortTransfer tunnelWanPortTransfer;
|
||||
private readonly TunnelUpnpTransfer tunnelUpnpTransfer;
|
||||
|
||||
public VersionManager OperatingVersion => operating.DataVersion;
|
||||
public ConcurrentDictionary<string, bool> Operating => operating.StringKeyValue;
|
||||
private readonly OperatingMultipleManager operating = new OperatingMultipleManager();
|
||||
private uint flowid = 1;
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
export const getForwardConnections = (hashcode = '0') => {
|
||||
return sendWebsocketMsg('forward/connections', hashcode);
|
||||
}
|
||||
export const removeForwardConnection = (id) => {
|
||||
return sendWebsocketMsg('forward/removeconnection', id);
|
||||
}
|
||||
export const getForwardInfo = (hashcode = '0') => {
|
||||
return sendWebsocketMsg('forward/get', hashcode);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ export const setRelayServers = (servers) => {
|
||||
export const setRelaySubscribe = () => {
|
||||
return sendWebsocketMsg('relay/Subscribe');
|
||||
}
|
||||
export const relayOperating = () => {
|
||||
return sendWebsocketMsg('relay/Operating');
|
||||
export const relayOperating = (data) => {
|
||||
return sendWebsocketMsg('relay/Operating',data);
|
||||
}
|
||||
export const relayConnect = (data) => {
|
||||
return sendWebsocketMsg('relay/Connect', data);
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
|
||||
export const getSocks5Connections = (hashcode = '0') => {
|
||||
return sendWebsocketMsg('socks5/connections', hashcode);
|
||||
}
|
||||
export const removeSocks5Connection = (id) => {
|
||||
return sendWebsocketMsg('socks5/removeconnection', id);
|
||||
}
|
||||
|
||||
export const getSocks5Info = (hashcode = '0') => {
|
||||
return sendWebsocketMsg('socks5/get', hashcode);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ export const getTunnelInfo = (hashcode = '0') => {
|
||||
export const tunnelRefresh = () => {
|
||||
return sendWebsocketMsg('tunnel/refresh');
|
||||
}
|
||||
export const tunnelOperating = () => {
|
||||
return sendWebsocketMsg('tunnel/Operating');
|
||||
export const tunnelOperating = (data) => {
|
||||
return sendWebsocketMsg('tunnel/Operating',data);
|
||||
}
|
||||
export const tunnelConnect = (data) => {
|
||||
return sendWebsocketMsg('tunnel/connect',data);
|
||||
@@ -29,4 +29,11 @@ export const getTunnelRecords = () => {
|
||||
}
|
||||
export const getTunnelNetwork = (data) => {
|
||||
return sendWebsocketMsg('tunnel/GetNetwork',data);
|
||||
}
|
||||
|
||||
export const getTunnelConnections = (hashcode) => {
|
||||
return sendWebsocketMsg('channel/get',hashcode);
|
||||
}
|
||||
export const removeTunnelConnection = (machineid,transactionId) => {
|
||||
return sendWebsocketMsg('channel/remove',{machineid,transactionId});
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
import { sendWebsocketMsg } from './request'
|
||||
|
||||
|
||||
export const getTuntapConnections = (hashcode = '0') => {
|
||||
return sendWebsocketMsg('tuntap/connections', hashcode);
|
||||
}
|
||||
export const removeTuntapConnection = (id) => {
|
||||
return sendWebsocketMsg('tuntap/removeconnection', id);
|
||||
}
|
||||
|
||||
export const getTuntapRoutes = (machineid) => {
|
||||
return sendWebsocketMsg('tuntap/routes', machineid);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ export const provideAccess = () => {
|
||||
});
|
||||
});
|
||||
}
|
||||
const accessProcessFn = (device) => {
|
||||
Object.assign(device,{
|
||||
const accessProcessFn = (device,json) => {
|
||||
Object.assign(json,{
|
||||
hook_accesss: access.value.list[device.MachineId] || ''
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
import { getForwardConnections, removeForwardConnection } from "@/apis/forward";
|
||||
import { getTuntapConnections, removeTuntapConnection } from "@/apis/tuntap";
|
||||
import { getSocks5Connections, removeSocks5Connection } from "@/apis/socks5";
|
||||
import { inject, provide, ref } from "vue";
|
||||
|
||||
const connectionsSymbol = Symbol();
|
||||
const forwardConnectionsSymbol = Symbol();
|
||||
const tuntapConnectionsSymbol = Symbol();
|
||||
const socks5ConnectionsSymbol = Symbol();
|
||||
export const provideConnections = () => {
|
||||
const connections = ref({
|
||||
showEdit: false,
|
||||
speedCache: {},
|
||||
current: '',
|
||||
currentName: '',
|
||||
hashcode: 0,
|
||||
hashcode1: 0,
|
||||
|
||||
_updateRealTime: false,
|
||||
updateRealTime: (value) => {
|
||||
forwardConnections.value.hashcode = 0;
|
||||
tuntapConnections.value.hashcode = 0;
|
||||
socks5Connections.value.hashcode = 0;
|
||||
connections.value._updateRealTime = value;
|
||||
}
|
||||
});
|
||||
provide(connectionsSymbol, connections);
|
||||
|
||||
const forwardConnections = ref({
|
||||
timer: 0,
|
||||
list: {},
|
||||
hashcode: 0,
|
||||
});
|
||||
provide(forwardConnectionsSymbol, forwardConnections);
|
||||
const _getForwardConnections = () => {
|
||||
clearTimeout(forwardConnections.value.timer)
|
||||
getForwardConnections(forwardConnections.value.hashcode.toString()).then((res) => {
|
||||
if (forwardConnections.value._updateRealTime == false)
|
||||
forwardConnections.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
parseConnections(res.List, removeForwardConnection);
|
||||
forwardConnections.value.list = res.List;
|
||||
}
|
||||
|
||||
forwardConnections.value.timer = setTimeout(_getForwardConnections, 1000);
|
||||
}).catch((e) => {
|
||||
forwardConnections.value.timer = setTimeout(_getForwardConnections, 1000);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const tuntapConnections = ref({
|
||||
timer: 0,
|
||||
list: {},
|
||||
hashcode: 0,
|
||||
});
|
||||
provide(tuntapConnectionsSymbol, tuntapConnections);
|
||||
const _getTuntapConnections = () => {
|
||||
clearTimeout(tuntapConnections.value.timer)
|
||||
getTuntapConnections(tuntapConnections.value.hashcode.toString()).then((res) => {
|
||||
if (connections.value._updateRealTime == false)
|
||||
tuntapConnections.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
parseConnections(res.List, removeTuntapConnection);
|
||||
tuntapConnections.value.list = res.List;
|
||||
}
|
||||
|
||||
tuntapConnections.value.timer = setTimeout(_getTuntapConnections, 1000);
|
||||
}).catch((e) => {
|
||||
tuntapConnections.value.timer = setTimeout(_getTuntapConnections, 1000);
|
||||
})
|
||||
}
|
||||
|
||||
const socks5Connections = ref({
|
||||
timer: 0,
|
||||
list: {},
|
||||
hashcode: 0,
|
||||
});
|
||||
provide(socks5ConnectionsSymbol, socks5Connections);
|
||||
const _getSocks5Connections = () => {
|
||||
clearTimeout(socks5Connections.value.timer)
|
||||
getSocks5Connections(socks5Connections.value.hashcode.toString()).then((res) => {
|
||||
if (connections.value._updateRealTime == false)
|
||||
socks5Connections.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
parseConnections(res.List, removeSocks5Connection);
|
||||
socks5Connections.value.list = res.List;
|
||||
}
|
||||
|
||||
socks5Connections.value.timer = setTimeout(_getSocks5Connections, 1000);
|
||||
}).catch((e) => {
|
||||
socks5Connections.value.timer = setTimeout(_getSocks5Connections, 1000);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const parseConnections = (_connections, removeFunc) => {
|
||||
const caches = connections.value.speedCache;
|
||||
for (let machineId in _connections) {
|
||||
const connection = _connections[machineId];
|
||||
connection.removeFunc = removeFunc;
|
||||
|
||||
const key = `${connection.RemoteMachineId}-${connection.TransactionId}`;
|
||||
const cache = caches[key] || { SendBytes: 0, ReceiveBytes: 0 };
|
||||
|
||||
connection.SendBytesText = parseSpeed(connection.SendBytes - cache.SendBytes,'/s');
|
||||
connection.ReceiveBytesText = parseSpeed(connection.ReceiveBytes - cache.ReceiveBytes,'/s');
|
||||
connection.SendBufferRemainingText = parseSpeed(connection.SendBufferRemaining,'');
|
||||
connection.RecvBufferRemainingText = parseSpeed(connection.RecvBufferRemaining || 0,'');
|
||||
|
||||
cache.SendBytes = connection.SendBytes;
|
||||
cache.ReceiveBytes = connection.ReceiveBytes;
|
||||
caches[key] = cache;
|
||||
}
|
||||
}
|
||||
const parseSpeed = (num,subfix = '') => {
|
||||
let index = 0;
|
||||
while (num >= 1024) {
|
||||
num /= 1024;
|
||||
index++;
|
||||
}
|
||||
return `${num.toFixed(2)}${['B', 'KB', 'MB', 'GB', 'TB'][index]}${subfix}`;
|
||||
}
|
||||
|
||||
const handleTunnelConnections = (device) => {
|
||||
connections.value.current = device.MachineId;
|
||||
connections.value.currentName = device.MachineName;
|
||||
connections.value.showEdit = true;
|
||||
}
|
||||
|
||||
|
||||
const clearConnectionsTimeout = () => {
|
||||
clearTimeout(forwardConnections.value.timer);
|
||||
clearTimeout(tuntapConnections.value.timer);
|
||||
clearTimeout(socks5Connections.value.timer);
|
||||
}
|
||||
return {
|
||||
connections,
|
||||
forwardConnections, _getForwardConnections,
|
||||
tuntapConnections, _getTuntapConnections,
|
||||
socks5Connections, _getSocks5Connections,
|
||||
handleTunnelConnections, clearConnectionsTimeout
|
||||
}
|
||||
}
|
||||
export const useConnections = () => {
|
||||
return inject(connectionsSymbol);
|
||||
}
|
||||
export const useForwardConnections = () => {
|
||||
return inject(forwardConnectionsSymbol);
|
||||
}
|
||||
export const useTuntapConnections = () => {
|
||||
return inject(tuntapConnectionsSymbol);
|
||||
}
|
||||
export const useSocks5Connections = () => {
|
||||
return inject(socks5ConnectionsSymbol);
|
||||
}
|
||||
@@ -25,10 +25,14 @@ export const provideDecenter = () => {
|
||||
});
|
||||
|
||||
}
|
||||
const counterProcessFn = (device) => {
|
||||
Object.assign(device,{
|
||||
hook_counter: decenter.value.list[device.MachineId] || ''
|
||||
})
|
||||
const counterProcessFn = (device,json) => {
|
||||
const _json = {};
|
||||
for (const key in decenter.value.list) {
|
||||
_json[key] = decenter.value.list[key][device.MachineId] || 0;
|
||||
}
|
||||
Object.assign(json,{
|
||||
hook_counter: _json
|
||||
});
|
||||
}
|
||||
const counterRefreshFn = () => {
|
||||
refreshCounter();
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
<p class="flex">
|
||||
<template v-if="scope.row.Connected">
|
||||
<div>
|
||||
<template v-if="tuntap.list[scope.row.MachineId] && tuntap.list[scope.row.MachineId].systems">
|
||||
<template v-for="system in tuntap.list[scope.row.MachineId].systems">
|
||||
<span :title="tuntap.list[scope.row.MachineId].SystemInfo">
|
||||
<template v-if="scope.row.hook_tuntap && scope.row.hook_tuntap.systems">
|
||||
<template v-for="system in scope.row.hook_tuntap.systems">
|
||||
<span :title="scope.row.hook_tuntap.SystemInfo">
|
||||
<img class="system" :src="`./${system}.svg`" />
|
||||
</span>
|
||||
</template>
|
||||
@@ -27,7 +27,7 @@
|
||||
</span>
|
||||
|
||||
<span class="flex-1"></span>
|
||||
<UpdaterBtn v-if="scope.row.showip == false" :config="true" :item="scope.row"></UpdaterBtn>
|
||||
<UpdaterBtn :config="true" :item="scope.row"></UpdaterBtn>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>{{ scope.row.LastSignIn }}</span>
|
||||
@@ -42,14 +42,12 @@ import { ref } from 'vue';
|
||||
import {Search} from '@element-plus/icons-vue'
|
||||
import UpdaterBtn from '../updater/UpdaterBtn.vue';
|
||||
import DeviceName from './DeviceName.vue';
|
||||
import { useTuntap } from '../tuntap/tuntap';
|
||||
|
||||
export default {
|
||||
emits:['refresh'],
|
||||
components:{Search,UpdaterBtn,DeviceName},
|
||||
setup(props,{emit}) {
|
||||
|
||||
const tuntap = useTuntap();
|
||||
const name = ref(sessionStorage.getItem('search-name') || '');
|
||||
|
||||
const handleRefresh = ()=>{
|
||||
@@ -58,7 +56,7 @@ export default {
|
||||
}
|
||||
|
||||
return {
|
||||
tuntap,name, handleRefresh
|
||||
name, handleRefresh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export const provideDevices = () => {
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const devices = reactive({
|
||||
timer: 0,
|
||||
timer1: 0,
|
||||
page: {
|
||||
Request: {
|
||||
Page: 1, Size: +(localStorage.getItem('ps') || '10'), Name: '', Ids: [], Prop: '', Asc: true
|
||||
@@ -25,18 +26,32 @@ export const provideDevices = () => {
|
||||
provide(deviceSymbol, devices);
|
||||
|
||||
const hooks = {};
|
||||
const addDeviceHook = (name,dataFn,processFn,refreshFn) => {
|
||||
hooks[name] = {dataFn,processFn,refreshFn,changed:true};
|
||||
const deviceAddHook = (name,dataFn,processFn,refreshFn) => {
|
||||
hooks[name] = {dataFn,processFn,refreshFn,changed:true,refresh:true};
|
||||
}
|
||||
const deviceRefreshHook = (name) => {
|
||||
if(hooks[name]) {
|
||||
hooks[name].changed = true;
|
||||
}
|
||||
}
|
||||
const startHooks = () => {
|
||||
const fn = async ()=>{
|
||||
for (let j in devices.page.List) {
|
||||
for(let name in hooks) {
|
||||
const hook = hooks[name];
|
||||
if(hook.changed) {
|
||||
hook.changed = false;
|
||||
hook.refreshFn();
|
||||
hook.processFn(devices.page.List[j]);
|
||||
clearTimeout(devices.timer1);
|
||||
for(let name in hooks) {
|
||||
const hook = hooks[name];
|
||||
if(hook.refresh) {
|
||||
hook.refresh = false;
|
||||
hook.refreshFn();
|
||||
}
|
||||
}
|
||||
for(let name in hooks) {
|
||||
const hook = hooks[name];
|
||||
if(hook.changed) {
|
||||
hook.changed = false;
|
||||
for (let i = 0; i< devices.page.List.length; i++) {
|
||||
const json = {}
|
||||
hook.processFn(devices.page.List[i],json);
|
||||
Object.assign(devices.page.List[i], json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,13 +59,13 @@ export const provideDevices = () => {
|
||||
const hook = hooks[name];
|
||||
hook.changed = await hook.dataFn();
|
||||
}
|
||||
setTimeout(fn,1000);
|
||||
devices.timer1 = setTimeout(fn,1000);
|
||||
}
|
||||
fn();
|
||||
}
|
||||
startHooks();
|
||||
|
||||
const startDeviceProcess = () => {
|
||||
const deviceStartProcess = () => {
|
||||
_getSignList().then(()=>{
|
||||
startHooks();
|
||||
_getSignList1();
|
||||
@@ -66,8 +81,7 @@ export const provideDevices = () => {
|
||||
showDel: machineId.value != res.List[j].MachineId && res.List[j].Connected == false,
|
||||
showAccess: machineId.value != res.List[j].MachineId && res.List[j].Connected,
|
||||
showReboot: res.List[j].Connected,
|
||||
isSelf: machineId.value == res.List[j].MachineId,
|
||||
showip: false
|
||||
isSelf: machineId.value == res.List[j].MachineId
|
||||
});
|
||||
if (res.List[j].isSelf) {
|
||||
globalData.value.self = res.List[j];
|
||||
@@ -120,9 +134,11 @@ export const provideDevices = () => {
|
||||
}
|
||||
_getSignList();
|
||||
}
|
||||
const clearDevicesTimeout = () => {
|
||||
const deviceClearTimeout = () => {
|
||||
clearTimeout(devices.timer);
|
||||
clearTimeout(devices.timer1);
|
||||
devices.timer = 0;
|
||||
devices.timer1 = 0;
|
||||
}
|
||||
|
||||
const setSort = (ids) => {
|
||||
@@ -130,7 +146,7 @@ export const provideDevices = () => {
|
||||
}
|
||||
|
||||
return {
|
||||
devices,addDeviceHook, startDeviceProcess, handlePageChange, handlePageSizeChange, clearDevicesTimeout, setSort
|
||||
devices,deviceAddHook,deviceRefreshHook, deviceStartProcess, handlePageChange, handlePageSizeChange, deviceClearTimeout, setSort
|
||||
}
|
||||
}
|
||||
export const useDevice = () => {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<el-table-column prop="forward" :label="$t('home.forward')" width="80">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.Connected">
|
||||
<template v-if="scope.row.Connected && scope.row.hook_counter">
|
||||
<AccessBoolean value="ForwardOther,ForwardSelf">
|
||||
<template #default="{values}">
|
||||
<template v-if="values.ForwardOther || (values.ForwardSelf && scope.row.isSelf)">
|
||||
<div class="nowrap">
|
||||
<ConnectionShow :data="connections.list[scope.row.MachineId]" :row="scope.row" transitionId="forward"></ConnectionShow>
|
||||
<a href="javascript:;" :class="{green:(scope.row.hook_counter || {forward:0}).forward>0}" @click="handleEdit(scope.row.MachineId,scope.row.MachineName,values)">
|
||||
<span :class="{gateway:(scope.row.hook_counter || {forward:0}).forward>0}">{{$t('home.forwardPort')}}({{(scope.row.hook_counter || {forward:0}).forward>99 ? '99+' : (scope.row.hook_counter || {forward:0}).forward}})</span>
|
||||
<ConnectionShow :row="scope.row" transactionId="forward"></ConnectionShow>
|
||||
<a href="javascript:;" :class="{green:scope.row.hook_counter.forward>0}" @click="handleEdit(scope.row.MachineId,scope.row.MachineName,values)">
|
||||
<span :class="{gateway:scope.row.hook_counter.forward>0}">{{$t('home.forwardPort')}}({{scope.row.hook_counter.forward>99 ? '99+' : scope.row.hook_counter.forward}})</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nowrap">
|
||||
<a href="javascript:;" :class="{green:(scope.row.hook_counter || {sforward:0}).sforward>0}" @click="handleSEdit(scope.row.MachineId,scope.row.MachineName,values)">
|
||||
<span :class="{gateway:(scope.row.hook_counter || {sforward:0}).sforward>0 }">{{$t('home.forwardServer')}}({{(scope.row.hook_counter || {sforward:0}).sforward>99 ? '99+' :(scope.row.hook_counter || {sforward:0}).sforward}})</span>
|
||||
<a href="javascript:;" :class="{green:scope.row.hook_counter.sforward>0}" @click="handleSEdit(scope.row.MachineId,scope.row.MachineName,values)">
|
||||
<span :class="{gateway:scope.row.hook_counter.sforward>0 }">{{$t('home.forwardServer')}}({{scope.row.hook_counter.sforward>99 ? '99+' :scope.row.hook_counter.sforward}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
@@ -28,8 +28,7 @@ import { injectGlobalData } from '@/provide';
|
||||
import { useForward } from './forward';
|
||||
import { useSforward } from './sforward';
|
||||
import { computed } from 'vue';
|
||||
import { useForwardConnections } from '../connection/connections';
|
||||
import ConnectionShow from '../connection/ConnectionShow.vue';
|
||||
import ConnectionShow from '../tunnel/ConnectionShow.vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
export default {
|
||||
@@ -41,7 +40,6 @@ export default {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const connections = useForwardConnections();
|
||||
|
||||
const handleEdit = (_machineId,_machineName,access)=>{
|
||||
if(machineId.value === _machineId){
|
||||
@@ -76,7 +74,7 @@ export default {
|
||||
sforward.value.showEdit = true;
|
||||
}
|
||||
return {
|
||||
connections, handleEdit,handleSEdit
|
||||
handleEdit,handleSEdit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@ import { inject, provide, ref } from "vue"
|
||||
const operSymbol = Symbol();
|
||||
export const provideOper = () => {
|
||||
const oper = ref({
|
||||
device: {id:'',name:''},
|
||||
showFirewall:false,
|
||||
showWakeup:false,
|
||||
showTransport:false,
|
||||
showAction:false,
|
||||
device: {id:'',name:''}
|
||||
});
|
||||
provide(operSymbol, oper);
|
||||
return {
|
||||
|
||||
@@ -1,34 +1,20 @@
|
||||
<template>
|
||||
<el-table-column prop="socks5" :label="socks5.show?$t('home.proxy'):''" width="160">
|
||||
<el-table-column prop="socks5" :label="$t('home.proxy')" width="160">
|
||||
<template #default="scope">
|
||||
<div v-if="socks5.show && socks5.list[scope.row.MachineId]">
|
||||
<Socks5Show :config="true" :item="scope.row" @edit="handleSocks5" @refresh="handleSocks5Refresh"></Socks5Show>
|
||||
<div v-if="scope.row.hook_socks5">
|
||||
<Socks5Show :config="true" :item="scope.row"></Socks5Show>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<script>
|
||||
import { useSocks5 } from './socks5';
|
||||
import Socks5Show from './Socks5Show.vue';
|
||||
export default {
|
||||
emits: ['edit','refresh'],
|
||||
components:{Socks5Show},
|
||||
setup(props, { emit }) {
|
||||
setup() {
|
||||
|
||||
const socks5 = useSocks5();
|
||||
|
||||
const handleSocks5 = (_socks5) => {
|
||||
socks5.value.current = _socks5;
|
||||
socks5.value.showEdit = true;
|
||||
}
|
||||
const handleSocks5Refresh = ()=>{
|
||||
emit('refresh');
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
socks5, handleSocks5,handleSocks5Refresh
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -27,7 +27,6 @@ import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import { useSocks5 } from './socks5';
|
||||
import { Delete, Plus } from '@element-plus/icons-vue'
|
||||
import Socks5Lan from './Socks5Lan.vue';
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
@@ -61,7 +60,7 @@ export default {
|
||||
|
||||
const socks5Dom = ref(null);
|
||||
const handleSave = () => {
|
||||
const json = JSON.parse(JSON.stringify(socks5.value.current));
|
||||
const json = JSON.parse(JSON.stringify(socks5.value.current,(key,value)=> key =='device'?'':value));
|
||||
json.Port = +(state.ruleForm.Port || '1805');
|
||||
json.Lans = socks5Dom.value.getData();
|
||||
updateSocks5(json).then(() => {
|
||||
|
||||
@@ -4,36 +4,36 @@
|
||||
<div>
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<ConnectionShow :data="connections.list[item.MachineId]" :row="item" transitionId="socks5"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleSocks5Port(socks5.list[item.MachineId],values)" title="此设备的socks5代理">
|
||||
<template v-if="socks5.list[item.MachineId].SetupError">
|
||||
<strong class="red" :title="socks5.list[item.MachineId].SetupError">
|
||||
socks5://*:{{ socks5.list[item.MachineId].Port }}
|
||||
<ConnectionShow :row="item" transactionId="socks5"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleSocks5Port(item.hook_socks5,values)" title="此设备的socks5代理">
|
||||
<template v-if="item.hook_socks5.SetupError">
|
||||
<strong class="red" :title="item.hook_socks5.SetupError">
|
||||
socks5://*:{{ item.hook_socks5.Port }}
|
||||
</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="item.Connected &&socks5.list[item.MachineId].running">
|
||||
<strong class="green gateway">socks5://*:{{ socks5.list[item.MachineId].Port }}</strong>
|
||||
<template v-if="item.Connected &&item.hook_socks5.running">
|
||||
<strong class="green gateway">socks5://*:{{ item.hook_socks5.Port }}</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>socks5://*:{{ socks5.list[item.MachineId].Port }}</span>
|
||||
<span>socks5://*:{{ item.hook_socks5.Port }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
<template v-if="socks5.list[item.MachineId].loading">
|
||||
<template v-if="item.hook_socks5.loading">
|
||||
<div>
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-switch :model-value="item.Connected && socks5.list[item.MachineId].running" :loading="socks5.list[item.MachineId].loading" disabled @click="handleSocks5(socks5.list[item.MachineId],values)" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
<el-switch :model-value="item.Connected && item.hook_socks5.running" :loading="item.hook_socks5.loading" disabled @click="handleSocks5(item.hook_socks5,values)" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
</el-switch>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<template v-for="(item1,index) in socks5.list[item.MachineId].Lans" :key="index">
|
||||
<template v-for="(item1,index) in item.hook_socks5.Lans" :key="index">
|
||||
<template v-if="item1.Disabled">
|
||||
<div class="flex disable" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
@@ -41,7 +41,7 @@
|
||||
<div class="flex yellow" title="与其它设备填写IP、或本机局域网IP有冲突">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex green" title="正常使用" :class="{green:item.Connected &&socks5.list[item.MachineId].running}">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
<div class="flex green" title="正常使用" :class="{green:item.Connected && item.hook_socks5.running}">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
@@ -58,24 +58,21 @@ import { useSocks5 } from './socks5';
|
||||
import {Loading} from '@element-plus/icons-vue'
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed } from 'vue';
|
||||
import { useSocks5Connections } from '../connection/connections';
|
||||
import ConnectionShow from '../connection/ConnectionShow.vue';
|
||||
import ConnectionShow from '../tunnel/ConnectionShow.vue';
|
||||
export default {
|
||||
props:['item','config'],
|
||||
emits: ['edit','refresh'],
|
||||
components:{Loading,ConnectionShow},
|
||||
setup (props,{emit}) {
|
||||
setup (props) {
|
||||
|
||||
const socks5 = useSocks5();
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const connections = useSocks5Connections();
|
||||
|
||||
const handleSocks5 = (socks5,access) => {
|
||||
const handleSocks5 = (_socks5,access) => {
|
||||
if(!props.config){
|
||||
return;
|
||||
}
|
||||
if(machineId.value === socks5.MachineId){
|
||||
if(machineId.value === _socks5.MachineId){
|
||||
if(!access.Socks5StatusSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
@@ -86,8 +83,8 @@ export default {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const fn = props.item.Connected && socks5.running ? stopSocks5 (socks5.MachineId) : runSocks5(socks5.MachineId);
|
||||
socks5.loading = true;
|
||||
const fn = props.item.Connected && _socks5.running ? stopSocks5 (_socks5.MachineId) : runSocks5(_socks5.MachineId);
|
||||
_socks5.loading = true;
|
||||
fn.then(() => {
|
||||
ElMessage.success('操作成功!');
|
||||
}).catch((err) => {
|
||||
@@ -95,11 +92,11 @@ export default {
|
||||
ElMessage.error('操作失败!');
|
||||
})
|
||||
}
|
||||
const handleSocks5Port = (socks5,access) => {
|
||||
if(!props.config && machineId.value != socks5.MachineId){
|
||||
const handleSocks5Port = (_socks5,access) => {
|
||||
if(!props.config && machineId.value != _socks5.MachineId){
|
||||
return;
|
||||
}
|
||||
if(machineId.value === socks5.MachineId){
|
||||
if(machineId.value === _socks5.MachineId){
|
||||
if(!access.Socks5ChangeSelf){
|
||||
ElMessage.success('无权限');
|
||||
return;
|
||||
@@ -110,15 +107,13 @@ export default {
|
||||
return;
|
||||
}
|
||||
}
|
||||
socks5.device = props.item;
|
||||
emit('edit',socks5);
|
||||
}
|
||||
const handleSocks5Refresh = ()=>{
|
||||
emit('refresh');
|
||||
_socks5.device = props.item;
|
||||
socks5.value.current = _socks5;
|
||||
socks5.value.showEdit = true;
|
||||
}
|
||||
|
||||
return {
|
||||
item:computed(()=>props.item),socks5,connections, handleSocks5, handleSocks5Port,handleSocks5Refresh
|
||||
socks5, handleSocks5, handleSocks5Port,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,36 +13,35 @@ export const provideSocks5 = () => {
|
||||
});
|
||||
provide(socks5Symbol, socks5);
|
||||
|
||||
const _getSocks5Info = () => {
|
||||
clearTimeout(socks5.value.timer);
|
||||
getSocks5Info(socks5.value.hashcode.toString()).then((res) => {
|
||||
socks5.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
for (let j in res.List) {
|
||||
Object.assign(res.List[j], {
|
||||
running: res.List[j].Status == 2,
|
||||
loading: res.List[j].Status == 1
|
||||
});
|
||||
const socks5DataFn = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
getSocks5Info(socks5.value.hashcode.toString()).then((res) => {
|
||||
socks5.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
for (let j in res.List) {
|
||||
Object.assign(res.List[j], {
|
||||
running: res.List[j].Status == 2,
|
||||
loading: res.List[j].Status == 1
|
||||
});
|
||||
}
|
||||
socks5.value.list = res.List;
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
socks5.value.list = res.List;
|
||||
}
|
||||
socks5.value.timer = setTimeout(_getSocks5Info, 1100);
|
||||
}).catch((e) => {
|
||||
socks5.value.timer = setTimeout(_getSocks5Info, 1100);
|
||||
resolve(false);
|
||||
}).catch((e) => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
const handleSocks5Edit = (_socks5) => {
|
||||
socks5.value.current = _socks5;
|
||||
socks5.value.showEdit = true;
|
||||
|
||||
const socks5ProcessFn = (device,json) => {
|
||||
Object.assign(json,{
|
||||
hook_socks5: socks5.value.list[device.MachineId] || ''
|
||||
});
|
||||
}
|
||||
const handleSocks5Refresh = () => {
|
||||
const socks5RefreshFn = () => {
|
||||
refreshSocks5();
|
||||
}
|
||||
const clearSocks5Timeout = () => {
|
||||
clearTimeout(socks5.value.timer);
|
||||
socks5.value.timer = 0;
|
||||
}
|
||||
const getSocks5Machines = (name) => {
|
||||
return Object.values(socks5.value.list)
|
||||
.filter(c => c.Port.toString().indexOf(name) >= 0 || (c.Lans.filter(d => d.IP.indexOf(name) >= 0).length > 0))
|
||||
@@ -55,7 +54,7 @@ export const provideSocks5 = () => {
|
||||
|
||||
|
||||
return {
|
||||
socks5, _getSocks5Info, handleSocks5Edit, handleSocks5Refresh, clearSocks5Timeout, getSocks5Machines, sortSocks5
|
||||
socks5, socks5DataFn,socks5ProcessFn, socks5RefreshFn, getSocks5Machines, sortSocks5
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
<template>
|
||||
<div class="connect-point" @click="handleShow" v-if="state.isSelf == false">
|
||||
<template v-if="state.connection && state.connection.Connected">
|
||||
<template v-if="state.connection.Type == 0">
|
||||
<span class="connect-point p2p" title="打洞直连" v-loading="state.connecting"></span>
|
||||
</template>
|
||||
<template v-else-if="state.connection.Type == 1">
|
||||
<span class="connect-point relay" title="中继连接" v-loading="state.connecting"></span>
|
||||
</template>
|
||||
<template v-else-if="state.connection.Type == 2">
|
||||
<span class="connect-point node" title="节点连接" v-loading="state.connecting"></span>
|
||||
</template>
|
||||
<div class="connect-point" @click="handleShow">
|
||||
<template v-if="state.className">
|
||||
<span :class="`connect-point ${state.className}`" :title="state.title" v-loading="state.connecting"></span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="connect-point default" title="未连接" v-loading="state.connecting"></span>
|
||||
@@ -18,27 +10,22 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, reactive, watch } from 'vue';
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useConnections } from './connections';
|
||||
import { useTunnel } from '../tunnel/tunnel';
|
||||
export default {
|
||||
props: ['data','row'],
|
||||
props: ['row','transactionId'],
|
||||
setup (props) {
|
||||
|
||||
const connections = useConnections();
|
||||
const tunnel = useTunnel();
|
||||
const connection = computed(()=>props.row.hook_connection?props.row.hook_connection[props.transactionId] || {} : {});
|
||||
const state = reactive({
|
||||
connection:props.data,
|
||||
transitionId:props.transitionId,
|
||||
connecting:computed(()=>tunnel.value.p2pOperatings[props.row.MachineId] || tunnel.value.relayOperatings[props.row.MachineId]),
|
||||
isSelf:props.row.isSelf
|
||||
});
|
||||
watch(()=>props.data,()=>{
|
||||
state.connection = props.data
|
||||
transactionId:props.transactionId,
|
||||
connecting:computed(()=>props.row.hook_operating[props.transactionId]),
|
||||
className:computed(()=>['p2p','relay','node'][connection.value.Type]),
|
||||
title:computed(()=>['打洞直连','中继连接','节点连接'][connection.value.Type]),
|
||||
});
|
||||
const handleShow = () => {
|
||||
connections.value.current = props.row.MachineId;
|
||||
connections.value.currentName = props.row.MachineName;
|
||||
connections.value.device = props.row;
|
||||
connections.value.transactionId = props.transactionId;
|
||||
connections.value.showEdit = true;
|
||||
}
|
||||
|
||||
@@ -1,81 +1,60 @@
|
||||
<template>
|
||||
<el-dialog v-model="state.show" append-to=".app-wrap" :title="`与[${state.machineName}]的链接`" top="1vh" width="98%">
|
||||
<el-dialog v-model="state.show" append-to=".app-wrap" :title="`与[${state.device.MachineName}]的链接`" top="1vh" width="500">
|
||||
<div>
|
||||
<el-table :data="state.data" size="small" border height="500">
|
||||
<el-table-column property="RemoteMachineId" label="目标/服务器">
|
||||
<template #default="scope">
|
||||
<div :class="{ green: scope.row.Connected }">
|
||||
<p>{{ scope.row.IPEndPoint }}</p>
|
||||
<p>ssl : {{ scope.row.SSL }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="TransactionId" label="事务" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ state.transactions[scope.row.TransactionId] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="TransportName" label="协议" >
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<p>{{ scope.row.TransportName }}({{ state.protocolTypes[scope.row.ProtocolType] }})</p>
|
||||
<p>{{ state.types[scope.row.Type] }} - {{ scope.row.SendBufferRemainingText }} - {{ scope.row.RecvBufferRemainingText }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="Delay" label="延迟" width="60">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<p>{{ scope.row.Delay }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="Bytes" label="通信">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<p>up : {{ scope.row.SendBytesText }}</p>
|
||||
<p>down : {{ scope.row.ReceiveBytesText }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="relay" label="中继节点">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<p class="ellipsis">
|
||||
<span>中继 : </span>
|
||||
<a v-if="state.relayOperatings[scope.row.RemoteMachineId]" href="javascript:;" class="a-line">
|
||||
<span>操作中.</span><el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</a>
|
||||
<a v-else href="javascript:;" class="a-line" @click="handleNode(scope.row)">{{
|
||||
state.nodesDic[scope.row.NodeId] || '选择节点' }}</a>
|
||||
</p>
|
||||
<p>
|
||||
<span>打洞 : </span>
|
||||
<a v-if="state.p2pOperatings[scope.row.RemoteMachineId]" href="javascript:;" class="a-line">
|
||||
<span>操作中.</span><el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</a>
|
||||
<a v-else href="javascript:;" class="a-line" @click="handlep2p(scope.row)">尝试打洞</a>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="54">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<AccessShow value="TunnelRemove">
|
||||
<el-popconfirm confirm-button-text="确认" cancel-button-text="取消"
|
||||
title="确定关闭此连接?" @confirm="handleDel(scope.row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" size="small"><el-icon>
|
||||
<Delete />
|
||||
</el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</AccessShow>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-descriptions border size="small" :column="2" column-max-width="120px" overlength-control="wrap">
|
||||
<el-descriptions-item label="目标">{{ state.connection.IPEndPoint || '0.0.0.0:0' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="事务">{{ state.transactions[state.connection.TransactionId] }}</el-descriptions-item>
|
||||
<el-descriptions-item label="协议">
|
||||
<div>
|
||||
<p>{{ state.connection.TransportName }}({{ state.protocolTypes[state.connection.ProtocolType] }}) - {{ state.types[state.connection.Type] }}</p>
|
||||
<!-- <p> - {{ state.connection.SendBufferRemainingText }} - {{ state.connection.RecvBufferRemainingText }}</p> -->
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="SSL">{{ state.connection.SSL }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="上传">
|
||||
<div>
|
||||
<p><span>{{ state.connection.SendBytesText }}</span></p>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="下载">
|
||||
<div>
|
||||
<p><span>{{ state.connection.ReceiveBytesText }}</span></p>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="中继">
|
||||
<div>
|
||||
<a v-if="state.connecting" href="javascript:;" class="a-line">
|
||||
<span>操作中.</span><el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</a>
|
||||
<a v-else href="javascript:;" class="a-line" @click="handleNode">{{ state.nodesDic[state.connection.NodeId] || '选择节点' }}</a>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="打洞">
|
||||
<div>
|
||||
<a v-if="state.connecting" href="javascript:;" class="a-line">
|
||||
<span>操作中.</span><el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</a>
|
||||
<a v-else href="javascript:;" class="a-line" @click="handlep2p">尝试打洞</a>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="延迟">{{ state.connection.Delay }}</el-descriptions-item>
|
||||
<el-descriptions-item label="操作">
|
||||
<div>
|
||||
<AccessShow value="TunnelRemove">
|
||||
<el-popconfirm confirm-button-text="确认" cancel-button-text="取消"
|
||||
title="确定关闭此连接?" @confirm="handleDel">
|
||||
<template #reference>
|
||||
<el-button type="danger" size="small"><el-icon>
|
||||
<Delete />
|
||||
</el-icon></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</AccessShow>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="state.showNodes" :title="$t('server.relayTitle')" width="98%" top="2vh">
|
||||
@@ -136,13 +115,12 @@
|
||||
<script>
|
||||
import { reactive, watch, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useConnections, useForwardConnections, useSocks5Connections, useTuntapConnections } from './connections';
|
||||
import { useConnections} from './connections';
|
||||
import { Delete, Select, ArrowDown,Loading } from '@element-plus/icons-vue';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { relayConnect, setRelaySubscribe } from '@/apis/relay';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useTunnel } from '../tunnel/tunnel';
|
||||
import { tunnelConnect } from '@/apis/tunnel';
|
||||
import { removeTunnelConnection, tunnelConnect } from '@/apis/tunnel';
|
||||
export default {
|
||||
props: ['modelValue'],
|
||||
emits: ['change', 'update:modelValue'],
|
||||
@@ -153,31 +131,22 @@ export default {
|
||||
const globalData = injectGlobalData();
|
||||
|
||||
const connections = useConnections();
|
||||
const forwardConnections = useForwardConnections();
|
||||
const tuntapConnections = useTuntapConnections();
|
||||
const socks5Connections = useSocks5Connections();
|
||||
const tunnel = useTunnel();
|
||||
const connection = computed(() =>connections.value.device.hook_connection? connections.value.device.hook_connection[connections.value.transactionId] || {} :{});
|
||||
|
||||
const state = reactive({
|
||||
show: true,
|
||||
protocolTypes: { 1: 'tcp', 2: 'udp', 4: 'msquic' },
|
||||
types: { 0: '打洞', 1: '中继', 2: '节点' },
|
||||
transactions: { 'forward': '端口转发', 'tuntap': '虚拟网卡', 'socks5': '代理转发' },
|
||||
machineName: connections.value.currentName,
|
||||
currentRow: {},
|
||||
data: computed(() => {
|
||||
return [
|
||||
forwardConnections.value.list[connections.value.current],
|
||||
tuntapConnections.value.list[connections.value.current],
|
||||
socks5Connections.value.list[connections.value.current],
|
||||
].filter(c => !!c);
|
||||
}),
|
||||
device: connections.value.device,
|
||||
transactionId: connections.value.transactionId,
|
||||
connecting:computed(()=>connections.value.device.hook_operating[connections.value.transactionId]),
|
||||
connection:connection,
|
||||
|
||||
showNodes: false,
|
||||
nodes: [],
|
||||
nodesDic: {},
|
||||
timer: 0,
|
||||
|
||||
relayOperatings:tunnel.value.relayOperatings,
|
||||
p2pOperatings:tunnel.value.p2pOperatings,
|
||||
timer: 0
|
||||
});
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
@@ -187,8 +156,8 @@ export default {
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
const handleDel = (row) => {
|
||||
row.removeFunc(row.RemoteMachineId).then(() => {
|
||||
const handleDel = () => {
|
||||
removeTunnelConnection(state.device.MachineId,state.transactionId).then(() => {
|
||||
ElMessage.success(t('common.oper'));
|
||||
}).catch(() => { });
|
||||
}
|
||||
@@ -207,25 +176,24 @@ export default {
|
||||
});
|
||||
}
|
||||
|
||||
const handlep2p = (row)=>{
|
||||
const handlep2p = ()=>{
|
||||
tunnelConnect({
|
||||
ToMachineId:row.RemoteMachineId,
|
||||
TransactionId:row.TransactionId,
|
||||
DenyProtocols:row.TransactionId == 'tuntap' ? 4 : 2
|
||||
ToMachineId:state.device.MachineId,
|
||||
TransactionId:state.transactionId,
|
||||
DenyProtocols:state.transactionId == 'tuntap' ? 4 : 2
|
||||
}).then(()=>{
|
||||
ElMessage.success(t('common.oper'));
|
||||
}).catch(()=>{ElMessage.success(t('common.operFail'));})
|
||||
}
|
||||
|
||||
const handleNode = (row) => {
|
||||
state.currentRow = row;
|
||||
const handleNode = () => {
|
||||
state.showNodes = true;
|
||||
}
|
||||
const handleConnect = (id, protocol) => {
|
||||
const json = {
|
||||
FromMachineId: globalData.value.config.Client.Id,
|
||||
TransactionId: state.currentRow.TransactionId,
|
||||
ToMachineId: state.currentRow.RemoteMachineId,
|
||||
TransactionId: state.transactionId,
|
||||
ToMachineId: state.device.MachineId,
|
||||
NodeId: id,
|
||||
Protocol: protocol
|
||||
};
|
||||
@@ -3,27 +3,27 @@
|
||||
<template #default="{values}">
|
||||
<el-table-column prop="tunnel" :label="$t('home.tunnel')" width="86">
|
||||
<template #default="scope">
|
||||
<template v-if="tunnel.list[scope.row.MachineId]">
|
||||
<template v-if="scope.row.hook_tunnel">
|
||||
<div>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.CountryCode">
|
||||
<template v-if="scope.row.hook_tunnel.Net.CountryCode">
|
||||
<img
|
||||
:title="`${tunnel.list[scope.row.MachineId].Net.CountryCode}、${tunnel.list[scope.row.MachineId].Net.City}`"
|
||||
:title="`${scope.row.hook_tunnel.Net.CountryCode}、${scope.row.hook_tunnel.Net.City}`"
|
||||
class="system"
|
||||
:src="`https://unpkg.com/flag-icons@7.2.3/flags/4x3/${tunnel.list[scope.row.MachineId].Net.CountryCode.toLowerCase()}.svg`" />
|
||||
:src="`https://unpkg.com/flag-icons@7.2.3/flags/4x3/${scope.row.hook_tunnel.Net.CountryCode.toLowerCase()}.svg`" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.Isp">
|
||||
<template v-if="scope.row.hook_tunnel.Net.Isp">
|
||||
<img
|
||||
:title="`${tunnel.list[scope.row.MachineId].Net.Isp}`"
|
||||
class="system" :src="netImg(tunnel.list[scope.row.MachineId].Net)" />
|
||||
:title="`${scope.row.hook_tunnel.Net.Isp}`"
|
||||
class="system" :src="netImg(scope.row.hook_tunnel.Net)" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
</template>
|
||||
<template v-if="tunnel.list[scope.row.MachineId].Net.Nat">
|
||||
<span class="nat" :title="tunnel.list[scope.row.MachineId].Net.Nat">{{ natMap[tunnel.list[scope.row.MachineId].Net.Nat] }}</span>
|
||||
<template v-if="scope.row.hook_tunnel.Net.Nat">
|
||||
<span class="nat" :title="scope.row.hook_tunnel.Net.Nat">{{ natMap[scope.row.hook_tunnel.Net.Nat] }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<img title="?" class="system" src="/system.svg" />
|
||||
@@ -31,10 +31,10 @@
|
||||
</div>
|
||||
<div class="flex">
|
||||
<a href="javascript:;" class="a-line"
|
||||
:class="{yellow:tunnel.list[scope.row.MachineId].NeedReboot}"
|
||||
:class="{yellow:scope.row.hook_tunnel.NeedReboot}"
|
||||
:title="$t('home.holeText')"
|
||||
@click="handleTunnel(tunnel.list[scope.row.MachineId],scope.row,values)">
|
||||
<span>{{$t('home.jump')}}:{{tunnel.list[scope.row.MachineId].RouteLevel}}+{{tunnel.list[scope.row.MachineId].RouteLevelPlus}}</span>
|
||||
@click="handleTunnel(scope.row.hook_tunnel,scope.row,values)">
|
||||
<span>{{$t('home.jump')}}:{{scope.row.hook_tunnel.RouteLevel}}+{{scope.row.hook_tunnel.RouteLevelPlus}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
@@ -45,7 +45,6 @@
|
||||
</template>
|
||||
<script>
|
||||
import { useTunnel } from './tunnel';
|
||||
import { useConnections,useForwardConnections,useSocks5Connections,useTuntapConnections } from '../connection/connections';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
@@ -53,17 +52,13 @@ import {useI18n} from 'vue-i18n';
|
||||
|
||||
export default {
|
||||
emits: ['edit','refresh'],
|
||||
setup(props, { emit }) {
|
||||
setup() {
|
||||
|
||||
const t = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
|
||||
const tunnel = useTunnel();
|
||||
const connections = useConnections();
|
||||
const forwardConnections = useForwardConnections();
|
||||
const tuntapConnections = useTuntapConnections();
|
||||
const socks5Connections = useSocks5Connections();
|
||||
|
||||
const imgMap = {
|
||||
'chinanet':'chinanet.svg',
|
||||
@@ -88,7 +83,6 @@ export default {
|
||||
}
|
||||
return `./system.svg`;
|
||||
}
|
||||
|
||||
const natMap = {
|
||||
"Unknown":'?',
|
||||
"UnsupportedServer":'?',
|
||||
@@ -101,43 +95,24 @@ export default {
|
||||
"Symmetric":'4',
|
||||
}
|
||||
|
||||
const connectionCount = (machineId)=>{
|
||||
const length = [
|
||||
forwardConnections.value.list[machineId],
|
||||
tuntapConnections.value.list[machineId],
|
||||
socks5Connections.value.list[machineId],
|
||||
].filter(c=>!!c && c.Connected).length;
|
||||
return length;
|
||||
};
|
||||
|
||||
const handleTunnel = (_tunnel,row,access) => {
|
||||
if(machineId.value === _tunnel.MachineId){
|
||||
if(!access.TunnelChangeSelf){
|
||||
ElMessage.success(t('common.access'));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(!access.TunnelChangeOther){
|
||||
ElMessage.success(t('common.access'));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
_tunnel.device = row;
|
||||
tunnel.value.current = _tunnel;
|
||||
tunnel.value.showEdit = true;
|
||||
}
|
||||
const handleTunnelRefresh = ()=>{
|
||||
emit('refresh');
|
||||
}
|
||||
const handleConnections = (row)=>{
|
||||
connections.value.current = row.MachineId;
|
||||
connections.value.currentName = row.MachineName;
|
||||
connections.value.showEdit = true;
|
||||
}
|
||||
|
||||
return {
|
||||
tunnel, handleTunnel,handleTunnelRefresh,
|
||||
connectionCount,handleConnections,netImg,natMap
|
||||
handleTunnel,netImg,natMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export default {
|
||||
});
|
||||
|
||||
const handleSave = () => {
|
||||
const json = JSON.parse(JSON.stringify(tunnel.value.current));
|
||||
const json = JSON.parse(JSON.stringify(tunnel.value.current,(key,value)=> key =='device'?'':value));
|
||||
json.RouteLevel = +state.ruleForm.RouteLevel;
|
||||
json.RouteLevelPlus = +state.ruleForm.RouteLevelPlus;
|
||||
json.PortMapWan = +state.ruleForm.PortMapWan;
|
||||
|
||||
90
src/linker.web/src/views/components/tunnel/connections.js
Normal file
90
src/linker.web/src/views/components/tunnel/connections.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import { inject, provide, ref } from "vue";
|
||||
import { getTunnelConnections } from "@/apis/tunnel";
|
||||
|
||||
const connectionsSymbol = Symbol();
|
||||
export const provideConnections = () => {
|
||||
const connections = ref({
|
||||
speedCache: {},
|
||||
|
||||
showEdit: false,
|
||||
device:{},
|
||||
transactionId:'',
|
||||
|
||||
timer: 0,
|
||||
list: {},
|
||||
hashcode: 0,
|
||||
|
||||
_updateRealTime: false,
|
||||
updateRealTime: (value) => {
|
||||
connections.value.hashcode = 0;
|
||||
connections.value._updateRealTime = value;
|
||||
}
|
||||
});
|
||||
provide(connectionsSymbol, connections);
|
||||
|
||||
const parseConnections = (_connections) => {
|
||||
const result = {};
|
||||
const caches = connections.value.speedCache;
|
||||
for (let transactionId in _connections) {
|
||||
for (let machineId in _connections[transactionId]) {
|
||||
|
||||
const connection = _connections[transactionId][machineId];
|
||||
|
||||
result[machineId] = result[machineId] || {};
|
||||
result[machineId][transactionId] = connection;
|
||||
|
||||
const key = `${machineId}-${transactionId}`;
|
||||
const cache = caches[key] || { SendBytes: 0, ReceiveBytes: 0 };
|
||||
|
||||
connection.SendBytesText = parseSpeed(connection.SendBytes - cache.SendBytes,'/s');
|
||||
connection.ReceiveBytesText = parseSpeed(connection.ReceiveBytes - cache.ReceiveBytes,'/s');
|
||||
connection.SendBufferRemainingText = parseSpeed(connection.SendBufferRemaining,'');
|
||||
connection.RecvBufferRemainingText = parseSpeed(connection.RecvBufferRemaining || 0,'');
|
||||
|
||||
cache.SendBytes = connection.SendBytes;
|
||||
cache.ReceiveBytes = connection.ReceiveBytes;
|
||||
caches[key] = cache;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
const parseSpeed = (num,subfix = '') => {
|
||||
let index = 0;
|
||||
while (num >= 1024) {
|
||||
num /= 1024;
|
||||
index++;
|
||||
}
|
||||
return `${num.toFixed(2)}${['B', 'KB', 'MB', 'GB', 'TB'][index]}${subfix}`;
|
||||
}
|
||||
|
||||
const connectionDataFn = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
getTunnelConnections(connections.value.hashcode.toString()).then((res) => {
|
||||
if (connections.value._updateRealTime == false)
|
||||
connections.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
connections.value.list = parseConnections(res.List);
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
resolve(false);
|
||||
}).catch(() => {
|
||||
resolve(false);
|
||||
})
|
||||
});
|
||||
}
|
||||
const connectionRefreshFn = () => {
|
||||
}
|
||||
const connectionProcessFn = (device,json) => {
|
||||
Object.assign(json,{
|
||||
hook_connection: connections.value.list[device.MachineId]
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
connections, connectionDataFn, connectionProcessFn,connectionRefreshFn
|
||||
}
|
||||
}
|
||||
export const useConnections = () => {
|
||||
return inject(connectionsSymbol);
|
||||
}
|
||||
@@ -1,75 +1,120 @@
|
||||
import { relayOperating } from "@/apis/relay";
|
||||
import { getTunnelInfo, tunnelRefresh,tunnelOperating } from "@/apis/tunnel";
|
||||
import { injectGlobalData } from "@/provide";
|
||||
import { inject, provide, ref } from "vue";
|
||||
|
||||
const tunnelSymbol = Symbol();
|
||||
export const provideTunnel = () => {
|
||||
const tunnel = ref({
|
||||
|
||||
timer1: 0,
|
||||
p2pOperatings:{},
|
||||
timer2: 0,
|
||||
relayOperatings:{},
|
||||
|
||||
showEdit: false,
|
||||
current: null,
|
||||
|
||||
timer: 0,
|
||||
list: {},
|
||||
hashcode: 0,
|
||||
showMap: false
|
||||
|
||||
timer1: 0,
|
||||
p2pOperatings:{},
|
||||
hashcode1: 0,
|
||||
|
||||
timer2: 0,
|
||||
relayOperatings:{},
|
||||
hashcode2: 0,
|
||||
|
||||
showEdit: false,
|
||||
current: null,
|
||||
|
||||
});
|
||||
provide(tunnelSymbol, tunnel);
|
||||
const _getTunnelInfo = () => {
|
||||
clearTimeout(tunnel.value.timer);
|
||||
getTunnelInfo(tunnel.value.hashcode.toString()).then((res) => {
|
||||
tunnel.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
tunnel.value.list = res.List;
|
||||
}
|
||||
tunnel.value.timer = setTimeout(_getTunnelInfo, 1060);
|
||||
}).catch(() => {
|
||||
tunnel.value.timer = setTimeout(_getTunnelInfo, 1060);
|
||||
});
|
||||
}
|
||||
const getTunnelOperating = () => {
|
||||
clearTimeout(tunnel.value.timer1);
|
||||
tunnelOperating().then((res) => {
|
||||
tunnel.p2pOperatings = res;
|
||||
tunnel.value.timer1 = setTimeout(getTunnelOperating, 1080);
|
||||
}).catch(() => {
|
||||
tunnel.value.timer1 = setTimeout(getTunnelOperating, 1080);
|
||||
});
|
||||
}
|
||||
const getRelayOperating = () => {
|
||||
clearTimeout(tunnel.value.timer2);
|
||||
relayOperating().then((res) => {
|
||||
tunnel.relayOperatings = res;
|
||||
tunnel.value.timer2 = setTimeout(getRelayOperating, 1040);
|
||||
}).catch(() => {
|
||||
tunnel.value.timer2 = setTimeout(getRelayOperating, 1040);
|
||||
return new Promise((resolve, reject) => {
|
||||
getTunnelInfo(tunnel.value.hashcode.toString()).then((res) => {
|
||||
tunnel.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
tunnel.value.list = res.List;
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
resolve(false);
|
||||
}).catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const handleTunnelEdit = (_tunnel) => {
|
||||
tunnel.value.current = _tunnel;
|
||||
tunnel.value.showEdit = true;
|
||||
const parseOperating = (operatings) => {
|
||||
const json = {};
|
||||
for(let key in operatings){
|
||||
let arr = key.split('@');
|
||||
if(!json[arr[0]]) json[arr[0]] = {};
|
||||
json[arr[0]][arr[1]] = operatings[key];
|
||||
}
|
||||
return json;
|
||||
}
|
||||
const handleTunnelRefresh = () => {
|
||||
const getTunnelOperating = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
tunnelOperating(tunnel.value.hashcode1.toString()).then((res) => {
|
||||
tunnel.value.hashcode1 = res.HashCode;
|
||||
if (res.List)
|
||||
{
|
||||
tunnel.value.p2pOperatings = parseOperating(res.List);
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
resolve(false);
|
||||
}).catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
const getRelayOperating = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
relayOperating(tunnel.value.hashcode2.toString()).then((res) => {
|
||||
tunnel.value.hashcode2 = res.HashCode;
|
||||
if (res.List)
|
||||
{
|
||||
tunnel.value.relayOperatings = parseOperating(res.List);
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
resolve(false);
|
||||
}).catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
const tunnelDataFn = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Promise.all([_getTunnelInfo(), getTunnelOperating(), getRelayOperating()]).then((res) => {
|
||||
resolve(res.filter(c=>c == true).length > 0);
|
||||
}).catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
const tunnelRefreshFn = () => {
|
||||
tunnelRefresh();
|
||||
}
|
||||
const clearTunnelTimeout = () => {
|
||||
clearTimeout(tunnel.value.timer);
|
||||
clearTimeout(tunnel.value.timer1);
|
||||
clearTimeout(tunnel.value.timer2);
|
||||
|
||||
|
||||
const tunnelProcessFn = (device,json) => {
|
||||
const p2p = tunnel.value.p2pOperatings[device.MachineId] || {};
|
||||
const relay = tunnel.value.relayOperatings[device.MachineId]|| {};
|
||||
const keys = [...new Set(Object.keys(p2p).concat(Object.keys(relay)))];
|
||||
const _json = {};
|
||||
for(let key of keys) {
|
||||
_json[key] = p2p[key] || relay[key] || false;
|
||||
}
|
||||
Object.assign(json,{
|
||||
hook_tunnel: tunnel.value.list[device.MachineId],
|
||||
hook_operating: _json,
|
||||
});
|
||||
}
|
||||
|
||||
const sortTunnel = (asc) => {
|
||||
return Object.values(tunnel.value.list).sort((a, b) => {
|
||||
return a.RouteLevel + a.RouteLevelPlus - b.RouteLevel + b.RouteLevelPlus;
|
||||
}).map(c => c.MachineId);
|
||||
}
|
||||
return {
|
||||
tunnel, _getTunnelInfo,getTunnelOperating,getRelayOperating, handleTunnelEdit, handleTunnelRefresh, clearTunnelTimeout, sortTunnel
|
||||
tunnel, tunnelDataFn,tunnelProcessFn,tunnelRefreshFn, sortTunnel
|
||||
}
|
||||
}
|
||||
export const useTunnel = () => {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<el-table-column prop="tuntap" :label="tuntap.show?$t('home.tuntap'):''" width="160">
|
||||
<el-table-column prop="tuntap" :label="$t('home.tuntap')" width="160">
|
||||
<template #header>
|
||||
<a v-if="tuntap.show" href="javascript:;" class="a-line" @click="handleShowLease">{{$t('home.tuntap')}}</a>
|
||||
<a href="javascript:;" class="a-line" @click="handleShowLease">{{$t('home.tuntap')}}</a>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div v-if="tuntap.show && tuntap.list[scope.row.MachineId]">
|
||||
<div v-if="scope.row.hook_tuntap">
|
||||
<TuntapShow :config="true" :item="scope.row"></TuntapShow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -89,7 +89,8 @@ export default {
|
||||
}
|
||||
|
||||
const getData = ()=>{
|
||||
const json = JSON.parse(JSON.stringify(tuntap.value.current));
|
||||
console.log(tuntap.value.current);
|
||||
const json = JSON.parse(JSON.stringify(tuntap.value.current,(key,value)=> key =='device'?'':value ));
|
||||
json.IP = state.ruleForm.IP.replace(/\s/g, '') || '0.0.0.0';
|
||||
json.PrefixLength = +state.ruleForm.PrefixLength;
|
||||
json.Gateway = state.ruleForm.Gateway;
|
||||
|
||||
@@ -4,50 +4,50 @@
|
||||
<div>
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<ConnectionShow :data="connections.list[item.MachineId]" :row="item" transitionId="tuntap"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleTuntapIP(tuntap.list[item.MachineId],values)" title="虚拟网卡IP">
|
||||
<ConnectionShow :row="item" transactionId="tuntap"></ConnectionShow>
|
||||
<a href="javascript:;" class="a-line" @click="handleTuntapIP(item.hook_tuntap,values)" title="虚拟网卡IP">
|
||||
<template v-if="item.Connected">
|
||||
<template v-if="tuntap.list[item.MachineId].SetupError">
|
||||
<strong class="red" :title="`setup ${tuntap.list[item.MachineId].SetupError}`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<template v-if="item.hook_tuntap.SetupError">
|
||||
<strong class="red" :title="`setup ${item.hook_tuntap.SetupError}`">{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].Exists">
|
||||
<strong class="red" title="IP存在冲突,请使用新IP">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<template v-else-if="item.hook_tuntap.Exists">
|
||||
<strong class="red" title="IP存在冲突,请使用新IP">{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].Available == false">
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<template v-else-if="item.hook_tuntap.Available == false">
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].NatError">
|
||||
<strong class="yellow" :title="`nat ${tuntap.list[item.MachineId].NatError}`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<template v-else-if="item.hook_tuntap.NatError">
|
||||
<strong class="yellow" :title="`nat ${item.hook_tuntap.NatError}`">{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].AppNat && tuntap.list[item.MachineId].running">
|
||||
<strong class="app-nat" :title="`虚拟网卡IP\r\n应用层DNAT`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<template v-else-if="item.hook_tuntap.AppNat && item.hook_tuntap.running">
|
||||
<strong class="app-nat" :title="`虚拟网卡IP\r\n应用层DNAT`">{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
<template v-else-if="tuntap.list[item.MachineId].running">
|
||||
<strong class="green gateway" :title="`虚拟网卡IP\r\n系统NAT`">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<template v-else-if="item.hook_tuntap.running">
|
||||
<strong class="green gateway" :title="`虚拟网卡IP\r\n系统NAT`">{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong>{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<strong>{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ tuntap.list[item.MachineId].IP }}</strong>
|
||||
<strong class="disable" title="IP不生效,可能是设备不在线">{{ item.hook_tuntap.IP }}</strong>
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
<template v-if="tuntap.list[item.MachineId].loading">
|
||||
<template v-if="item.hook_tuntap.loading">
|
||||
<div>
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-switch :model-value="item.Connected && tuntap.list[item.MachineId].running" :loading="tuntap.list[item.MachineId].loading" disabled @click="handleTuntap(tuntap.list[item.MachineId],values)" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
<el-switch :model-value="item.Connected && item.hook_tuntap.running" :loading="item.hook_tuntap.loading" disabled @click="handleTuntap(item.hook_tuntap,values)" size="small" inline-prompt active-text="😀" inactive-text="😣" >
|
||||
</el-switch>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<template v-for="(item1,index) in tuntap.list[item.MachineId].Lans" :key="index">
|
||||
<template v-if="tuntap.list[item.MachineId].Available == false">
|
||||
<template v-for="(item1,index) in item.hook_tuntap.Lans" :key="index">
|
||||
<template v-if="item.hook_tuntap.Available == false">
|
||||
<div class="flex disable" title="IP不生效,可能是设备不在线">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||
</template>
|
||||
<template v-else-if="item1.Disabled">
|
||||
@@ -61,15 +61,15 @@
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<template v-if="tuntap.list[item.MachineId].Any">
|
||||
<template v-if="item.hook_tuntap.Any">
|
||||
<div class="any green"><el-icon><Share /></el-icon></div>
|
||||
</template>
|
||||
<template v-if="showDelay">
|
||||
<template v-if="tuntap.list[item.MachineId].Delay>=0 && tuntap.list[item.MachineId].Delay<=100">
|
||||
<div class="delay green">{{ tuntap.list[item.MachineId].Delay }}ms</div>
|
||||
<template v-if="item.hook_tuntap.Delay>=0 && item.hook_tuntap.Delay<=100">
|
||||
<div class="delay green">{{ item.hook_tuntap.Delay }}ms</div>
|
||||
</template>
|
||||
<template>
|
||||
<div class="delay yellow">{{ tuntap.list[item.MachineId].Delay }}ms</div>
|
||||
<div class="delay yellow">{{ item.hook_tuntap.Delay }}ms</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
@@ -85,8 +85,7 @@ import { useTuntap } from './tuntap';
|
||||
import {Loading,Share} from '@element-plus/icons-vue'
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { computed } from 'vue';
|
||||
import { useTuntapConnections } from '../connection/connections';
|
||||
import ConnectionShow from '../connection/ConnectionShow.vue';
|
||||
import ConnectionShow from '../tunnel/ConnectionShow.vue';
|
||||
export default {
|
||||
props:['item','config'],
|
||||
components:{Loading,Share,ConnectionShow},
|
||||
@@ -95,7 +94,6 @@ export default {
|
||||
const tuntap = useTuntap();
|
||||
const globalData = injectGlobalData();
|
||||
const machineId = computed(() => globalData.value.config.Client.Id);
|
||||
const connections = useTuntapConnections();
|
||||
|
||||
|
||||
const showDelay = computed(()=>((globalData.value.config.Running.Tuntap || {Switch:0}).Switch & 2) == 2);
|
||||
@@ -149,7 +147,7 @@ export default {
|
||||
}
|
||||
|
||||
return {
|
||||
item:computed(()=>props.item),tuntap,showDelay,connections, handleTuntap, handleTuntapIP,handleTuntapRefresh
|
||||
item:computed(()=>props.item),tuntap,showDelay, handleTuntap, handleTuntapIP,handleTuntapRefresh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { getTuntapInfo, refreshTuntap, subscribePing } from "@/apis/tuntap";
|
||||
const tuntapSymbol = Symbol();
|
||||
export const provideTuntap = () => {
|
||||
const tuntap = ref({
|
||||
show: true,
|
||||
timer: 0,
|
||||
showEdit: false,
|
||||
current: null,
|
||||
@@ -22,40 +21,39 @@ export const provideTuntap = () => {
|
||||
|
||||
const reg = /iphone|samsung|vivo|oppo|google|huawei|xiaomi|ios|android|windows|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux|docker/g;
|
||||
|
||||
const _getTuntapInfo = () => {
|
||||
clearTimeout(tuntap.value.timer);
|
||||
getTuntapInfo(tuntap.value.hashcode.toString()).then((res) => {
|
||||
tuntap.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
for (let j in res.List) {
|
||||
const systemStr = res.List[j].SystemInfo.toLowerCase();
|
||||
const tuntapDataFn = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
getTuntapInfo(tuntap.value.hashcode.toString()).then((res) => {
|
||||
|
||||
const match =[...new Set(systemStr.match(reg))];
|
||||
Object.assign(res.List[j], {
|
||||
running: res.List[j].Status == 2,
|
||||
loading: res.List[j].Status == 1,
|
||||
systems: match
|
||||
});
|
||||
subscribePing();
|
||||
tuntap.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
for (let j in res.List) {
|
||||
const systemStr = res.List[j].SystemInfo.toLowerCase();
|
||||
const match =[...new Set(systemStr.match(reg))];
|
||||
Object.assign(res.List[j], {
|
||||
running: res.List[j].Status == 2,
|
||||
loading: res.List[j].Status == 1,
|
||||
systems: match
|
||||
});
|
||||
}
|
||||
tuntap.value.list = res.List;
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
tuntap.value.list = res.List;
|
||||
}
|
||||
tuntap.value.timer = setTimeout(_getTuntapInfo, 1100);
|
||||
subscribePing();
|
||||
}).catch((e) => {
|
||||
tuntap.value.timer = setTimeout(_getTuntapInfo, 1100);
|
||||
resolve(false);
|
||||
}).catch((e) => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
const handleTuntapEdit = (_tuntap) => {
|
||||
tuntap.value.current = _tuntap;
|
||||
tuntap.value.showEdit = true;
|
||||
|
||||
}
|
||||
const handleTuntapRefresh = () => {
|
||||
}
|
||||
const tuntapRefreshFn = () => {
|
||||
refreshTuntap();
|
||||
}
|
||||
const clearTuntapTimeout = () => {
|
||||
clearTimeout(tuntap.value.timer);
|
||||
tuntap.value.timer = 0;
|
||||
const tuntapProcessFn = (device,json) => {
|
||||
Object.assign(json,{
|
||||
hook_tuntap: tuntap.value.list[device.MachineId]
|
||||
});
|
||||
}
|
||||
const getTuntapMachines = (name) => {
|
||||
return Object.values(tuntap.value.list)
|
||||
@@ -79,7 +77,7 @@ export const provideTuntap = () => {
|
||||
|
||||
|
||||
return {
|
||||
tuntap, _getTuntapInfo, handleTuntapEdit, handleTuntapRefresh, clearTuntapTimeout, getTuntapMachines, sortTuntapIP
|
||||
tuntap, tuntapDataFn, tuntapProcessFn, tuntapRefreshFn, getTuntapMachines, sortTuntapIP
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
<a href="javascript:;" class="download" @click="handleUpdate(values)" :title="updaterText" :class="updaterColor">
|
||||
<span>
|
||||
<span>{{item.Version}}</span>
|
||||
<template v-if="updater.list[item.MachineId]">
|
||||
<template v-if="updater.list[item.MachineId].Status == 1">
|
||||
<template v-if="item.hook_updater">
|
||||
<template v-if="item.hook_updater.Status == 1">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 2">
|
||||
<template v-else-if="item.hook_updater.Status == 2">
|
||||
<el-icon size="14"><Download /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 3 || updater.list[item.MachineId].Status == 5">
|
||||
<template v-else-if="item.hook_updater.Status == 3 || item.hook_updater.Status == 5">
|
||||
<el-icon size="14" class="loading"><Loading /></el-icon>
|
||||
<span class="progress" v-if="updater.list[item.MachineId].Length ==0">0%</span>
|
||||
<span class="progress" v-else>{{parseInt(updater.list[item.MachineId].Current/updater.list[item.MachineId].Length*100)}}%</span>
|
||||
<span class="progress" v-if="item.hook_updater.Length ==0">0%</span>
|
||||
<span class="progress" v-else>{{parseInt(item.hook_updater.Current/item.hook_updater.Length*100)}}%</span>
|
||||
</template>
|
||||
<template v-else-if="updater.list[item.MachineId].Status == 6">
|
||||
<template v-else-if="item.hook_updater.Status == 6">
|
||||
<el-icon size="14" class="yellow"><CircleCheck /></el-icon>
|
||||
</template>
|
||||
</template>
|
||||
@@ -43,21 +43,20 @@ export default {
|
||||
components:{Download,Loading,CircleCheck},
|
||||
setup (props) {
|
||||
|
||||
const {t} = useI18n();
|
||||
const {t} = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const updater = useUpdater();
|
||||
const serverVersion = computed(()=>globalData.value.signin.Version);
|
||||
const updaterVersion = computed(()=>updater.value.current.Version);
|
||||
const updaterText = computed(()=>{
|
||||
if(!updater.value.list[props.item.MachineId]){
|
||||
if(!props.item.hook_updater){
|
||||
return '未检测到更新';
|
||||
}
|
||||
|
||||
if(updater.value.list[props.item.MachineId].Status <= 2) {
|
||||
if(props.item.hook_updater.Status <= 2) {
|
||||
return props.item.Version != serverVersion.value
|
||||
? `与服务器版本(${serverVersion.value})不一致,建议更新`
|
||||
: updaterVersion.value != props.item.Version
|
||||
? `不是最新版本(${updaterVersion.value}),建议更新`
|
||||
: props.item.hook_updater.Version != props.item.Version
|
||||
? `不是最新版本(${props.item.hook_updater.Version}),建议更新`
|
||||
: `是最新版本,但我无法阻止你喜欢更新`
|
||||
}
|
||||
return {
|
||||
@@ -65,12 +64,12 @@ export default {
|
||||
4:'已下载',
|
||||
5:'正在解压',
|
||||
6:'已解压,请重启',
|
||||
}[updater.value.list[props.item.MachineId].Status];
|
||||
}[props.item.hook_updater.Status];
|
||||
})
|
||||
const updaterColor = computed(()=>{
|
||||
return props.item.Version != serverVersion.value
|
||||
? 'red'
|
||||
: updater.value.list[props.item.MachineId] && updaterVersion.value != props.item.Version
|
||||
: props.item.hook_updater && props.item.hook_updater.Version != props.item.Version
|
||||
? 'yellow' :'green'
|
||||
})
|
||||
const handleUpdate = (access)=>{
|
||||
@@ -87,18 +86,17 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateInfo = updater.value.list[props.item.MachineId];
|
||||
if(!updateInfo){
|
||||
if(!props.item.hook_updater){
|
||||
ElMessage.error('未检测到更新');
|
||||
return;
|
||||
}
|
||||
//未检测,检测中,下载中,解压中
|
||||
if([0,1,3,5].indexOf(updateInfo.Status)>=0){
|
||||
if([0,1,3,5].indexOf(props.item.hook_updater.Status)>=0){
|
||||
ElMessage.error('操作中,请稍后!');
|
||||
return;
|
||||
}
|
||||
//已解压
|
||||
if(updateInfo.Status == 6){
|
||||
if(props.item.hook_updater.Status == 6){
|
||||
ElMessageBox.confirm('确定关闭程序吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
@@ -108,12 +106,12 @@ export default {
|
||||
}).catch(() => {});
|
||||
return;
|
||||
}
|
||||
updater.value.show = updateInfo.Status == 2;
|
||||
updater.value.show = props.item.hook_updater.Status == 2;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
item:computed(()=>props.item),updater,updaterText,updaterColor,handleUpdate
|
||||
updater,updaterText,updaterColor,handleUpdate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,16 +48,14 @@ export default {
|
||||
const globalData = injectGlobalData();
|
||||
const updater = useUpdater();
|
||||
const serverVersion = computed(()=>globalData.value.signin.Version);
|
||||
const updaterVersion = computed(()=>updater.value.current.Version);
|
||||
|
||||
const versions = [
|
||||
{label:`${updaterVersion.value}【最新版本】`,value:updaterVersion.value},
|
||||
{label:`${updater.value.device.hook_updater.Version}【最新版本】`,value:updater.value.device.hook_updater.Version},
|
||||
{label:`${serverVersion.value}【服务器版本】`,value:serverVersion.value},
|
||||
].filter(c=>c.value);
|
||||
const state = reactive({
|
||||
show: true,
|
||||
type:'',
|
||||
version:versions[0] || '',
|
||||
version:versions[0] || {},
|
||||
versions:versions,
|
||||
msg:[]
|
||||
});
|
||||
@@ -104,7 +102,7 @@ export default {
|
||||
});
|
||||
|
||||
return {
|
||||
state,getTypes,updater,handleUpdate
|
||||
state,getTypes,handleUpdate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,58 +4,55 @@ import { inject, provide, ref } from "vue";
|
||||
|
||||
const updaterSymbol = Symbol();
|
||||
export const provideUpdater = () => {
|
||||
const globalData = injectGlobalData();
|
||||
const updater = ref({
|
||||
timer: 0,
|
||||
list: {},
|
||||
hashcode: 0,
|
||||
current: { Version: '', Msg: [], DateTime: '', Status: 0, Length: 0, Current: 0 },
|
||||
|
||||
subscribeTimer: 0,
|
||||
|
||||
device: {},
|
||||
show: false,
|
||||
});
|
||||
provide(updaterSymbol, updater);
|
||||
const _getUpdater = () => {
|
||||
clearTimeout(updater.value.timer);
|
||||
getUpdater(updater.value.hashcode.toString()).then((res) => {
|
||||
updater.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
const self = Object.values(res.List).filter(c => !!c.Version)[0];
|
||||
if (self) {
|
||||
Object.assign(updater.value.current, {
|
||||
Version: self.Version,
|
||||
Status: self.Status,
|
||||
Length: self.Length,
|
||||
Current: self.Current
|
||||
});
|
||||
globalData.value.updater = updater.value.current;
|
||||
|
||||
const updaterDataFn = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
getUpdater(updater.value.hashcode.toString()).then((res) => {
|
||||
updater.value.hashcode = res.HashCode;
|
||||
if (res.List) {
|
||||
updater.value.list = res.List;
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
updater.value.list = res.List;
|
||||
}
|
||||
|
||||
updater.value.timer = setTimeout(_getUpdater, 800);
|
||||
}).catch(() => {
|
||||
updater.value.timer = setTimeout(_getUpdater, 800);
|
||||
resolve(false);
|
||||
}).catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
const _subscribeUpdater = () => {
|
||||
const updaterRefreshFn = () => {
|
||||
}
|
||||
const updaterProcessFn = (device,json) => {
|
||||
Object.assign(json,{
|
||||
hook_updater: updater.value.list[device.MachineId] || {}
|
||||
});
|
||||
}
|
||||
|
||||
const updaterSubscribe = () => {
|
||||
subscribeUpdater().then(() => {
|
||||
updater.value.subscribeTimer = setTimeout(_subscribeUpdater, 5000);
|
||||
updater.value.subscribeTimer = setTimeout(updaterSubscribe, 5000);
|
||||
}).catch(() => {
|
||||
updater.value.subscribeTimer = setTimeout(_subscribeUpdater, 5000);
|
||||
updater.value.subscribeTimer = setTimeout(updaterSubscribe, 5000);
|
||||
});
|
||||
}
|
||||
|
||||
const clearUpdaterTimeout = () => {
|
||||
clearTimeout(updater.value.timer);
|
||||
const updaterClearTimeout = () => {
|
||||
clearTimeout(updater.value.subscribeTimer);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
updater, _getUpdater, _subscribeUpdater, clearUpdaterTimeout
|
||||
updater, updaterDataFn, updaterProcessFn,updaterRefreshFn,updaterSubscribe, updaterClearTimeout
|
||||
}
|
||||
}
|
||||
export const useUpdater = () => {
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
<Sort @sort="handleSortChange"></Sort>
|
||||
<el-table :data="devices.page.List" stripe border style="width: 100%" :height="`${state.height}px`" size="small">
|
||||
<Device @refresh="handlePageRefresh"></Device>
|
||||
<Tunnel @refresh="handleTunnelRefresh"></Tunnel>
|
||||
<Tunnel @refresh="deviceRefreshHook('tunnel')"></Tunnel>
|
||||
<Tuntap></Tuntap>
|
||||
<Socks5 @refresh="handleSocks5Refresh"></Socks5>
|
||||
<Socks5 @refresh="deviceRefreshHook('socks5')"></Socks5>
|
||||
<Forward ></Forward>
|
||||
<Oper @refresh="handlePageRefresh"></Oper>
|
||||
</el-table>
|
||||
<div class="page" :class="{'t-c':globalData.isPc}">
|
||||
<div class="page" :class="{'t-c':state.center}">
|
||||
<div class="page-wrap">
|
||||
<el-pagination small background :total="devices.page.Count"
|
||||
:pager-count="globalData.isPc?7:3"
|
||||
:layout="globalData.isPc?'total,sizes,prev,pager, next':'prev, pager, next'"
|
||||
:pager-count="state.paperCount"
|
||||
:layout="state.paperLayout"
|
||||
:page-size="devices.page.Request.Size" :current-page="devices.page.Request.Page"
|
||||
@current-change="handlePageChange" @size-change="handlePageSizeChange"
|
||||
:page-sizes="[10, 20, 50, 100,255]" />
|
||||
@@ -21,11 +21,11 @@
|
||||
</div>
|
||||
<DeviceEdit v-if="devices.showDeviceEdit" v-model="devices.showDeviceEdit" @change="handlePageChange" :data="devices.deviceInfo"></DeviceEdit>
|
||||
<AccessEdit v-if="devices.showAccessEdit" v-model="devices.showAccessEdit" @change="handlePageChange" :data="devices.deviceInfo"></AccessEdit>
|
||||
<TunnelEdit v-if="tunnel.showEdit" v-model="tunnel.showEdit" @change="handleTunnelRefresh"></TunnelEdit>
|
||||
<TunnelEdit v-if="tunnel.showEdit" v-model="tunnel.showEdit" @change="deviceRefreshHook('tunnel')"></TunnelEdit>
|
||||
<ConnectionsEdit v-if="connections.showEdit" v-model="connections.showEdit" ></ConnectionsEdit>
|
||||
<TuntapEdit v-if="tuntap.showEdit" v-model="tuntap.showEdit" @change="handleTuntapRefresh"></TuntapEdit>
|
||||
<TuntapLease v-if="tuntap.showLease" v-model="tuntap.showLease" @change="handleTuntapRefresh"></TuntapLease>
|
||||
<Socks5Edit v-if="socks5.showEdit" v-model="socks5.showEdit" @change="handleSocks5Refresh"></Socks5Edit>
|
||||
<TuntapEdit v-if="tuntap.showEdit" v-model="tuntap.showEdit" @change="deviceRefreshHook('tuntap')"></TuntapEdit>
|
||||
<TuntapLease v-if="tuntap.showLease" v-model="tuntap.showLease" @change="deviceRefreshHook('tuntap')"></TuntapLease>
|
||||
<Socks5Edit v-if="socks5.showEdit" v-model="socks5.showEdit" @change="deviceRefreshHook('socks5')"></Socks5Edit>
|
||||
<ForwardEdit v-if="forward.showEdit" v-model="forward.showEdit" ></ForwardEdit>
|
||||
<SForwardEdit v-if="sforward.showEdit" v-model="sforward.showEdit" ></SForwardEdit>
|
||||
<UpdaterConfirm v-if="updater.show" v-model="updater.show" ></UpdaterConfirm>
|
||||
@@ -45,7 +45,6 @@ import { ElMessage } from 'element-plus'
|
||||
|
||||
import Sort from './Sort.vue'
|
||||
|
||||
|
||||
import Device from '../../../components/device/Device.vue'
|
||||
import DeviceEdit from '../../../components/device/DeviceEdit.vue'
|
||||
import { provideDevices } from '../../../components/device/devices'
|
||||
@@ -53,12 +52,6 @@ import { provideDevices } from '../../../components/device/devices'
|
||||
import AccessEdit from '../../../components/accesss/AccessEdit.vue'
|
||||
import { provideAccess } from '../../../components/accesss/access'
|
||||
|
||||
import Tuntap from '../../../components/tuntap/Tuntap.vue'
|
||||
import TuntapEdit from '../../../components/tuntap/TuntapEdit.vue'
|
||||
import TuntapLease from '../../../components/tuntap/TuntapLease.vue'
|
||||
import { provideTuntap } from '../../../components/tuntap/tuntap'
|
||||
|
||||
|
||||
import Socks5 from '../../../components/socks5/Socks5.vue'
|
||||
import Socks5Edit from '../../../components/socks5/Socks5Edit.vue'
|
||||
import { provideSocks5 } from '../../../components/socks5/socks5'
|
||||
@@ -67,18 +60,25 @@ import Tunnel from '../../../components/tunnel/Tunnel.vue'
|
||||
import TunnelEdit from '../../../components/tunnel/TunnelEdit.vue'
|
||||
import { provideTunnel } from '../../../components/tunnel/tunnel'
|
||||
|
||||
import { provideUpdater } from '../../../components/updater/updater'
|
||||
import UpdaterConfirm from '../../../components/updater/UpdaterConfirm.vue'
|
||||
|
||||
|
||||
import Tuntap from '../../../components/tuntap/Tuntap.vue'
|
||||
import TuntapEdit from '../../../components/tuntap/TuntapEdit.vue'
|
||||
import TuntapLease from '../../../components/tuntap/TuntapLease.vue'
|
||||
import { provideTuntap } from '../../../components/tuntap/tuntap'
|
||||
|
||||
import ConnectionsEdit from '../../../components/tunnel/ConnectionsEdit.vue'
|
||||
import { provideConnections } from '../../../components/tunnel/connections'
|
||||
|
||||
|
||||
import Forward from '../../../components/forward/Forward.vue'
|
||||
import ForwardEdit from '../../../components/forward/ForwardEdit.vue'
|
||||
import { provideForward } from '../../../components/forward/forward'
|
||||
import SForwardEdit from '../../../components/forward/SForwardEdit.vue'
|
||||
import { provideSforward } from '../../../components/forward/sforward'
|
||||
|
||||
import ConnectionsEdit from '../../../components/connection/ConnectionsEdit.vue'
|
||||
import { provideConnections } from '../../../components/connection/connections'
|
||||
|
||||
import { provideUpdater } from '../../../components/updater/updater'
|
||||
import UpdaterConfirm from '../../../components/updater/UpdaterConfirm.vue'
|
||||
|
||||
import { provideFlow } from '../../../components/flow/flow'
|
||||
import Stopwatch from '../../../components/flow/stopwatch/Index.vue'
|
||||
import OperFlow from '../../../components/flow/OperDialog.vue'
|
||||
@@ -114,29 +114,37 @@ export default {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
height: computed(()=>globalData.value.height-90)
|
||||
height: computed(()=>globalData.value.height-90),
|
||||
center: computed(()=>globalData.value.isPc),
|
||||
paperCount: computed(()=>globalData.value.isPc?7:3),
|
||||
paperLayout: computed(()=>globalData.value.isPc?'total,sizes,prev,pager, next':'prev, pager, next'),
|
||||
});
|
||||
|
||||
const {devices,addDeviceHook, startDeviceProcess, handlePageChange, handlePageSizeChange,clearDevicesTimeout,setSort} = provideDevices();
|
||||
const {tuntap,_getTuntapInfo,handleTuntapRefresh,clearTuntapTimeout,getTuntapMachines,sortTuntapIP} = provideTuntap();
|
||||
const {socks5,_getSocks5Info,handleSocks5Refresh,clearSocks5Timeout,getSocks5Machines,sortSocks5} = provideSocks5();
|
||||
const {tunnel,_getTunnelInfo,getTunnelOperating,getRelayOperating,handleTunnelRefresh,clearTunnelTimeout,sortTunnel} = provideTunnel();
|
||||
const {devices,deviceAddHook,deviceRefreshHook, deviceStartProcess, handlePageChange, handlePageSizeChange,deviceClearTimeout,setSort} = provideDevices();
|
||||
const {forward} = provideForward();
|
||||
const {sforward} = provideSforward();
|
||||
const {connections,_getForwardConnections,_getTuntapConnections,_getSocks5Connections, clearConnectionsTimeout } = provideConnections();
|
||||
const {updater,_getUpdater,_subscribeUpdater,clearUpdaterTimeout} = provideUpdater();
|
||||
const {flow} = provideFlow();
|
||||
const {accessDataFn,accessProcessFn,accessRefreshFn} = provideAccess();
|
||||
const {oper} = provideOper();
|
||||
const {decenter,counterDataFn,counterProcessFn,counterRefreshFn} = provideDecenter();
|
||||
const {firewall} = provideFirewall();
|
||||
const {wakeup} = provideWakeup();
|
||||
const {transport} = provideTransport();
|
||||
const {action} = provideAction();
|
||||
|
||||
addDeviceHook('access',accessDataFn,accessProcessFn,accessRefreshFn)
|
||||
addDeviceHook('counter',counterDataFn,counterProcessFn,counterRefreshFn)
|
||||
|
||||
const {accessDataFn,accessProcessFn,accessRefreshFn} = provideAccess();
|
||||
deviceAddHook('access',accessDataFn,accessProcessFn,accessRefreshFn);
|
||||
const {decenter,counterDataFn,counterProcessFn,counterRefreshFn} = provideDecenter();
|
||||
deviceAddHook('counter',counterDataFn,counterProcessFn,counterRefreshFn);
|
||||
const {socks5,socks5DataFn,socks5ProcessFn,socks5RefreshFn,getSocks5Machines,sortSocks5} = provideSocks5();
|
||||
deviceAddHook('socks5',socks5DataFn,socks5ProcessFn,socks5RefreshFn);
|
||||
const {tunnel,tunnelDataFn,tunnelProcessFn,tunnelRefreshFn,sortTunnel} = provideTunnel();
|
||||
deviceAddHook('tunnel',tunnelDataFn,tunnelProcessFn,tunnelRefreshFn);
|
||||
const {updater, updaterDataFn, updaterProcessFn,updaterRefreshFn,updaterSubscribe, updaterClearTimeout} = provideUpdater();
|
||||
deviceAddHook('updater',updaterDataFn,updaterProcessFn,updaterRefreshFn);
|
||||
const {tuntap,tuntapDataFn,tuntapProcessFn,tuntapRefreshFn,getTuntapMachines,sortTuntapIP} = provideTuntap();
|
||||
deviceAddHook('tuntap',tuntapDataFn,tuntapProcessFn,tuntapRefreshFn);
|
||||
const {connections,connectionDataFn,connectionProcessFn,connectionRefreshFn } = provideConnections();
|
||||
deviceAddHook('connection',connectionDataFn,connectionProcessFn,connectionRefreshFn);
|
||||
|
||||
const handleSortChange = (row)=>{
|
||||
|
||||
devices.page.Request.Prop = row.prop;
|
||||
@@ -183,51 +191,25 @@ export default {
|
||||
devices.page.Request.Ids = [];
|
||||
}
|
||||
handlePageChange();
|
||||
handleTunnelRefresh();
|
||||
handleTuntapRefresh();
|
||||
handleSocks5Refresh();
|
||||
handleForwardRefresh();
|
||||
handleSForwardRefresh();
|
||||
handleAccesssRefresh();
|
||||
ElMessage.success({message:'刷新成功',grouping:true});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handlePageChange();
|
||||
handleTunnelRefresh();
|
||||
handleTuntapRefresh();
|
||||
handleSocks5Refresh();
|
||||
|
||||
startDeviceProcess();
|
||||
|
||||
_getTuntapInfo();
|
||||
_getSocks5Info();
|
||||
_getTunnelInfo();
|
||||
getTunnelOperating();
|
||||
getRelayOperating();
|
||||
_getForwardConnections();
|
||||
_getTuntapConnections();
|
||||
_getSocks5Connections();
|
||||
_getUpdater();
|
||||
_subscribeUpdater();
|
||||
|
||||
deviceStartProcess();
|
||||
updaterSubscribe();
|
||||
});
|
||||
onUnmounted(() => {
|
||||
clearDevicesTimeout();
|
||||
clearConnectionsTimeout();
|
||||
clearTuntapTimeout();
|
||||
clearSocks5Timeout();
|
||||
clearTunnelTimeout();
|
||||
|
||||
clearUpdaterTimeout();
|
||||
|
||||
deviceClearTimeout();
|
||||
updaterClearTimeout();
|
||||
});
|
||||
|
||||
return {
|
||||
state,globalData,devices,handleSortChange, handlePageRefresh, handlePageChange,handlePageSizeChange,
|
||||
state,devices,deviceRefreshHook,handleSortChange, handlePageRefresh, handlePageChange,handlePageSizeChange,
|
||||
tuntap,
|
||||
socks5, handleSocks5Refresh,
|
||||
tunnel,connections, handleTunnelRefresh,
|
||||
socks5,
|
||||
tunnel,connections,
|
||||
forward,
|
||||
sforward,
|
||||
updater,flow,oper,firewall,wakeup,transport,action
|
||||
|
||||
@@ -3,20 +3,10 @@
|
||||
<el-table-column prop="MachineId" :label="$t('home.device')" width="90" sortable="custom" ></el-table-column>
|
||||
<el-table-column prop="Version" :label="$t('home.version')" width="90" sortable="custom"></el-table-column>
|
||||
<el-table-column prop="tunnel" :label="$t('home.tunnel')" width="86" sortable="custom"></el-table-column>
|
||||
<el-table-column v-if="tuntap.show" prop="tuntap" :label="$t('home.tuntapIP')" width="160" sortable="custom"></el-table-column>
|
||||
<el-table-column v-if="socks5.show" prop="socks5" :label="$t('home.proxy')" width="160" sortable="custom"></el-table-column>
|
||||
<el-table-column label="columns" fixed="right">
|
||||
<el-table-column prop="tuntap" :label="$t('home.tuntapIP')" width="160" sortable="custom"></el-table-column>
|
||||
<el-table-column prop="socks5" :label="$t('home.proxy')" width="160" sortable="custom"></el-table-column>
|
||||
<el-table-column label="..." fixed="right">
|
||||
<template #header>
|
||||
<el-dropdown class="show-columns">
|
||||
<span class="el-dropdown-link">{{$t('home.showItems')}}<el-icon><ArrowDownBold /></el-icon></span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item><el-checkbox v-model="tuntap.show" @change="handleTuntapShow" size="small" style="margin-right:1rem">{{$t('home.tuntap')}}</el-checkbox> </el-dropdown-item>
|
||||
<el-dropdown-item><el-checkbox v-model="socks5.show" @change="handleSocks5Show" size="small" style="margin-right:1rem">{{$t('home.proxy')}}</el-checkbox> </el-dropdown-item>
|
||||
<el-dropdown-item><el-checkbox v-model="forward.show" @change="handleForwardShow" size="small" style="margin-right:0rem">{{$t('home.forward')}}</el-checkbox></el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="head">
|
||||
<Head></Head>
|
||||
</div>
|
||||
<div class="body flex-1 relative">
|
||||
<div class="body flex-1 relative" id="main-body">
|
||||
<List></List>
|
||||
</div>
|
||||
<div class="status">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
</dt>
|
||||
<dd class="tuntap">
|
||||
<TuntapShow v-if="tuntap.list[item.MachineId]" :item="item"></TuntapShow>
|
||||
<TuntapShow v-if="item.hook_tuntap" :item="item"></TuntapShow>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -32,53 +32,44 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { injectGlobalData } from '@/provide.js'
|
||||
import { reactive, onMounted, onUnmounted } from 'vue'
|
||||
import { StarFilled} from '@element-plus/icons-vue'
|
||||
import { provideTuntap } from '../../components/tuntap/tuntap'
|
||||
import { provideDevices } from '../../components/device/devices'
|
||||
import { provideUpdater } from '../../components/updater/updater'
|
||||
import UpdaterBtn from '../../components/updater/UpdaterBtn.vue'
|
||||
import DeviceName from '../../components/device/DeviceName.vue'
|
||||
import TuntapShow from '../../components/tuntap/TuntapShow.vue';
|
||||
import { provideConnections } from '../../components/connection/connections'
|
||||
import { provideTunnel } from '@/views/components/tunnel/tunnel'
|
||||
import { provideConnections } from '../../components/tunnel/connections'
|
||||
import { provideAccess } from '@/views/components/accesss/access'
|
||||
import { provideUpdater } from '@/views/components/updater/updater'
|
||||
export default {
|
||||
components: {StarFilled,UpdaterBtn,DeviceName,TuntapShow},
|
||||
setup(props) {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
});
|
||||
|
||||
const {devices, machineId, _getSignList, _getSignList1,
|
||||
handlePageChange, handlePageSizeChange, clearDevicesTimeout} = provideDevices();
|
||||
const {tuntap,_getTuntapInfo,handleTuntapRefresh,clearTuntapTimeout,handleTuntapEdit,sortTuntapIP} = provideTuntap();
|
||||
const {_getUpdater,_subscribeUpdater,clearUpdaterTimeout} = provideUpdater();
|
||||
|
||||
provideTunnel();
|
||||
|
||||
const connections = provideConnections();
|
||||
|
||||
const {devices,deviceAddHook,deviceRefreshHook, deviceStartProcess, handlePageChange, handlePageSizeChange,deviceClearTimeout,setSort} = provideDevices();
|
||||
const {accessDataFn,accessProcessFn,accessRefreshFn} = provideAccess();
|
||||
deviceAddHook('access',accessDataFn,accessProcessFn,accessRefreshFn);
|
||||
const {updater, updaterDataFn, updaterProcessFn,updaterRefreshFn,updaterSubscribe, updaterClearTimeout} = provideUpdater();
|
||||
deviceAddHook('updater',updaterDataFn,updaterProcessFn,updaterRefreshFn);
|
||||
const {tuntap,tuntapDataFn,tuntapProcessFn,tuntapRefreshFn,getTuntapMachines,sortTuntapIP} = provideTuntap();
|
||||
deviceAddHook('tuntap',tuntapDataFn,tuntapProcessFn,tuntapRefreshFn);
|
||||
const {connections,connectionDataFn,connectionProcessFn,connectionRefreshFn } = provideConnections();
|
||||
deviceAddHook('connection',connectionDataFn,connectionProcessFn,connectionRefreshFn);
|
||||
onMounted(() => {
|
||||
handlePageChange();
|
||||
handleTuntapRefresh();
|
||||
|
||||
_getSignList();
|
||||
_getSignList1();
|
||||
_getTuntapInfo();
|
||||
|
||||
_getUpdater();
|
||||
_subscribeUpdater();
|
||||
deviceStartProcess();
|
||||
});
|
||||
onUnmounted(() => {
|
||||
clearDevicesTimeout();
|
||||
clearTuntapTimeout();
|
||||
clearUpdaterTimeout();
|
||||
deviceClearTimeout();
|
||||
updaterClearTimeout();
|
||||
});
|
||||
|
||||
return {
|
||||
state,devices, machineId, handlePageChange,handlePageSizeChange,
|
||||
state,devices, handlePageChange,handlePageSizeChange,
|
||||
tuntap
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user