加入基本完备的反向代理
This commit is contained in:
parent
086d16e8c8
commit
937192f771
@ -134,7 +134,7 @@ namespace NoSugarNet.Adapter
|
||||
while (_localClientInfo.msgQueue.Count > 0)
|
||||
{
|
||||
IdxWithMsg msg = _localClientInfo.msgQueue.Dequeue();
|
||||
LocalMsgQueuePool._localMsgPool.Enqueue(msg);
|
||||
MsgQueuePool._MsgPool.Enqueue(msg);
|
||||
}
|
||||
|
||||
_localClientInfo._socket.Shutdown(SocketShutdown.Both);
|
||||
@ -314,7 +314,7 @@ namespace NoSugarNet.Adapter
|
||||
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||
return;
|
||||
|
||||
IdxWithMsg Msg = LocalMsgQueuePool._localMsgPool.Dequeue();
|
||||
IdxWithMsg Msg = MsgQueuePool._MsgPool.Dequeue();
|
||||
Msg.Idx = Idx;
|
||||
Msg.data = data;
|
||||
_localClientInfo.msgQueue.Enqueue(Msg);
|
||||
|
@ -6,13 +6,13 @@
|
||||
public byte[] data;
|
||||
}
|
||||
|
||||
public class LocalMsgQueuePool
|
||||
public class MsgQueuePool
|
||||
{
|
||||
public static LocalMsgQueuePool _localMsgPool = new LocalMsgQueuePool(1000);
|
||||
public static MsgQueuePool _MsgPool = new MsgQueuePool(1000);
|
||||
|
||||
Queue<IdxWithMsg> msg_pool;
|
||||
|
||||
public LocalMsgQueuePool(int capacity)
|
||||
public MsgQueuePool(int capacity)
|
||||
{
|
||||
msg_pool = new Queue<IdxWithMsg>(capacity);
|
||||
}
|
||||
|
@ -22,10 +22,11 @@ namespace NoSugarNet.ClientCore
|
||||
public static UserDataManager user;
|
||||
public static System.Timers.Timer _SpeedCheckTimeTimer;//速度检测计时器
|
||||
public static int TimerInterval = 1000;//计时器间隔
|
||||
static NetStatus netStatus;
|
||||
static NetStatus Forward_NetStatus;
|
||||
static NetStatus Reverse_NetStatus;
|
||||
|
||||
#region 委托和事件
|
||||
public delegate void OnUpdateStatusHandler(NetStatus Status);
|
||||
public delegate void OnUpdateStatusHandler(NetStatus ForwardStatus, NetStatus ReverseStatus);
|
||||
public static event OnUpdateStatusHandler OnUpdateStatus;
|
||||
#endregion
|
||||
|
||||
@ -43,7 +44,8 @@ namespace NoSugarNet.ClientCore
|
||||
forwardlocal = new AppForwardLocalClient();
|
||||
reverselocal = new AppReverseLocalClient(Config.compressAdapterType);
|
||||
user = new UserDataManager();
|
||||
netStatus = new NetStatus();
|
||||
Forward_NetStatus = new NetStatus();
|
||||
Reverse_NetStatus = new NetStatus();
|
||||
_SpeedCheckTimeTimer = new System.Timers.Timer();
|
||||
_SpeedCheckTimeTimer.Interval = TimerInterval;
|
||||
_SpeedCheckTimeTimer.Elapsed += Checktimer_Elapsed;
|
||||
@ -67,25 +69,46 @@ namespace NoSugarNet.ClientCore
|
||||
}
|
||||
|
||||
static void Checktimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
{
|
||||
forwardlocal.GetCurrLenght(out long resultReciveAllLenght, out long resultSendAllLenght);
|
||||
forwardlocal.GetClientCount(out int ClientUserCount, out int TunnelCount);
|
||||
|
||||
NetStatus resutnetStatus = new NetStatus()
|
||||
{
|
||||
TunnelCount = TunnelCount,
|
||||
ClientUserCount = ClientUserCount,
|
||||
srcSendAllLenght = resultSendAllLenght,
|
||||
srcReciveAllLenght = resultReciveAllLenght,
|
||||
srcReciveSecSpeed = (resultReciveAllLenght - netStatus.srcReciveAllLenght) / (TimerInterval / 1000),
|
||||
srcSendSecSpeed = (resultSendAllLenght - netStatus.srcSendAllLenght) / (TimerInterval / 1000),
|
||||
srcReciveSecSpeed = (resultReciveAllLenght - Forward_NetStatus.srcReciveAllLenght) / (TimerInterval / 1000),
|
||||
srcSendSecSpeed = (resultSendAllLenght - Forward_NetStatus.srcSendAllLenght) / (TimerInterval / 1000),
|
||||
tSendAllLenght = forwardlocal.tSendAllLenght,
|
||||
tReciveAllLenght = forwardlocal.tReciveAllLenght,
|
||||
tSendSecSpeed = (forwardlocal.tSendAllLenght - netStatus.tSendAllLenght) / (TimerInterval / 1000),
|
||||
tReciveSecSpeed = (forwardlocal.tReciveAllLenght - netStatus.tReciveAllLenght) / (TimerInterval / 1000),
|
||||
tSendSecSpeed = (forwardlocal.tSendAllLenght - Forward_NetStatus.tSendAllLenght) / (TimerInterval / 1000),
|
||||
tReciveSecSpeed = (forwardlocal.tReciveAllLenght - Forward_NetStatus.tReciveAllLenght) / (TimerInterval / 1000),
|
||||
};
|
||||
netStatus = resutnetStatus;
|
||||
OnUpdateStatus?.Invoke(resutnetStatus);
|
||||
Forward_NetStatus = resutnetStatus;
|
||||
}
|
||||
|
||||
{
|
||||
reverselocal.GetCurrLenght(out long resultReciveAllLenght, out long resultSendAllLenght);
|
||||
reverselocal.GetClientCount(out int ClientUserCount, out int TunnelCount);
|
||||
NetStatus resutnetStatus = new NetStatus()
|
||||
{
|
||||
TunnelCount = TunnelCount,
|
||||
ClientUserCount = ClientUserCount,
|
||||
srcSendAllLenght = resultSendAllLenght,
|
||||
srcReciveAllLenght = resultReciveAllLenght,
|
||||
srcReciveSecSpeed = (resultReciveAllLenght - Reverse_NetStatus.srcReciveAllLenght) / (TimerInterval / 1000),
|
||||
srcSendSecSpeed = (resultSendAllLenght - Reverse_NetStatus.srcSendAllLenght) / (TimerInterval / 1000),
|
||||
tSendAllLenght = reverselocal.tSendAllLenght,
|
||||
tReciveAllLenght = reverselocal.tReciveAllLenght,
|
||||
tSendSecSpeed = (reverselocal.tSendAllLenght - Reverse_NetStatus.tSendAllLenght) / (TimerInterval / 1000),
|
||||
tReciveSecSpeed = (reverselocal.tReciveAllLenght - Reverse_NetStatus.tReciveAllLenght) / (TimerInterval / 1000),
|
||||
};
|
||||
Reverse_NetStatus = resutnetStatus;
|
||||
}
|
||||
|
||||
OnUpdateStatus?.Invoke(Forward_NetStatus , Reverse_NetStatus);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,9 +15,7 @@ namespace ServerCore.Manager
|
||||
{
|
||||
Dictionary<byte, Protobuf_Cfgs_Single> mDictTunnelID2Cfg = new Dictionary<byte, Protobuf_Cfgs_Single>();
|
||||
Dictionary<byte, ForwardLocalListener> mDictTunnelID2Listeners = new Dictionary<byte, ForwardLocalListener>();
|
||||
//NoSugarNet.Adapter.DataHelper.CompressAdapter mCompressAdapter;
|
||||
NoSugarNet.Adapter.DataHelper.E_CompressAdapter compressAdapterType;
|
||||
//public LocalMsgQueuePool _localMsgPool = new LocalMsgQueuePool(1000);
|
||||
|
||||
public long tReciveAllLenght { get; private set; }
|
||||
public long tSendAllLenght { get; private set; }
|
||||
@ -149,7 +147,7 @@ namespace ServerCore.Manager
|
||||
#region 解析服务端下行数据
|
||||
public void Recive_CmdCfgs(byte[] reqData)
|
||||
{
|
||||
AppNoSugarNet.log.Debug("Recive_CmdCfgs");
|
||||
AppNoSugarNet.log.Debug("Forward->Recive_CmdCfgs");
|
||||
Protobuf_Cfgs msg = ProtoBufHelper.DeSerizlize<Protobuf_Cfgs>(reqData);
|
||||
|
||||
for (int i = 0;i < msg.Cfgs.Count;i++)
|
||||
@ -162,24 +160,23 @@ namespace ServerCore.Manager
|
||||
}
|
||||
public void Recive_TunnelS2CConnect(byte[] reqData)
|
||||
{
|
||||
AppNoSugarNet.log.Debug("Recive_TunnelS2CConnect");
|
||||
AppNoSugarNet.log.Debug("Forward->Recive_TunnelS2CConnect");
|
||||
Protobuf_Tunnel_Connect msg = ProtoBufHelper.DeSerizlize<Protobuf_Tunnel_Connect>(reqData);
|
||||
if(msg.Connected == 1)
|
||||
OnServerLocalConnect((byte)msg.TunnelID,(byte)msg.Idx);
|
||||
OnRemoteLocalConnect((byte)msg.TunnelID,(byte)msg.Idx);
|
||||
else
|
||||
OnServerLocalDisconnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
OnRemoteLocalDisconnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
}
|
||||
public void Recive_TunnelS2CDisconnect(byte[] reqData)
|
||||
{
|
||||
AppNoSugarNet.log.Debug("Recive_TunnelS2CDisconnect");
|
||||
AppNoSugarNet.log.Debug("Forward->Recive_TunnelS2CDisconnect");
|
||||
Protobuf_Tunnel_Disconnect msg = ProtoBufHelper.DeSerizlize<Protobuf_Tunnel_Disconnect>(reqData);
|
||||
OnServerLocalDisconnect((byte)msg.TunnelID,(byte)msg.Idx);
|
||||
OnRemoteLocalDisconnect((byte)msg.TunnelID,(byte)msg.Idx);
|
||||
}
|
||||
public void Recive_TunnelS2CData(byte[] reqData)
|
||||
{
|
||||
//AppNoSugarNet.log.Debug("Recive_TunnelS2CData");
|
||||
Protobuf_Tunnel_DATA msg = ProtoBufHelper.DeSerizlize<Protobuf_Tunnel_DATA>(reqData);
|
||||
OnServerLocalDataCallBack((byte)msg.TunnelID,(byte)msg.Idx, msg.HunterNetCoreData.ToArray());
|
||||
OnRemoteLocalDataCallBack((byte)msg.TunnelID,(byte)msg.Idx, msg.HunterNetCoreData.ToArray());
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -191,7 +188,7 @@ namespace ServerCore.Manager
|
||||
/// <param name="tunnelId"></param>
|
||||
public void OnClientLocalConnect(long UID, byte tunnelId,byte _Idx)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"OnClientLocalConnect {tunnelId},{_Idx}");
|
||||
AppNoSugarNet.log.Debug($"Forward->OnClientLocalConnect {tunnelId},{_Idx}");
|
||||
if (!mDictTunnelID2Cfg.ContainsKey(tunnelId))
|
||||
return;
|
||||
|
||||
@ -211,7 +208,7 @@ namespace ServerCore.Manager
|
||||
/// <param name="tunnelId"></param>
|
||||
public void OnClientLocalDisconnect(long UID, byte tunnelId, byte _Idx)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"OnClientLocalDisconnect {tunnelId},{_Idx}");
|
||||
AppNoSugarNet.log.Debug($"Forward->OnClientLocalDisconnect {tunnelId},{_Idx}");
|
||||
//隧道ID定位投递服务端本地连接
|
||||
if (!mDictTunnelID2Cfg.ContainsKey(tunnelId))
|
||||
return;
|
||||
@ -230,9 +227,9 @@ namespace ServerCore.Manager
|
||||
/// 当服务端本地端口连接
|
||||
/// </summary>
|
||||
/// <param name="tunnelId"></param>
|
||||
public void OnServerLocalConnect(byte tunnelId,byte Idx)
|
||||
public void OnRemoteLocalConnect(byte tunnelId,byte Idx)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"OnServerLocalConnect {tunnelId},{Idx}");
|
||||
AppNoSugarNet.log.Debug($"Forward->OnRemoteLocalConnect {tunnelId},{Idx}");
|
||||
if (!GetLocalListener(tunnelId, out ForwardLocalListener _listener))
|
||||
return;
|
||||
//维护状态
|
||||
@ -245,7 +242,7 @@ namespace ServerCore.Manager
|
||||
//投递给服务端,来自客户端本地的连接数据
|
||||
AppNoSugarNet.networkHelper.SendToServer((int)CommandID.CmdTunnelC2SForwardData, msg.data);
|
||||
//发送后回收
|
||||
LocalMsgQueuePool._localMsgPool.Enqueue(msg);
|
||||
MsgQueuePool._MsgPool.Enqueue(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -254,9 +251,9 @@ namespace ServerCore.Manager
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="tunnelId"></param>
|
||||
public void OnServerLocalDisconnect(byte tunnelId, byte Idx)
|
||||
public void OnRemoteLocalDisconnect(byte tunnelId, byte Idx)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"OnServerLocalDisconnect {tunnelId},{Idx}");
|
||||
AppNoSugarNet.log.Debug($"Forward->OnRemoteLocalDisconnect {tunnelId},{Idx}");
|
||||
if (!GetLocalListener(tunnelId, out ForwardLocalListener _listener))
|
||||
return;
|
||||
_listener.SetRemoteConnectd(Idx,false);
|
||||
@ -271,9 +268,9 @@ namespace ServerCore.Manager
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="tunnelId"></param>
|
||||
/// <param name="data"></param>
|
||||
public void OnServerLocalDataCallBack(byte tunnelId,byte Idx, byte[] data)
|
||||
public void OnRemoteLocalDataCallBack(byte tunnelId,byte Idx, byte[] data)
|
||||
{
|
||||
//AppNoSugarNet.log.Info($"OnServerLocalDataCallBack {tunnelId},{Idx},Data长度:{data.Length}");
|
||||
//AppNoSugarNet.log.Info($"OnRemoteLocalDataCallBack {tunnelId},{Idx},Data长度:{data.Length}");
|
||||
if (!GetLocalListener(tunnelId, out ForwardLocalListener _listener))
|
||||
return;
|
||||
//记录压缩前数据长度
|
||||
|
@ -17,6 +17,8 @@ namespace ServerCore.Manager
|
||||
public long tReciveAllLenght { get; private set; }
|
||||
public long tSendAllLenght { get; private set; }
|
||||
|
||||
Protobuf_Cfgs _Send_Protobuf_Cfgs = new Protobuf_Cfgs();
|
||||
|
||||
static long GetCommKey(long Uid, int Tunnel, int Idx)
|
||||
{
|
||||
return (Uid * 10000000) + (Tunnel * 10000) + Idx;
|
||||
@ -39,19 +41,30 @@ namespace ServerCore.Manager
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTunnelS2CReverseData, Recive_TunnelS2CData);
|
||||
}
|
||||
|
||||
Protobuf_Cfgs _Protobuf_Cfgs = new Protobuf_Cfgs();
|
||||
public void GetCurrLenght(out long resultReciveAllLenght, out long resultSendAllLenght)
|
||||
{
|
||||
resultReciveAllLenght = 0;
|
||||
resultSendAllLenght = 0;
|
||||
long[] Keys = mDictCommKey2LocalClients.Keys.ToArray();
|
||||
for (int i = 0; i < Keys.Length; i++)
|
||||
{
|
||||
//local和转发 收发相反
|
||||
resultSendAllLenght += mDictCommKey2LocalClients[Keys[i]].mReciveAllLenght;
|
||||
resultReciveAllLenght += mDictCommKey2LocalClients[Keys[i]].mSendAllLenght;
|
||||
}
|
||||
}
|
||||
|
||||
public void Send_ClientCfg()
|
||||
{
|
||||
AppNoSugarNet.log.Debug("Reverse->-->Send_ClientCfg");
|
||||
|
||||
_Protobuf_Cfgs.CompressAdapterType = (int)Config.compressAdapterType;
|
||||
_Protobuf_Cfgs.Cfgs.Clear();
|
||||
_Send_Protobuf_Cfgs.CompressAdapterType = (int)Config.compressAdapterType;
|
||||
_Send_Protobuf_Cfgs.Cfgs.Clear();
|
||||
foreach (var cfg in Config.cfgs)
|
||||
{
|
||||
_Protobuf_Cfgs.Cfgs.Add(new Protobuf_Cfgs_Single() { Port = cfg.Value.RemoteLocalPort, TunnelID = cfg.Value.TunnelId });
|
||||
_Send_Protobuf_Cfgs.Cfgs.Add(new Protobuf_Cfgs_Single() { Port = cfg.Value.RemoteLocalPort, TunnelID = cfg.Value.TunnelId });
|
||||
}
|
||||
AppNoSugarNet.networkHelper.SendToServer((int)CommandID.CmdClientCfgs, ProtoBufHelper.Serizlize(_Protobuf_Cfgs));
|
||||
AppNoSugarNet.networkHelper.SendToServer((int)CommandID.CmdClientCfgs, ProtoBufHelper.Serizlize(_Send_Protobuf_Cfgs));
|
||||
}
|
||||
|
||||
|
||||
@ -61,21 +74,20 @@ namespace ServerCore.Manager
|
||||
AppNoSugarNet.log.Debug("Reverse->Recive_TunnelS2CConnect");
|
||||
Protobuf_Tunnel_Connect msg = ProtoBufHelper.DeSerizlize<Protobuf_Tunnel_Connect>(reqData);
|
||||
if (msg.Connected == 1)
|
||||
OnServerLocalConnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
OnRemoteLocalConnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
else
|
||||
OnServerLocalDisconnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
OnRemoteLocalDisconnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
}
|
||||
public void Recive_TunnelS2CDisconnect(byte[] reqData)
|
||||
{
|
||||
AppNoSugarNet.log.Debug("Reverse->Recive_TunnelS2CDisconnect");
|
||||
Protobuf_Tunnel_Disconnect msg = ProtoBufHelper.DeSerizlize<Protobuf_Tunnel_Disconnect>(reqData);
|
||||
OnServerLocalDisconnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
OnRemoteLocalDisconnect((byte)msg.TunnelID, (byte)msg.Idx);
|
||||
}
|
||||
public void Recive_TunnelS2CData(byte[] reqData)
|
||||
{
|
||||
//AppNoSugarNet.log.Debug("Recive_TunnelS2CData");
|
||||
Protobuf_Tunnel_DATA msg = ProtoBufHelper.DeSerizlize<Protobuf_Tunnel_DATA>(reqData);
|
||||
OnServerTunnelDataCallBack(AppNoSugarNet.user.userdata.UID, (byte)msg.TunnelID, (byte)msg.Idx, msg.HunterNetCoreData.ToArray());
|
||||
OnRemoteTunnelDataCallBack(AppNoSugarNet.user.userdata.UID, (byte)msg.TunnelID, (byte)msg.Idx, msg.HunterNetCoreData.ToArray());
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -86,9 +98,9 @@ namespace ServerCore.Manager
|
||||
/// 当服务端本地端口连接
|
||||
/// </summary>
|
||||
/// <param name="tunnelId"></param>
|
||||
public void OnServerLocalConnect(byte tunnelId, byte Idx)
|
||||
public void OnRemoteLocalConnect(byte tunnelId, byte Idx)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"Reverse->OnClientLocalConnect!!!!!! {AppNoSugarNet.user.userdata.UID},{tunnelId},{Idx}");
|
||||
AppNoSugarNet.log.Debug($"Reverse->OnRemoteLocalConnect{AppNoSugarNet.user.userdata.UID},{tunnelId},{Idx}");
|
||||
|
||||
if (!Config.cfgs.ContainsKey(tunnelId))
|
||||
return;
|
||||
@ -104,7 +116,6 @@ namespace ServerCore.Manager
|
||||
if (!serverLocalClient.Init(tunnelDataCfg.LocalTargetIP, tunnelDataCfg.LocalTargetPort))
|
||||
{
|
||||
//TODO告知客户端连接失败
|
||||
|
||||
byte[] respData = ProtoBufHelper.Serizlize(new Protobuf_Tunnel_Connect()
|
||||
{
|
||||
TunnelID = tunnelId,
|
||||
@ -122,9 +133,9 @@ namespace ServerCore.Manager
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="tunnelId"></param>
|
||||
public void OnServerLocalDisconnect(byte tunnelId, byte Idx)
|
||||
public void OnRemoteLocalDisconnect(byte tunnelId, byte Idx)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"Reverse->OnServerLocalDisconnect,收到客户端断开链接!!!!!! {AppNoSugarNet.user.userdata.UID},{tunnelId},{Idx}");
|
||||
AppNoSugarNet.log.Debug($"Reverse->OnRemoteLocalDisconnect {AppNoSugarNet.user.userdata.UID},{tunnelId},{Idx}");
|
||||
|
||||
//隧道ID定位投递服务端本地连接
|
||||
if (!GetClientLocalClient(AppNoSugarNet.user.userdata.UID, tunnelId, Idx, out BackwardLocalClient LocalClient))
|
||||
@ -279,9 +290,8 @@ namespace ServerCore.Manager
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="tunnelId"></param>
|
||||
/// <param name="data"></param>
|
||||
public void OnServerTunnelDataCallBack(long uid, byte tunnelId, byte Idx, byte[] data)
|
||||
public void OnRemoteTunnelDataCallBack(long uid, byte tunnelId, byte Idx, byte[] data)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"Reverse->OnServerTunnelDataCallBack {uid},{tunnelId},{Idx},data -> {data.Length}");
|
||||
//隧道ID定位投递服务端本地连接
|
||||
if (!GetClientLocalClient(uid, tunnelId, Idx, out BackwardLocalClient serverLocalClient))
|
||||
return;
|
||||
@ -302,11 +312,7 @@ namespace ServerCore.Manager
|
||||
/// <param name="data"></param>
|
||||
public void OnClientLocalDataCallBack(long uid, byte tunnelId, byte Idx, byte[] data)
|
||||
{
|
||||
AppNoSugarNet.log.Debug($"Reverse->OnClientLocalDataCallBack {uid},{tunnelId},{Idx},data -> {data.Length}");
|
||||
//ServerManager.g_Log.Debug($"OnServerLocalDataCallBack {uid},{tunnelId},{Idx}");
|
||||
//if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
||||
// return;
|
||||
|
||||
//AppNoSugarNet.log.Debug($"Reverse->OnClientLocalDataCallBack {uid},{tunnelId},{Idx},data -> {data.Length}");
|
||||
int SlienLenght = 1000;
|
||||
//判断数据量大时分包
|
||||
if (data.Length > SlienLenght)
|
||||
@ -335,9 +341,6 @@ namespace ServerCore.Manager
|
||||
}
|
||||
void SendDataToRemote(long uid, byte tunnelId, byte Idx, byte[] data)
|
||||
{
|
||||
//if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
||||
// return;
|
||||
|
||||
//压缩
|
||||
data = mCompressAdapter.Compress(data);
|
||||
//记录压缩后数据长度
|
||||
|
@ -26,6 +26,33 @@ namespace ServerCore.Manager
|
||||
return CommKey / 10000000;
|
||||
}
|
||||
|
||||
public void GetCurrLenght(out long resultReciveAllLenght, out long resultSendAllLenght)
|
||||
{
|
||||
resultReciveAllLenght = 0;
|
||||
resultSendAllLenght = 0;
|
||||
long[] Keys = mDictCommKey2LocalListeners.Keys.ToArray();
|
||||
for (int i = 0; i < Keys.Length; i++)
|
||||
{
|
||||
//local和转发 收发相反
|
||||
resultSendAllLenght += mDictCommKey2LocalListeners[Keys[i]].mReciveAllLenght;
|
||||
resultReciveAllLenght += mDictCommKey2LocalListeners[Keys[i]].mSendAllLenght;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetClientCount(out int ClientUserCount, out int TunnelCount)
|
||||
{
|
||||
TunnelCount = mDictCommKey2LocalListeners.Count;
|
||||
long[] CommIDKeys = mDictCommKey2LocalListeners.Keys.ToArray();
|
||||
List<long> TempHadLocalConnetList = new List<long>();
|
||||
for (int i = 0; i < CommIDKeys.Length; i++)
|
||||
{
|
||||
long uid = GetUidForCommKey(CommIDKeys[i]);
|
||||
if (!TempHadLocalConnetList.Contains(uid))
|
||||
TempHadLocalConnetList.Add(uid);
|
||||
}
|
||||
ClientUserCount = TempHadLocalConnetList.Count;
|
||||
}
|
||||
|
||||
public ReverseLocalClientManager()
|
||||
{
|
||||
//注册网络消息
|
||||
@ -151,7 +178,7 @@ namespace ServerCore.Manager
|
||||
}
|
||||
public void Recive_TunnelC2SData(Socket sk, byte[] reqData)
|
||||
{
|
||||
ServerManager.g_Log.Debug("Reverse->Recive_TunnelC2SData");
|
||||
//ServerManager.g_Log.Debug("Reverse->Recive_TunnelC2SData");
|
||||
ClientInfo _c = ServerManager.g_ClientMgr.GetClientForSocket(sk);
|
||||
Protobuf_Tunnel_DATA msg = ProtoBufHelper.DeSerizlize<Protobuf_Tunnel_DATA>(reqData);
|
||||
OnRemoteLocalDataCallBack(_c.UID, (byte)msg.TunnelID, (byte)msg.Idx, msg.HunterNetCoreData.ToArray());
|
||||
@ -234,7 +261,7 @@ namespace ServerCore.Manager
|
||||
//投递给服务端,来自客户端本地的连接数据
|
||||
ServerManager.g_ClientMgr.ClientSend(client, (int)CommandID.CmdTunnelS2CReverseData, (int)ErrorCode.ErrorOk, msg.data);
|
||||
//发送后回收
|
||||
LocalMsgQueuePool._localMsgPool.Enqueue(msg);
|
||||
MsgQueuePool._MsgPool.Enqueue(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -268,7 +295,7 @@ namespace ServerCore.Manager
|
||||
/// <param name="data"></param>
|
||||
public void OnRemoteLocalDataCallBack(long UID, byte tunnelId, byte Idx, byte[] data)
|
||||
{
|
||||
ServerManager.g_Log.Debug($"Reverse->OnRemoteLocalDataCallBack {UID},{tunnelId},{Idx},Data长度:{data.Length}");
|
||||
//ServerManager.g_Log.Debug($"Reverse->OnRemoteLocalDataCallBack {UID},{tunnelId},{Idx},Data长度:{data.Length}");
|
||||
|
||||
if (!ServerManager.g_ClientMgr.GetClientByUID(UID, out ClientInfo client))
|
||||
return;
|
||||
@ -290,7 +317,7 @@ namespace ServerCore.Manager
|
||||
/// <param name="data"></param>
|
||||
public void OnTunnelDataCallBack(long UID, byte tunnelId, byte Idx, byte[] data)
|
||||
{
|
||||
ServerManager.g_Log.Debug($"Reverse->OnTunnelDataCallBack {UID},{tunnelId},{Idx},Data长度:{data.Length}");
|
||||
//ServerManager.g_Log.Debug($"Reverse->OnTunnelDataCallBack {UID},{tunnelId},{Idx},Data长度:{data.Length}");
|
||||
|
||||
int SlienLenght = 1000;
|
||||
//判断数据量大时分包
|
||||
@ -321,7 +348,7 @@ namespace ServerCore.Manager
|
||||
|
||||
void SendDataToRemote(long UID, byte tunnelId, byte Idx, byte[] data)
|
||||
{
|
||||
ServerManager.g_Log.Debug($"Reverse->SendDataToRemote {UID},{tunnelId},{Idx},Data长度:{data.Length}");
|
||||
//ServerManager.g_Log.Debug($"Reverse->SendDataToRemote {UID},{tunnelId},{Idx},Data长度:{data.Length}");
|
||||
|
||||
if (!ServerManager.g_ClientMgr.GetClientByUID(UID, out ClientInfo client))
|
||||
return;
|
||||
|
@ -20,9 +20,10 @@ namespace ServerCore.Manager
|
||||
public static int TimerInterval = 1000;//计时器间隔
|
||||
static long mLastReciveAllLenght = 0;
|
||||
static long mSendAllLenght = 0;
|
||||
static NetStatus netStatus;
|
||||
static NetStatus Forward_NetStatus;
|
||||
static NetStatus Reverse_NetStatus;
|
||||
#region 委托和事件
|
||||
public delegate void OnUpdateStatusHandler(NetStatus Status);
|
||||
public delegate void OnUpdateStatusHandler(NetStatus ForwardStatus, NetStatus ReverseStatus);
|
||||
public static event OnUpdateStatusHandler OnUpdateStatus;
|
||||
#endregion
|
||||
|
||||
@ -40,7 +41,8 @@ namespace ServerCore.Manager
|
||||
//g_SocketMgr = new IOCPNetWork(1024, 1024);
|
||||
g_SocketMgr = new IOCPNetWork(1024, 4096);
|
||||
|
||||
netStatus = new NetStatus();
|
||||
Forward_NetStatus = new NetStatus();
|
||||
Reverse_NetStatus = new NetStatus();
|
||||
|
||||
g_SocketMgr.Init();
|
||||
g_SocketMgr.Start(new IPEndPoint(IPAddress.Any.Address, port));
|
||||
@ -55,6 +57,8 @@ namespace ServerCore.Manager
|
||||
|
||||
static void Checktimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
{
|
||||
|
||||
g_ForwardLocal.GetCurrLenght(out long resultReciveAllLenght, out long resultSendAllLenght);
|
||||
g_ForwardLocal.GetClientCount(out int ClientUserCount, out int TunnelCount);
|
||||
NetStatus resutnetStatus = new NetStatus()
|
||||
@ -63,15 +67,37 @@ namespace ServerCore.Manager
|
||||
ClientUserCount = ClientUserCount,
|
||||
srcSendAllLenght = resultSendAllLenght,
|
||||
srcReciveAllLenght = resultReciveAllLenght,
|
||||
srcReciveSecSpeed = (resultReciveAllLenght - netStatus.srcReciveAllLenght) / (TimerInterval / 1000),
|
||||
srcSendSecSpeed = (resultSendAllLenght - netStatus.srcSendAllLenght) / (TimerInterval / 1000),
|
||||
srcReciveSecSpeed = (resultReciveAllLenght - Forward_NetStatus.srcReciveAllLenght) / (TimerInterval / 1000),
|
||||
srcSendSecSpeed = (resultSendAllLenght - Forward_NetStatus.srcSendAllLenght) / (TimerInterval / 1000),
|
||||
tSendAllLenght = g_ForwardLocal.tSendAllLenght,
|
||||
tReciveAllLenght = g_ForwardLocal.tReciveAllLenght,
|
||||
tSendSecSpeed = (g_ForwardLocal.tSendAllLenght - netStatus.tSendAllLenght) / (TimerInterval / 1000),
|
||||
tReciveSecSpeed = (g_ForwardLocal.tReciveAllLenght - netStatus.tReciveAllLenght) / (TimerInterval / 1000),
|
||||
tSendSecSpeed = (g_ForwardLocal.tSendAllLenght - Forward_NetStatus.tSendAllLenght) / (TimerInterval / 1000),
|
||||
tReciveSecSpeed = (g_ForwardLocal.tReciveAllLenght - Forward_NetStatus.tReciveAllLenght) / (TimerInterval / 1000),
|
||||
};
|
||||
netStatus = resutnetStatus;
|
||||
OnUpdateStatus?.Invoke(resutnetStatus);
|
||||
Forward_NetStatus = resutnetStatus;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
g_ReverseLocal.GetCurrLenght(out long resultReciveAllLenght, out long resultSendAllLenght);
|
||||
g_ReverseLocal.GetClientCount(out int ClientUserCount, out int TunnelCount);
|
||||
NetStatus resutnetStatus = new NetStatus()
|
||||
{
|
||||
TunnelCount = TunnelCount,
|
||||
ClientUserCount = ClientUserCount,
|
||||
srcSendAllLenght = resultSendAllLenght,
|
||||
srcReciveAllLenght = resultReciveAllLenght,
|
||||
srcReciveSecSpeed = (resultReciveAllLenght - Reverse_NetStatus.srcReciveAllLenght) / (TimerInterval / 1000),
|
||||
srcSendSecSpeed = (resultSendAllLenght - Reverse_NetStatus.srcSendAllLenght) / (TimerInterval / 1000),
|
||||
tSendAllLenght = g_ForwardLocal.tSendAllLenght,
|
||||
tReciveAllLenght = g_ForwardLocal.tReciveAllLenght,
|
||||
tSendSecSpeed = (g_ForwardLocal.tSendAllLenght - Reverse_NetStatus.tSendAllLenght) / (TimerInterval / 1000),
|
||||
tReciveSecSpeed = (g_ForwardLocal.tReciveAllLenght - Reverse_NetStatus.tReciveAllLenght) / (TimerInterval / 1000),
|
||||
};
|
||||
Reverse_NetStatus = resutnetStatus;
|
||||
}
|
||||
|
||||
OnUpdateStatus?.Invoke(Forward_NetStatus, Reverse_NetStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
65
README.md
65
README.md
@ -1,6 +1,8 @@
|
||||
## NoSugarNet
|
||||
|
||||
NoSugarNet(无糖网络),一个有效降低任意C/S程序(软件,程序)网络流量传输的网络中间工具。
|
||||
NoSugarNet(无糖网络),一个有效降低任意C/S程序(游戏,程序)网络流量传输的网络中间工具。
|
||||
|
||||
同时,也可以作为通用性极强、高性能、反向代理内网穿透工具。
|
||||
|
||||
### 有意义的应用场景
|
||||
|
||||
@ -20,7 +22,13 @@ NoSugarNet(无糖网络),一个有效降低任意C/S程序(软件,程
|
||||
|
||||
使用NoSugarNet,您就可以突破这个限制。
|
||||
|
||||
3. 您的程序集成需求
|
||||
3. 反向代理
|
||||
|
||||
在某一方面,优于frp等反向代理工具。
|
||||
|
||||
frp等反代工具,是端口一对一的。而NoSugarNet是,多对一对一对多。
|
||||
|
||||
4. 您的程序集成需求
|
||||
|
||||
您可以在你的网关程序,客户端登陆器,代理程序或传输业务层接入NoSugarNet。
|
||||
|
||||
@ -43,20 +51,14 @@ NoSugarNet(无糖网络),一个有效降低任意C/S程序(软件,程
|
||||
|
||||
其中config.cfg 是配置文件
|
||||
|
||||
格式:
|
||||
|
||||
```
|
||||
<配置编号>:<目标服务端IP>:<目标服务器端口>:<客户端监听的端口>
|
||||
```
|
||||
|
||||
每个配置换行
|
||||
服务器代理,可以配置正向代理的配置。
|
||||
|
||||
形如
|
||||
|
||||
```
|
||||
{
|
||||
"ServerPort": 1000,
|
||||
"CompressAdapterType": 1,
|
||||
"CompressAdapterType": 0,
|
||||
"TunnelList": [
|
||||
{
|
||||
"ServerLocalTargetIP": "1.2.3.4",
|
||||
@ -74,24 +76,55 @@ NoSugarNet(无糖网络),一个有效降低任意C/S程序(软件,程
|
||||
|
||||
表示
|
||||
|
||||
本代理服务,可以连接代理访问,1.2.3.4:3389 和 1.2.3.5:3306
|
||||
服务器正向代理服务,可以连接代理访问,1.2.3.4:3389 和 1.2.3.5:3306
|
||||
|
||||
配置编号和客户端安排端口会发送到给客户端。
|
||||
TunnelList 是告知客户端[正向代理]的配置,
|
||||
|
||||
客户端连接服务器获取基本信息后,客户端会开始监听10001和10002
|
||||
配置编号会发送给客户端。
|
||||
|
||||
客户端连接服务器获取基本信息后,客户端会开始监听10001和10002,开启正向代理服务。
|
||||
|
||||
效果为:
|
||||
|
||||
任何用户 访问客户端侧的 localhost:13389 最终会转发到 服务器侧的1.2.3.4:3389
|
||||
|
||||
任何用户 访问客户端侧的 localhost:13306 最终会转发到 服务器侧的1.2.3.4:3306
|
||||
|
||||
————————————————————
|
||||
|
||||
## 客户端 NoSugarNet.ClientCli
|
||||
|
||||
其中config.cfg 是配置文件
|
||||
其中config.cfg 是配置文件 配置服务器IP和端口,以及可选的请求反向代理的本地端口和的远端端口
|
||||
|
||||
格式:
|
||||
|
||||
```
|
||||
<代理服务端IP>:<代理服务端Port>
|
||||
{
|
||||
"ServerIP": "6.6.6.6",
|
||||
"ServerPort": 1000,
|
||||
"CompressAdapterType": 0,
|
||||
"TunnelList": [
|
||||
{
|
||||
"LocalTargetIP": "127.0.0.1",
|
||||
"LocalTargetPort": 3389,
|
||||
"RemoteLocalPort": 20001
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
*代理端口IP可以改,端口哦固定为1000,因为服务器中转端口写死的1000(笑)
|
||||
表示:
|
||||
|
||||
客户端连接服务器IP 为6.6.6.6 端口1000
|
||||
|
||||
TunnelList 是客户端请求服务器[反向代理]的配置
|
||||
|
||||
配置发送给服务端。
|
||||
|
||||
客户端连接服务器上报配置后,服务端会开始监听20001端口,开启反向代理服务。
|
||||
|
||||
如上示例为 请求服务器监听20001端口,做反向代理到本地127.0.0.1:3389
|
||||
|
||||
效果为:
|
||||
|
||||
任何用户 访问服务器侧的 服务器IP:20001 最终会转发到 客户端测侧的127.0.0.1:3389
|
||||
|
@ -56,10 +56,10 @@ namespace NoSugarNet.ClientCli
|
||||
}
|
||||
}
|
||||
}
|
||||
static void OnUpdateStatus(NetStatus netState)
|
||||
static void OnUpdateStatus(NetStatus Forward_NetStatus, NetStatus Reverse_NetStatus)
|
||||
{
|
||||
//string info = $"User:{netState.ClientUserCount} Tun:{netState.TunnelCount} rec:{netState.srcReciveAllLenght}|{netState.tReciveAllLenght} {ConvertBytesToKilobytes(netState.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tReciveSecSpeed)}K/s send:{netState.srcSendAllLenght}|{netState.tSendAllLenght} {ConvertBytesToKilobytes(netState.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tSendSecSpeed)}K/s";
|
||||
string info = $"User:{netState.ClientUserCount} Tun:{netState.TunnelCount} rec: {ConvertBytesToKilobytes(netState.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tReciveSecSpeed)}K/s send: {ConvertBytesToKilobytes(netState.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tSendSecSpeed)}K/s";
|
||||
string info = $"Forward: t:{Forward_NetStatus.TunnelCount} r:{ConvertBytesToKilobytes(Forward_NetStatus.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(Forward_NetStatus.tReciveSecSpeed)}K/s s: {ConvertBytesToKilobytes(Forward_NetStatus.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(Forward_NetStatus.tSendSecSpeed)}K/s" +
|
||||
$"| Reverse t:{Reverse_NetStatus.TunnelCount} r:{ConvertBytesToKilobytes(Reverse_NetStatus.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(Reverse_NetStatus.tReciveSecSpeed)}K/s s: {ConvertBytesToKilobytes(Reverse_NetStatus.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(Reverse_NetStatus.tSendSecSpeed)}K/s";
|
||||
Console.Title = Title + info;
|
||||
Console.WriteLine(info);
|
||||
}
|
||||
|
@ -6,13 +6,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net8.0\publish\win-x64\</PublishDir>
|
||||
<PublishDir>bin\Release\net8.0\publish\linux-x64\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
<PublishReadyToRun>false</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2024-06-18T04:59:35.6257454Z;True|2024-06-18T10:27:07.8233386+08:00;True|2024-06-17T15:05:24.3158316+08:00;True|2024-05-20T18:14:09.8394409+08:00;True|2024-05-20T18:13:33.8442145+08:00;True|2024-05-20T18:01:49.3220793+08:00;True|2024-05-20T18:01:28.3681468+08:00;True|2024-04-14T22:24:49.2846754+08:00;True|2024-01-23T16:35:06.3918472+08:00;True|2024-01-23T16:34:52.0595483+08:00;True|2024-01-23T16:27:36.4850749+08:00;True|2024-01-23T16:27:04.0721589+08:00;</History>
|
||||
<History>True|2024-06-26T08:20:13.8778793Z;True|2024-06-26T15:41:32.1172715+08:00;True|2024-06-18T12:59:35.6257454+08:00;True|2024-06-18T10:27:07.8233386+08:00;True|2024-06-17T15:05:24.3158316+08:00;True|2024-05-20T18:14:09.8394409+08:00;True|2024-05-20T18:13:33.8442145+08:00;True|2024-05-20T18:01:49.3220793+08:00;True|2024-05-20T18:01:28.3681468+08:00;True|2024-04-14T22:24:49.2846754+08:00;True|2024-01-23T16:35:06.3918472+08:00;True|2024-01-23T16:34:52.0595483+08:00;True|2024-01-23T16:27:36.4850749+08:00;True|2024-01-23T16:27:04.0721589+08:00;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -38,10 +38,10 @@ namespace NoSugarNet.ServerCli
|
||||
}
|
||||
}
|
||||
|
||||
static void OnUpdateStatus(NetStatus netState)
|
||||
static void OnUpdateStatus(NetStatus Forward_NetStatus, NetStatus Reverse_NetStatus)
|
||||
{
|
||||
//string info = $"User:{netState.ClientUserCount} Tun:{netState.TunnelCount} rec:{netState.srcReciveAllLenght}|{netState.tReciveAllLenght} {ConvertBytesToKilobytes(netState.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tReciveSecSpeed)}K/s send:{netState.srcSendAllLenght}|{netState.tSendAllLenght} {ConvertBytesToKilobytes(netState.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tSendSecSpeed)}K/s";
|
||||
string info = $"User:{netState.ClientUserCount} Tun:{netState.TunnelCount} rec: {ConvertBytesToKilobytes(netState.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tReciveSecSpeed)}K/s send: {ConvertBytesToKilobytes(netState.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(netState.tSendSecSpeed)}K/s";
|
||||
string info = $"Forward: user:{Forward_NetStatus.ClientUserCount} t:{Forward_NetStatus.TunnelCount} r:{ConvertBytesToKilobytes(Forward_NetStatus.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(Forward_NetStatus.tReciveSecSpeed)}K/s s: {ConvertBytesToKilobytes(Forward_NetStatus.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(Forward_NetStatus.tSendSecSpeed)}K/s" +
|
||||
$"| Reverse user:{Reverse_NetStatus.ClientUserCount} t:{Reverse_NetStatus.TunnelCount} r:{ConvertBytesToKilobytes(Reverse_NetStatus.srcReciveSecSpeed)}K/s|{ConvertBytesToKilobytes(Reverse_NetStatus.tReciveSecSpeed)}K/s s: {ConvertBytesToKilobytes(Reverse_NetStatus.srcSendSecSpeed)}K/s|{ConvertBytesToKilobytes(Reverse_NetStatus.tSendSecSpeed)}K/s";
|
||||
Console.Title = Title + info;
|
||||
Console.WriteLine(info);
|
||||
}
|
||||
|
@ -6,13 +6,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net8.0\publish\win-x64\</PublishDir>
|
||||
<PublishDir>bin\Release\net8.0\publish\linux-x64\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2024-06-25T05:14:05.9372915Z;True|2024-06-18T11:37:53.3986849+08:00;True|2024-06-18T11:21:56.8035265+08:00;True|2024-06-18T11:21:19.5434721+08:00;True|2024-06-18T11:21:01.1589956+08:00;True|2024-06-18T11:13:38.3624463+08:00;True|2024-06-18T11:10:28.0508856+08:00;True|2024-06-18T10:39:23.0033920+08:00;True|2024-06-18T10:28:08.9658896+08:00;True|2024-06-17T14:46:33.2307641+08:00;True|2024-05-20T17:56:34.6581491+08:00;True|2024-04-23T17:02:36.4793408+08:00;True|2024-04-15T15:24:50.3598281+08:00;True|2024-04-15T15:24:34.0374231+08:00;True|2024-01-25T17:09:07.9161603+08:00;True|2024-01-23T18:28:01.1220581+08:00;True|2024-01-23T16:36:21.1141328+08:00;</History>
|
||||
<History>True|2024-06-26T07:56:48.7750337Z;True|2024-06-26T15:52:00.1532751+08:00;True|2024-06-25T13:14:05.9372915+08:00;True|2024-06-18T11:37:53.3986849+08:00;True|2024-06-18T11:21:56.8035265+08:00;True|2024-06-18T11:21:19.5434721+08:00;True|2024-06-18T11:21:01.1589956+08:00;True|2024-06-18T11:13:38.3624463+08:00;True|2024-06-18T11:10:28.0508856+08:00;True|2024-06-18T10:39:23.0033920+08:00;True|2024-06-18T10:28:08.9658896+08:00;True|2024-06-17T14:46:33.2307641+08:00;True|2024-05-20T17:56:34.6581491+08:00;True|2024-04-23T17:02:36.4793408+08:00;True|2024-04-15T15:24:50.3598281+08:00;True|2024-04-15T15:24:34.0374231+08:00;True|2024-01-25T17:09:07.9161603+08:00;True|2024-01-23T18:28:01.1220581+08:00;True|2024-01-23T16:36:21.1141328+08:00;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user