抽象Forward和Backward网络监听
This commit is contained in:
parent
59ee584c2c
commit
2c11d70b68
112
NoSugarNet.Adapter/BackwardLocalClient.cs
Normal file
112
NoSugarNet.Adapter/BackwardLocalClient.cs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
using HaoYueNet.ClientNetwork.OtherMode;
|
||||||
|
|
||||||
|
namespace NoSugarNet.Adapter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 继承网络库,以支持网络功能
|
||||||
|
/// </summary>
|
||||||
|
public class BackwardLocalClient : NetworkHelperCore_SourceMode
|
||||||
|
{
|
||||||
|
public long mUID;
|
||||||
|
public byte mTunnelID;
|
||||||
|
public byte mIdx;
|
||||||
|
public long mReciveAllLenght;
|
||||||
|
public long mSendAllLenght;
|
||||||
|
|
||||||
|
public delegate void OnBackwardLogOutHandler(int LogLevel, string Msg);
|
||||||
|
public delegate void OnBackwardConnectHandler(long uid, byte tunnelId, byte Idx, BackwardLocalClient serverLocalClient);
|
||||||
|
public delegate void OnBackwardDisconnectHandler(long uid, byte tunnelId, byte Idx, BackwardLocalClient serverLocalClient);
|
||||||
|
public delegate void OnBackwardDataCallBackHandler(long uid, byte tunnelId, byte Idx, byte[] data);
|
||||||
|
|
||||||
|
public event OnBackwardLogOutHandler OnBackwardLogOut;
|
||||||
|
public event OnBackwardConnectHandler OnBackwardConnect;
|
||||||
|
public event OnBackwardDisconnectHandler OnBackwardDisconnect;
|
||||||
|
public event OnBackwardDataCallBackHandler OnBackwardDataCallBack;
|
||||||
|
|
||||||
|
public BackwardLocalClient(long UID,byte TunnelID, byte Idx)
|
||||||
|
{
|
||||||
|
mUID = UID;
|
||||||
|
mTunnelID = TunnelID;
|
||||||
|
mIdx = Idx;
|
||||||
|
//指定接收服务器数据事件
|
||||||
|
OnReceiveData += GetDataCallBack;
|
||||||
|
//断开连接
|
||||||
|
OnClose += OnConnectClose;
|
||||||
|
OnConnected += NetworkConnected;
|
||||||
|
//网络库调试信息输出事件,用于打印网络内容
|
||||||
|
OnLogOut += NetworkDeBugLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BandEvent(
|
||||||
|
OnBackwardLogOutHandler _OnBackwardLogOut,
|
||||||
|
OnBackwardConnectHandler _OnConnect,
|
||||||
|
OnBackwardDisconnectHandler _OnDisconnect,
|
||||||
|
OnBackwardDataCallBackHandler _OnDataCallBack
|
||||||
|
)
|
||||||
|
{
|
||||||
|
OnBackwardLogOut += _OnBackwardLogOut;
|
||||||
|
OnBackwardConnect += _OnConnect;
|
||||||
|
OnBackwardDisconnect += _OnDisconnect;
|
||||||
|
OnBackwardDataCallBack += _OnDataCallBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NetworkConnected(bool IsConnect)
|
||||||
|
{
|
||||||
|
NetworkDeBugLog($"NetworkConnected:{IsConnect}");
|
||||||
|
if (IsConnect)
|
||||||
|
{
|
||||||
|
OnBackwardConnect?.Invoke(mUID, mTunnelID, mIdx, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//连接失败
|
||||||
|
NetworkDeBugLog("连接失败!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NetworkDeBugLog(string str)
|
||||||
|
{
|
||||||
|
OnBackwardLogOut?.Invoke(1 ,"NetCoreDebug >> " + str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接受包回调
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="CMDID">协议ID</param>
|
||||||
|
/// <param name="ERRCODE">错误编号</param>
|
||||||
|
/// <param name="data">业务数据</param>
|
||||||
|
public void GetDataCallBack(byte[] data)
|
||||||
|
{
|
||||||
|
//NetworkDeBugLog("收到消息 数据长度=>" + data.Length);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//记录接收数据长度
|
||||||
|
mReciveAllLenght += data.Length;
|
||||||
|
//抛出网络数据
|
||||||
|
OnBackwardDataCallBack?.Invoke(mUID, mTunnelID, mIdx, data);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
NetworkDeBugLog("逻辑处理错误:" + ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭连接
|
||||||
|
/// </summary>
|
||||||
|
void OnConnectClose()
|
||||||
|
{
|
||||||
|
NetworkDeBugLog("OnConnectClose");
|
||||||
|
OnBackwardDisconnect?.Invoke(mUID, mTunnelID,mIdx,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Release()
|
||||||
|
{
|
||||||
|
OnBackwardLogOut -= OnBackwardLogOut;
|
||||||
|
OnBackwardConnect -= OnBackwardConnect;
|
||||||
|
OnBackwardDisconnect -= OnBackwardDisconnect;
|
||||||
|
OnBackwardDataCallBack -= OnBackwardDataCallBack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
94
NoSugarNet.Adapter/DataHelper/CompressAdapter.cs
Normal file
94
NoSugarNet.Adapter/DataHelper/CompressAdapter.cs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
namespace NoSugarNet.Adapter.DataHelper
|
||||||
|
{
|
||||||
|
public enum E_CompressAdapter
|
||||||
|
{
|
||||||
|
//不压缩
|
||||||
|
None = 0,
|
||||||
|
//GIPZ
|
||||||
|
GZIP_Plan1 = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩适配器
|
||||||
|
/// </summary>
|
||||||
|
public class CompressAdapter
|
||||||
|
{
|
||||||
|
IDataCompress mIDataCompress;
|
||||||
|
public CompressAdapter(E_CompressAdapter type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
//不压缩
|
||||||
|
case E_CompressAdapter.None:
|
||||||
|
mIDataCompress = new NoCompress();
|
||||||
|
break;
|
||||||
|
//GZIP Plan1
|
||||||
|
case E_CompressAdapter.GZIP_Plan1:
|
||||||
|
mIDataCompress = new GZipCompress();
|
||||||
|
break;
|
||||||
|
//TODO 其他压缩对比
|
||||||
|
//……
|
||||||
|
default:
|
||||||
|
mIDataCompress = new NoCompress();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Compress(byte[] data)
|
||||||
|
{
|
||||||
|
return mIDataCompress.Compress(data);
|
||||||
|
}
|
||||||
|
public byte[] Decompress(byte[] data)
|
||||||
|
{
|
||||||
|
return mIDataCompress.Decompress(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface IDataCompress
|
||||||
|
{
|
||||||
|
byte[] Compress(byte[] data);
|
||||||
|
byte[] Decompress(byte[] data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NoCompress : IDataCompress
|
||||||
|
{
|
||||||
|
public byte[] Compress(byte[] data)
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
public byte[] Decompress(byte[] data)
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GZipCompress : IDataCompress
|
||||||
|
{
|
||||||
|
public byte[] Compress(byte[] data)
|
||||||
|
{
|
||||||
|
using (var compressedStream = new MemoryStream())
|
||||||
|
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
|
||||||
|
{
|
||||||
|
zipStream.Write(data, 0, data.Length);
|
||||||
|
zipStream.Close();
|
||||||
|
return compressedStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Decompress(byte[] data)
|
||||||
|
{
|
||||||
|
using (var compressedStream = new MemoryStream(data))
|
||||||
|
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
|
||||||
|
using (var resultStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
zipStream.CopyTo(resultStream);
|
||||||
|
return resultStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
342
NoSugarNet.Adapter/ForwardLocalListener.cs
Normal file
342
NoSugarNet.Adapter/ForwardLocalListener.cs
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
using HaoYueNet.ServerNetwork;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace NoSugarNet.Adapter
|
||||||
|
{
|
||||||
|
public class ForwardLocalListener : TcpSaeaServer_SourceMode
|
||||||
|
{
|
||||||
|
public byte mTunnelID;
|
||||||
|
public long mReciveAllLenght;
|
||||||
|
public long mSendAllLenght;
|
||||||
|
public long currSeed;
|
||||||
|
static long Seed;
|
||||||
|
|
||||||
|
public enum AdptLogLevel
|
||||||
|
{
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void OnLogOutHandler(int LogLevel,string Msg);
|
||||||
|
public delegate void OnClientLocalConnectHandler(byte tunnelId, byte _Idx);
|
||||||
|
public delegate void OnClientLocalDisconnectHandler(byte tunnelId, byte _Idx);
|
||||||
|
public delegate void OnClientTunnelDataCallBackHandler(byte tunnelId, byte Idx, byte[] data);
|
||||||
|
|
||||||
|
public event OnLogOutHandler OnForwardLogOut;
|
||||||
|
public event OnClientLocalConnectHandler OnClientLocalConnect;
|
||||||
|
public event OnClientLocalDisconnectHandler OnClientLocalDisconnect;
|
||||||
|
public event OnClientTunnelDataCallBackHandler OnClientTunnelDataCallBack;
|
||||||
|
|
||||||
|
public ForwardLocalListener(int numConnections, int receiveBufferSize, byte TunnelID)
|
||||||
|
: base(numConnections, receiveBufferSize)
|
||||||
|
{
|
||||||
|
OnClientNumberChange += ClientNumberChange;
|
||||||
|
OnReceive += ReceiveData;
|
||||||
|
OnDisconnected += OnDisconnect;
|
||||||
|
OnNetLog += OnShowNetLog;
|
||||||
|
|
||||||
|
mTunnelID = TunnelID;
|
||||||
|
|
||||||
|
currSeed = Seed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public event OnLogOutHandler OnForwardLogOut2;
|
||||||
|
|
||||||
|
public void BandEvent(
|
||||||
|
OnLogOutHandler _OnLogOut,
|
||||||
|
OnClientLocalConnectHandler _OnClientLocalConnect,
|
||||||
|
OnClientLocalDisconnectHandler _OnClientLocalDisconnect,
|
||||||
|
OnClientTunnelDataCallBackHandler _ClientTunnelDataCall
|
||||||
|
)
|
||||||
|
{
|
||||||
|
OnForwardLogOut += _OnLogOut;
|
||||||
|
OnClientLocalConnect += _OnClientLocalConnect;
|
||||||
|
OnClientLocalDisconnect += _OnClientLocalDisconnect;
|
||||||
|
OnClientTunnelDataCallBack += _ClientTunnelDataCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartListener(uint port)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
Start(new IPEndPoint(IPAddress.Any.Address, (int)port));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClientNumberChange(int num, AsyncUserToken token)
|
||||||
|
{
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Info, "Client数发生变化");
|
||||||
|
//增加连接数stsc
|
||||||
|
if (num > 0)
|
||||||
|
{
|
||||||
|
int Idx = AddDictSocket(token.Socket);
|
||||||
|
if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInf))
|
||||||
|
{
|
||||||
|
OnClientLocalConnect?.Invoke(mTunnelID, (byte)Idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过下标发送
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Idx"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
public void SendSocketByIdx(int Idx, byte[] data)
|
||||||
|
{
|
||||||
|
if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
|
{
|
||||||
|
mSendAllLenght += data.Length;
|
||||||
|
SendToSocket(_localClientInfo._socket, data);
|
||||||
|
}
|
||||||
|
//TODO连接前缓存数据
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接受包回调
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="CMDID">协议ID</param>
|
||||||
|
/// <param name="ERRCODE">错误编号</param>
|
||||||
|
/// <param name="data">业务数据</param>
|
||||||
|
private void ReceiveData(AsyncUserToken token, byte[] data)
|
||||||
|
{
|
||||||
|
DataCallBack(token.Socket, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DataCallBack(Socket sk, byte[] data)
|
||||||
|
{
|
||||||
|
//AppNoSugarNet.log.Info("收到消息 数据长度=>" + data.Length);
|
||||||
|
//记录接受长度
|
||||||
|
mReciveAllLenght += data.Length;
|
||||||
|
if (!GetSocketIdxBySocket(sk, out int Idx))
|
||||||
|
return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//抛出网络数据
|
||||||
|
OnClientTunnelDataCallBack?.Invoke(mTunnelID, (byte)Idx, data);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Error,"逻辑处理错误:" + ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseConnectByIdx(byte Idx)
|
||||||
|
{
|
||||||
|
if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
|
{
|
||||||
|
//把未发送消息队列回收了
|
||||||
|
while (_localClientInfo.msgQueue.Count > 0)
|
||||||
|
{
|
||||||
|
IdxWithMsg msg = _localClientInfo.msgQueue.Dequeue();
|
||||||
|
LocalMsgQueuePool._localMsgPool.Enqueue(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
_localClientInfo._socket.Shutdown(SocketShutdown.Both);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 断开连接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sk"></param>
|
||||||
|
public void OnDisconnect(AsyncUserToken token)
|
||||||
|
{
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Info,"断开连接");
|
||||||
|
|
||||||
|
if (!GetSocketIdxBySocket(token.Socket, out int Idx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
OnClientLocalDisconnect?.Invoke(mTunnelID, (byte)Idx);
|
||||||
|
RemoveDictSocket(token.Socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnShowNetLog(string msg)
|
||||||
|
{
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Info, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 一个轻量级无用户连接管理
|
||||||
|
Dictionary<nint, int> DictSocketHandle2Idx = new Dictionary<nint, int>();
|
||||||
|
Dictionary<int, LocalClientInfo> DictIdx2LocalClientInfo = new Dictionary<int, LocalClientInfo>();
|
||||||
|
int mSeedIdx = 0;
|
||||||
|
List<int> FreeIdxs = new List<int>();
|
||||||
|
public class LocalClientInfo
|
||||||
|
{
|
||||||
|
public Socket _socket;
|
||||||
|
public bool bRemoteConnect;
|
||||||
|
public bool bLocalConnect => _socket.Connected;
|
||||||
|
public Queue<IdxWithMsg> msgQueue = new Queue<IdxWithMsg>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<int, LocalClientInfo> GetDictIdx2LocalClientInfo()
|
||||||
|
{
|
||||||
|
return DictIdx2LocalClientInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetNextIdx()
|
||||||
|
{
|
||||||
|
if (FreeIdxs.Count > 0)
|
||||||
|
{
|
||||||
|
int Idx = FreeIdxs[0];
|
||||||
|
FreeIdxs.RemoveAt(0);
|
||||||
|
return Idx;
|
||||||
|
}
|
||||||
|
return mSeedIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetFree()
|
||||||
|
{
|
||||||
|
FreeIdxs.Clear();
|
||||||
|
mSeedIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 追加Socket返回下标
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="socket"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int AddDictSocket(Socket socket)
|
||||||
|
{
|
||||||
|
if (socket == null)
|
||||||
|
return -1;
|
||||||
|
lock (DictSocketHandle2Idx)
|
||||||
|
{
|
||||||
|
int Idx = GetNextIdx();
|
||||||
|
DictSocketHandle2Idx[socket.Handle] = Idx;
|
||||||
|
DictIdx2LocalClientInfo[Idx] = new LocalClientInfo() { _socket = socket,bRemoteConnect = false};
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Debug, $"AddDictSocket mTunnelID->{mTunnelID} Idx->{Idx} socket.Handle{socket.Handle}");
|
||||||
|
return Idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveDictSocket(Socket socket)
|
||||||
|
{
|
||||||
|
if (socket == null)
|
||||||
|
return;
|
||||||
|
lock (DictSocketHandle2Idx)
|
||||||
|
{
|
||||||
|
if (!DictSocketHandle2Idx.ContainsKey(socket.Handle))
|
||||||
|
return;
|
||||||
|
int Idx = DictSocketHandle2Idx[socket.Handle];
|
||||||
|
FreeIdxs.Add(Idx);
|
||||||
|
if (DictIdx2LocalClientInfo.ContainsKey(Idx))
|
||||||
|
DictIdx2LocalClientInfo.Remove(Idx);
|
||||||
|
DictSocketHandle2Idx.Remove(socket.Handle);
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Debug, $"RemoveDictSocket mTunnelID->{mTunnelID} Idx->{Idx} socket.Handle{socket.Handle}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetSocketByIdx(int Idx, out LocalClientInfo _localClientInfo)
|
||||||
|
{
|
||||||
|
if (!DictIdx2LocalClientInfo.ContainsKey(Idx))
|
||||||
|
{
|
||||||
|
_localClientInfo = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_localClientInfo = DictIdx2LocalClientInfo[Idx];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetSocketIdxBySocket(Socket _socket, out int Idx)
|
||||||
|
{
|
||||||
|
if (_socket == null)
|
||||||
|
{
|
||||||
|
Idx = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DictSocketHandle2Idx.ContainsKey(_socket.Handle))
|
||||||
|
{
|
||||||
|
Idx = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Idx = DictSocketHandle2Idx[_socket.Handle];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckRemoteConnect(int Idx)
|
||||||
|
{
|
||||||
|
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
|
return false;
|
||||||
|
return _localClientInfo.bRemoteConnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRemoteConnectd(int Idx,bool bConnected)
|
||||||
|
{
|
||||||
|
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
|
return;
|
||||||
|
if (bConnected)
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Info,"远端本地连接已连接!!!!");
|
||||||
|
else
|
||||||
|
OnForwardLogOut?.Invoke((int)AdptLogLevel.Info, "远端本地连接已断开连接!!!!");
|
||||||
|
_localClientInfo.bRemoteConnect = bConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopAllLocalClient()
|
||||||
|
{
|
||||||
|
lock (DictIdx2LocalClientInfo)
|
||||||
|
{
|
||||||
|
int[] Idxs = DictIdx2LocalClientInfo.Keys.ToArray();
|
||||||
|
for (int i = 0; i < Idxs.Length; i++)
|
||||||
|
{
|
||||||
|
CloseConnectByIdx((byte)Idxs[i]);
|
||||||
|
}
|
||||||
|
DictIdx2LocalClientInfo.Clear();
|
||||||
|
DictSocketHandle2Idx.Clear();
|
||||||
|
ResetFree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopWithClear()
|
||||||
|
{
|
||||||
|
base.Stop();
|
||||||
|
//清理事件
|
||||||
|
OnForwardLogOut -= OnForwardLogOut;
|
||||||
|
OnClientLocalConnect -= OnClientLocalConnect;
|
||||||
|
OnClientLocalDisconnect -= OnClientLocalDisconnect;
|
||||||
|
OnClientTunnelDataCallBack -= OnClientTunnelDataCallBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region 缓存
|
||||||
|
public void EnqueueIdxWithMsg(byte Idx, byte[] data)
|
||||||
|
{
|
||||||
|
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
|
return;
|
||||||
|
|
||||||
|
IdxWithMsg Msg = LocalMsgQueuePool._localMsgPool.Dequeue();
|
||||||
|
Msg.Idx = Idx;
|
||||||
|
Msg.data = data;
|
||||||
|
_localClientInfo.msgQueue.Enqueue(Msg);
|
||||||
|
}
|
||||||
|
public bool GetDictMsgQueue(byte Idx,out List<IdxWithMsg> MsgList)
|
||||||
|
{
|
||||||
|
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo) || _localClientInfo.msgQueue.Count < 1)
|
||||||
|
{
|
||||||
|
MsgList = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgList = new List<IdxWithMsg>();
|
||||||
|
lock (_localClientInfo.msgQueue)
|
||||||
|
{
|
||||||
|
while (_localClientInfo.msgQueue.Count > 0)
|
||||||
|
{
|
||||||
|
IdxWithMsg msg = _localClientInfo.msgQueue.Dequeue();
|
||||||
|
MsgList.Add(msg);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
55
NoSugarNet.Adapter/LocalMsgQueuePool.cs
Normal file
55
NoSugarNet.Adapter/LocalMsgQueuePool.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
namespace NoSugarNet.Adapter
|
||||||
|
{
|
||||||
|
public class IdxWithMsg
|
||||||
|
{
|
||||||
|
public byte Idx;
|
||||||
|
public byte[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LocalMsgQueuePool
|
||||||
|
{
|
||||||
|
public static LocalMsgQueuePool _localMsgPool = new LocalMsgQueuePool(1000);
|
||||||
|
|
||||||
|
Queue<IdxWithMsg> msg_pool;
|
||||||
|
|
||||||
|
public LocalMsgQueuePool(int capacity)
|
||||||
|
{
|
||||||
|
msg_pool = new Queue<IdxWithMsg>(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向 Queue 的末尾添加一个对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
public void Enqueue(IdxWithMsg item)
|
||||||
|
{
|
||||||
|
lock (msg_pool)
|
||||||
|
{
|
||||||
|
item.Idx = 0;
|
||||||
|
item.data = null;
|
||||||
|
msg_pool.Enqueue(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//移除并返回在 Queue 的开头的对象。
|
||||||
|
public IdxWithMsg Dequeue()
|
||||||
|
{
|
||||||
|
lock (msg_pool)
|
||||||
|
{
|
||||||
|
if(msg_pool.Count > 0)
|
||||||
|
return msg_pool.Dequeue();
|
||||||
|
return new IdxWithMsg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get { return msg_pool.Count; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
msg_pool.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
NoSugarNet.Adapter/NoSugarNet.Adapter.csproj
Normal file
18
NoSugarNet.Adapter/NoSugarNet.Adapter.csproj
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="HaoYueNet.ClientNetwork">
|
||||||
|
<HintPath>..\Lib\HaoYueNet.ClientNetwork.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="HaoYueNet.ServerNetwork">
|
||||||
|
<HintPath>..\Lib\HaoYueNet.ServerNetwork.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -19,8 +19,5 @@
|
|||||||
<Reference Include="HaoYueNet.ServerNetwork.Standard2">
|
<Reference Include="HaoYueNet.ServerNetwork.Standard2">
|
||||||
<HintPath>..\Lib\NetLib_Standard2\HaoYueNet.ServerNetwork.Standard2.dll</HintPath>
|
<HintPath>..\Lib\NetLib_Standard2\HaoYueNet.ServerNetwork.Standard2.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NoSugarNet.DataHelper">
|
|
||||||
<HintPath>..\Lib\NetLib_Standard2\NoSugarNet.DataHelper.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,6 +1,8 @@
|
|||||||
using AxibugProtobuf;
|
using AxibugProtobuf;
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using HaoYueNet.ServerNetwork;
|
using HaoYueNet.ServerNetwork;
|
||||||
|
using NoSugarNet.Adapter;
|
||||||
|
using NoSugarNet.Adapter.DataHelper;
|
||||||
using NoSugarNet.ClientCore;
|
using NoSugarNet.ClientCore;
|
||||||
using NoSugarNet.ClientCore.Common;
|
using NoSugarNet.ClientCore.Common;
|
||||||
using NoSugarNet.ClientCore.Network;
|
using NoSugarNet.ClientCore.Network;
|
||||||
@ -12,10 +14,10 @@ namespace ServerCore.Manager
|
|||||||
public class AppLocalClient
|
public class AppLocalClient
|
||||||
{
|
{
|
||||||
Dictionary<byte, Protobuf_Cfgs_Single> mDictTunnelID2Cfg = new Dictionary<byte, Protobuf_Cfgs_Single>();
|
Dictionary<byte, Protobuf_Cfgs_Single> mDictTunnelID2Cfg = new Dictionary<byte, Protobuf_Cfgs_Single>();
|
||||||
Dictionary<byte, LocalListener> mDictTunnelID2Listeners = new Dictionary<byte, LocalListener>();
|
Dictionary<byte, ForwardLocalListener> mDictTunnelID2Listeners = new Dictionary<byte, ForwardLocalListener>();
|
||||||
CompressAdapter mCompressAdapter;
|
NoSugarNet.Adapter.DataHelper.CompressAdapter mCompressAdapter;
|
||||||
E_CompressAdapter compressAdapterType;
|
NoSugarNet.Adapter.DataHelper.E_CompressAdapter compressAdapterType;
|
||||||
public LocalMsgQueuePool _localMsgPool = new LocalMsgQueuePool(1000);
|
//public LocalMsgQueuePool _localMsgPool = new LocalMsgQueuePool(1000);
|
||||||
|
|
||||||
public long tReciveAllLenght { get; private set; }
|
public long tReciveAllLenght { get; private set; }
|
||||||
public long tSendAllLenght { get; private set; }
|
public long tSendAllLenght { get; private set; }
|
||||||
@ -74,13 +76,15 @@ namespace ServerCore.Manager
|
|||||||
{
|
{
|
||||||
AppNoSugarNet.log.Info("初始化压缩适配器" + compressAdapterType);
|
AppNoSugarNet.log.Info("初始化压缩适配器" + compressAdapterType);
|
||||||
//初始化压缩适配器,代表压缩类型
|
//初始化压缩适配器,代表压缩类型
|
||||||
mCompressAdapter = new CompressAdapter(compressAdapterType);
|
mCompressAdapter = new NoSugarNet.Adapter.DataHelper.CompressAdapter(compressAdapterType);
|
||||||
foreach (var cfg in mDictTunnelID2Cfg)
|
foreach (var cfg in mDictTunnelID2Cfg)
|
||||||
{
|
{
|
||||||
LocalListener listener = new LocalListener(256, 1024, cfg.Key);
|
ForwardLocalListener listener = new ForwardLocalListener(256, 1024, cfg.Key);
|
||||||
AppNoSugarNet.log.Info($"开始监听配置 Tunnel:{cfg.Key},Port:{cfg.Value.Port}");
|
AppNoSugarNet.log.Info($"开始监听配置 Tunnel:{cfg.Key},Port:{cfg.Value.Port}");
|
||||||
listener.Init();
|
listener.BandEvent(AppNoSugarNet.log.Log, OnClientLocalConnect, OnClientLocalDisconnect, OnClientTunnelDataCallBack);
|
||||||
listener.Start(new IPEndPoint(IPAddress.Any.Address, (int)cfg.Value.Port));
|
listener.StartListener((uint)cfg.Value.Port);
|
||||||
|
//listener.Init();
|
||||||
|
//listener.Start(new IPEndPoint(IPAddress.Any.Address, (int)cfg.Value.Port));
|
||||||
//listener.Init((int)cfg.Value.Port);
|
//listener.Init((int)cfg.Value.Port);
|
||||||
AddLocalListener(listener);
|
AddLocalListener(listener);
|
||||||
}
|
}
|
||||||
@ -93,7 +97,7 @@ namespace ServerCore.Manager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tunnelId"></param>
|
/// <param name="tunnelId"></param>
|
||||||
/// <param name="serverClient"></param>
|
/// <param name="serverClient"></param>
|
||||||
void AddLocalListener(LocalListener _listener)
|
void AddLocalListener(ForwardLocalListener _listener)
|
||||||
{
|
{
|
||||||
lock (mDictTunnelID2Listeners)
|
lock (mDictTunnelID2Listeners)
|
||||||
{
|
{
|
||||||
@ -105,7 +109,7 @@ namespace ServerCore.Manager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tunnelId"></param>
|
/// <param name="tunnelId"></param>
|
||||||
/// <param name="serverClient"></param>
|
/// <param name="serverClient"></param>
|
||||||
void RemoveLocalListener(LocalListener _listener)
|
void RemoveLocalListener(ForwardLocalListener _listener)
|
||||||
{
|
{
|
||||||
lock (mDictTunnelID2Listeners)
|
lock (mDictTunnelID2Listeners)
|
||||||
{
|
{
|
||||||
@ -115,7 +119,7 @@ namespace ServerCore.Manager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool GetLocalListener(byte tunnelId,out LocalListener _listener)
|
bool GetLocalListener(byte tunnelId,out ForwardLocalListener _listener)
|
||||||
{
|
{
|
||||||
_listener = null;
|
_listener = null;
|
||||||
if (!mDictTunnelID2Listeners.ContainsKey(tunnelId))
|
if (!mDictTunnelID2Listeners.ContainsKey(tunnelId))
|
||||||
@ -131,9 +135,9 @@ namespace ServerCore.Manager
|
|||||||
byte[] keys = mDictTunnelID2Listeners.Keys.ToArray();
|
byte[] keys = mDictTunnelID2Listeners.Keys.ToArray();
|
||||||
for (int i = 0; i < keys.Length; i++)
|
for (int i = 0; i < keys.Length; i++)
|
||||||
{
|
{
|
||||||
LocalListener _listener = mDictTunnelID2Listeners[keys[i]];
|
ForwardLocalListener _listener = mDictTunnelID2Listeners[keys[i]];
|
||||||
_listener.StopAllLocalClient();
|
_listener.StopAllLocalClient();
|
||||||
_listener.Stop();
|
_listener.StopWithClear();
|
||||||
//_listener.Stop();
|
//_listener.Stop();
|
||||||
RemoveLocalListener(_listener);
|
RemoveLocalListener(_listener);
|
||||||
}
|
}
|
||||||
@ -153,7 +157,7 @@ namespace ServerCore.Manager
|
|||||||
Protobuf_Cfgs_Single cfg = msg.Cfgs[i];
|
Protobuf_Cfgs_Single cfg = msg.Cfgs[i];
|
||||||
mDictTunnelID2Cfg[(byte)cfg.TunnelID] = cfg;
|
mDictTunnelID2Cfg[(byte)cfg.TunnelID] = cfg;
|
||||||
}
|
}
|
||||||
compressAdapterType = (E_CompressAdapter)msg.CompressAdapterType;
|
compressAdapterType = (NoSugarNet.Adapter.DataHelper.E_CompressAdapter)msg.CompressAdapterType;
|
||||||
InitListenerMode();
|
InitListenerMode();
|
||||||
}
|
}
|
||||||
public void Recive_TunnelS2CConnect(byte[] reqData)
|
public void Recive_TunnelS2CConnect(byte[] reqData)
|
||||||
@ -229,7 +233,7 @@ namespace ServerCore.Manager
|
|||||||
public void OnServerLocalConnect(byte tunnelId,byte Idx)
|
public void OnServerLocalConnect(byte tunnelId,byte Idx)
|
||||||
{
|
{
|
||||||
AppNoSugarNet.log.Debug($"OnServerLocalConnect {tunnelId},{Idx}");
|
AppNoSugarNet.log.Debug($"OnServerLocalConnect {tunnelId},{Idx}");
|
||||||
if (!GetLocalListener(tunnelId, out LocalListener _listener))
|
if (!GetLocalListener(tunnelId, out ForwardLocalListener _listener))
|
||||||
return;
|
return;
|
||||||
//维护状态
|
//维护状态
|
||||||
_listener.SetRemoteConnectd(Idx, true);
|
_listener.SetRemoteConnectd(Idx, true);
|
||||||
@ -241,7 +245,7 @@ namespace ServerCore.Manager
|
|||||||
//投递给服务端,来自客户端本地的连接数据
|
//投递给服务端,来自客户端本地的连接数据
|
||||||
AppNoSugarNet.networkHelper.SendToServer((int)CommandID.CmdTunnelC2SData, msg.data);
|
AppNoSugarNet.networkHelper.SendToServer((int)CommandID.CmdTunnelC2SData, msg.data);
|
||||||
//发送后回收
|
//发送后回收
|
||||||
AppNoSugarNet.local._localMsgPool.Enqueue(msg);
|
LocalMsgQueuePool._localMsgPool.Enqueue(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,7 +257,7 @@ namespace ServerCore.Manager
|
|||||||
public void OnServerLocalDisconnect(byte tunnelId, byte Idx)
|
public void OnServerLocalDisconnect(byte tunnelId, byte Idx)
|
||||||
{
|
{
|
||||||
AppNoSugarNet.log.Debug($"OnServerLocalDisconnect {tunnelId},{Idx}");
|
AppNoSugarNet.log.Debug($"OnServerLocalDisconnect {tunnelId},{Idx}");
|
||||||
if (!GetLocalListener(tunnelId, out LocalListener _listener))
|
if (!GetLocalListener(tunnelId, out ForwardLocalListener _listener))
|
||||||
return;
|
return;
|
||||||
_listener.SetRemoteConnectd(Idx,false);
|
_listener.SetRemoteConnectd(Idx,false);
|
||||||
_listener.CloseConnectByIdx(Idx);
|
_listener.CloseConnectByIdx(Idx);
|
||||||
@ -270,7 +274,7 @@ namespace ServerCore.Manager
|
|||||||
public void OnServerLocalDataCallBack(byte tunnelId,byte Idx, byte[] data)
|
public void OnServerLocalDataCallBack(byte tunnelId,byte Idx, byte[] data)
|
||||||
{
|
{
|
||||||
//AppNoSugarNet.log.Info($"OnServerLocalDataCallBack {tunnelId},{Idx},Data长度:{data.Length}");
|
//AppNoSugarNet.log.Info($"OnServerLocalDataCallBack {tunnelId},{Idx},Data长度:{data.Length}");
|
||||||
if (!GetLocalListener(tunnelId, out LocalListener _listener))
|
if (!GetLocalListener(tunnelId, out ForwardLocalListener _listener))
|
||||||
return;
|
return;
|
||||||
//记录压缩前数据长度
|
//记录压缩前数据长度
|
||||||
tReciveAllLenght += data.Length;
|
tReciveAllLenght += data.Length;
|
||||||
@ -329,7 +333,7 @@ namespace ServerCore.Manager
|
|||||||
HunterNetCoreData = ByteString.CopyFrom(data)
|
HunterNetCoreData = ByteString.CopyFrom(data)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!GetLocalListener(tunnelId, out LocalListener _listener))
|
if (!GetLocalListener(tunnelId, out ForwardLocalListener _listener))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//远程未连接,添加到缓存
|
//远程未连接,添加到缓存
|
||||||
|
@ -14,6 +14,7 @@ namespace NoSugarNet.ClientCore.Manager
|
|||||||
|
|
||||||
public void Login()
|
public void Login()
|
||||||
{
|
{
|
||||||
|
AppNoSugarNet.log.Debug("-->Login");
|
||||||
if(string.IsNullOrEmpty(LastLoginGuid))
|
if(string.IsNullOrEmpty(LastLoginGuid))
|
||||||
LastLoginGuid = Guid.NewGuid().ToString();
|
LastLoginGuid = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
@ -1,295 +1,295 @@
|
|||||||
using HaoYueNet.ServerNetwork;
|
//using HaoYueNet.ServerNetwork;
|
||||||
using System.Net.Sockets;
|
//using System.Net.Sockets;
|
||||||
|
|
||||||
namespace NoSugarNet.ClientCore
|
//namespace NoSugarNet.ClientCore
|
||||||
{
|
//{
|
||||||
public class LocalListener : TcpSaeaServer_SourceMode
|
// public class LocalListener : TcpSaeaServer_SourceMode
|
||||||
{
|
// {
|
||||||
public byte mTunnelID;
|
// public byte mTunnelID;
|
||||||
public long mReciveAllLenght;
|
// public long mReciveAllLenght;
|
||||||
public long mSendAllLenght;
|
// public long mSendAllLenght;
|
||||||
public long currSeed;
|
// public long currSeed;
|
||||||
static long Seed;
|
// static long Seed;
|
||||||
|
|
||||||
public LocalListener(int numConnections, int receiveBufferSize, byte TunnelID)
|
// public LocalListener(int numConnections, int receiveBufferSize, byte TunnelID)
|
||||||
: base(numConnections, receiveBufferSize)
|
// : base(numConnections, receiveBufferSize)
|
||||||
{
|
// {
|
||||||
OnClientNumberChange += ClientNumberChange;
|
// OnClientNumberChange += ClientNumberChange;
|
||||||
OnReceive += ReceiveData;
|
// OnReceive += ReceiveData;
|
||||||
OnDisconnected += OnDisconnect;
|
// OnDisconnected += OnDisconnect;
|
||||||
OnNetLog += OnShowNetLog;
|
// OnNetLog += OnShowNetLog;
|
||||||
|
|
||||||
mTunnelID = TunnelID;
|
// mTunnelID = TunnelID;
|
||||||
|
|
||||||
currSeed = Seed++;
|
// currSeed = Seed++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void ClientNumberChange(int num, AsyncUserToken token)
|
// private void ClientNumberChange(int num, AsyncUserToken token)
|
||||||
{
|
// {
|
||||||
AppNoSugarNet.log.Info("Client数发生变化");
|
// AppNoSugarNet.log.Info("Client数发生变化");
|
||||||
//增加连接数stsc
|
// //增加连接数stsc
|
||||||
if (num > 0)
|
// if (num > 0)
|
||||||
{
|
// {
|
||||||
int Idx = AddDictSocket(token.Socket);
|
// int Idx = AddDictSocket(token.Socket);
|
||||||
if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInf))
|
// if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInf))
|
||||||
{
|
// {
|
||||||
AppNoSugarNet.local.OnClientLocalConnect(mTunnelID, (byte)Idx);
|
// AppNoSugarNet.local.OnClientLocalConnect(mTunnelID, (byte)Idx);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 通过下标发送
|
// /// 通过下标发送
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="Idx"></param>
|
// /// <param name="Idx"></param>
|
||||||
/// <param name="data"></param>
|
// /// <param name="data"></param>
|
||||||
public void SendSocketByIdx(int Idx, byte[] data)
|
// public void SendSocketByIdx(int Idx, byte[] data)
|
||||||
{
|
// {
|
||||||
if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
// if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
{
|
// {
|
||||||
mSendAllLenght += data.Length;
|
// mSendAllLenght += data.Length;
|
||||||
SendToSocket(_localClientInfo._socket, data);
|
// SendToSocket(_localClientInfo._socket, data);
|
||||||
}
|
// }
|
||||||
//TODO连接前缓存数据
|
// //TODO连接前缓存数据
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 接受包回调
|
// /// 接受包回调
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="CMDID">协议ID</param>
|
// /// <param name="CMDID">协议ID</param>
|
||||||
/// <param name="ERRCODE">错误编号</param>
|
// /// <param name="ERRCODE">错误编号</param>
|
||||||
/// <param name="data">业务数据</param>
|
// /// <param name="data">业务数据</param>
|
||||||
private void ReceiveData(AsyncUserToken token, byte[] data)
|
// private void ReceiveData(AsyncUserToken token, byte[] data)
|
||||||
{
|
// {
|
||||||
DataCallBack(token.Socket, data);
|
// DataCallBack(token.Socket, data);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void DataCallBack(Socket sk, byte[] data)
|
// public void DataCallBack(Socket sk, byte[] data)
|
||||||
{
|
// {
|
||||||
//AppNoSugarNet.log.Info("收到消息 数据长度=>" + data.Length);
|
// //AppNoSugarNet.log.Info("收到消息 数据长度=>" + data.Length);
|
||||||
//记录接受长度
|
// //记录接受长度
|
||||||
mReciveAllLenght += data.Length;
|
// mReciveAllLenght += data.Length;
|
||||||
if (!GetSocketIdxBySocket(sk, out int Idx))
|
// if (!GetSocketIdxBySocket(sk, out int Idx))
|
||||||
return;
|
// return;
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
//抛出网络数据
|
// //抛出网络数据
|
||||||
AppNoSugarNet.local.OnClientTunnelDataCallBack(mTunnelID, (byte)Idx, data);
|
// AppNoSugarNet.local.OnClientTunnelDataCallBack(mTunnelID, (byte)Idx, data);
|
||||||
}
|
// }
|
||||||
catch (Exception ex)
|
// catch (Exception ex)
|
||||||
{
|
// {
|
||||||
AppNoSugarNet.log.Info("逻辑处理错误:" + ex.ToString());
|
// AppNoSugarNet.log.Info("逻辑处理错误:" + ex.ToString());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void CloseConnectByIdx(byte Idx)
|
// public void CloseConnectByIdx(byte Idx)
|
||||||
{
|
// {
|
||||||
if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
// if (GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
{
|
// {
|
||||||
//把未发送消息队列回收了
|
// //把未发送消息队列回收了
|
||||||
while (_localClientInfo.msgQueue.Count > 0)
|
// while (_localClientInfo.msgQueue.Count > 0)
|
||||||
{
|
// {
|
||||||
IdxWithMsg msg = _localClientInfo.msgQueue.Dequeue();
|
// IdxWithMsg msg = _localClientInfo.msgQueue.Dequeue();
|
||||||
AppNoSugarNet.local._localMsgPool.Enqueue(msg);
|
// AppNoSugarNet.local._localMsgPool.Enqueue(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
_localClientInfo._socket.Shutdown(SocketShutdown.Both);
|
// _localClientInfo._socket.Shutdown(SocketShutdown.Both);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 断开连接
|
// /// 断开连接
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="sk"></param>
|
// /// <param name="sk"></param>
|
||||||
public void OnDisconnect(AsyncUserToken token)
|
// public void OnDisconnect(AsyncUserToken token)
|
||||||
{
|
// {
|
||||||
AppNoSugarNet.log.Info("断开连接");
|
// AppNoSugarNet.log.Info("断开连接");
|
||||||
|
|
||||||
if (!GetSocketIdxBySocket(token.Socket, out int Idx))
|
// if (!GetSocketIdxBySocket(token.Socket, out int Idx))
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
AppNoSugarNet.local.OnClientLocalDisconnect(mTunnelID, (byte)Idx);
|
// AppNoSugarNet.local.OnClientLocalDisconnect(mTunnelID, (byte)Idx);
|
||||||
RemoveDictSocket(token.Socket);
|
// RemoveDictSocket(token.Socket);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void OnShowNetLog(string msg)
|
// public void OnShowNetLog(string msg)
|
||||||
{
|
// {
|
||||||
AppNoSugarNet.log.Info(msg);
|
// AppNoSugarNet.log.Info(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
#region 一个轻量级无用户连接管理
|
// #region 一个轻量级无用户连接管理
|
||||||
Dictionary<nint, int> DictSocketHandle2Idx = new Dictionary<nint, int>();
|
// Dictionary<nint, int> DictSocketHandle2Idx = new Dictionary<nint, int>();
|
||||||
Dictionary<int, LocalClientInfo> DictIdx2LocalClientInfo = new Dictionary<int, LocalClientInfo>();
|
// Dictionary<int, LocalClientInfo> DictIdx2LocalClientInfo = new Dictionary<int, LocalClientInfo>();
|
||||||
int mSeedIdx = 0;
|
// int mSeedIdx = 0;
|
||||||
List<int> FreeIdxs = new List<int>();
|
// List<int> FreeIdxs = new List<int>();
|
||||||
public class LocalClientInfo
|
// public class LocalClientInfo
|
||||||
{
|
// {
|
||||||
public Socket _socket;
|
// public Socket _socket;
|
||||||
public bool bRemoteConnect;
|
// public bool bRemoteConnect;
|
||||||
public bool bLocalConnect => _socket.Connected;
|
// public bool bLocalConnect => _socket.Connected;
|
||||||
public Queue<IdxWithMsg> msgQueue = new Queue<IdxWithMsg>();
|
// public Queue<IdxWithMsg> msgQueue = new Queue<IdxWithMsg>();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Dictionary<int, LocalClientInfo> GetDictIdx2LocalClientInfo()
|
// public Dictionary<int, LocalClientInfo> GetDictIdx2LocalClientInfo()
|
||||||
{
|
// {
|
||||||
return DictIdx2LocalClientInfo;
|
// return DictIdx2LocalClientInfo;
|
||||||
}
|
// }
|
||||||
|
|
||||||
int GetNextIdx()
|
// int GetNextIdx()
|
||||||
{
|
// {
|
||||||
if (FreeIdxs.Count > 0)
|
// if (FreeIdxs.Count > 0)
|
||||||
{
|
// {
|
||||||
int Idx = FreeIdxs[0];
|
// int Idx = FreeIdxs[0];
|
||||||
FreeIdxs.RemoveAt(0);
|
// FreeIdxs.RemoveAt(0);
|
||||||
return Idx;
|
// return Idx;
|
||||||
}
|
// }
|
||||||
return mSeedIdx++;
|
// return mSeedIdx++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void ResetFree()
|
// void ResetFree()
|
||||||
{
|
// {
|
||||||
FreeIdxs.Clear();
|
// FreeIdxs.Clear();
|
||||||
mSeedIdx = 0;
|
// mSeedIdx = 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 追加Socket返回下标
|
// /// 追加Socket返回下标
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="socket"></param>
|
// /// <param name="socket"></param>
|
||||||
/// <returns></returns>
|
// /// <returns></returns>
|
||||||
public int AddDictSocket(Socket socket)
|
// public int AddDictSocket(Socket socket)
|
||||||
{
|
// {
|
||||||
if (socket == null)
|
// if (socket == null)
|
||||||
return -1;
|
// return -1;
|
||||||
lock (DictSocketHandle2Idx)
|
// lock (DictSocketHandle2Idx)
|
||||||
{
|
// {
|
||||||
int Idx = GetNextIdx();
|
// int Idx = GetNextIdx();
|
||||||
DictSocketHandle2Idx[socket.Handle] = Idx;
|
// DictSocketHandle2Idx[socket.Handle] = Idx;
|
||||||
DictIdx2LocalClientInfo[Idx] = new LocalClientInfo() { _socket = socket,bRemoteConnect = false};
|
// DictIdx2LocalClientInfo[Idx] = new LocalClientInfo() { _socket = socket,bRemoteConnect = false};
|
||||||
AppNoSugarNet.log.Debug($"AddDictSocket mTunnelID->{mTunnelID} Idx->{Idx} socket.Handle{socket.Handle}");
|
// AppNoSugarNet.log.Debug($"AddDictSocket mTunnelID->{mTunnelID} Idx->{Idx} socket.Handle{socket.Handle}");
|
||||||
return Idx;
|
// return Idx;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void RemoveDictSocket(Socket socket)
|
// public void RemoveDictSocket(Socket socket)
|
||||||
{
|
// {
|
||||||
if (socket == null)
|
// if (socket == null)
|
||||||
return;
|
// return;
|
||||||
lock (DictSocketHandle2Idx)
|
// lock (DictSocketHandle2Idx)
|
||||||
{
|
// {
|
||||||
if (!DictSocketHandle2Idx.ContainsKey(socket.Handle))
|
// if (!DictSocketHandle2Idx.ContainsKey(socket.Handle))
|
||||||
return;
|
// return;
|
||||||
int Idx = DictSocketHandle2Idx[socket.Handle];
|
// int Idx = DictSocketHandle2Idx[socket.Handle];
|
||||||
FreeIdxs.Add(Idx);
|
// FreeIdxs.Add(Idx);
|
||||||
if (DictIdx2LocalClientInfo.ContainsKey(Idx))
|
// if (DictIdx2LocalClientInfo.ContainsKey(Idx))
|
||||||
DictIdx2LocalClientInfo.Remove(Idx);
|
// DictIdx2LocalClientInfo.Remove(Idx);
|
||||||
DictSocketHandle2Idx.Remove(socket.Handle);
|
// DictSocketHandle2Idx.Remove(socket.Handle);
|
||||||
AppNoSugarNet.log.Debug($"RemoveDictSocket mTunnelID->{mTunnelID} Idx->{Idx} socket.Handle{socket.Handle}");
|
// AppNoSugarNet.log.Debug($"RemoveDictSocket mTunnelID->{mTunnelID} Idx->{Idx} socket.Handle{socket.Handle}");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
bool GetSocketByIdx(int Idx, out LocalClientInfo _localClientInfo)
|
// bool GetSocketByIdx(int Idx, out LocalClientInfo _localClientInfo)
|
||||||
{
|
// {
|
||||||
if (!DictIdx2LocalClientInfo.ContainsKey(Idx))
|
// if (!DictIdx2LocalClientInfo.ContainsKey(Idx))
|
||||||
{
|
// {
|
||||||
_localClientInfo = null;
|
// _localClientInfo = null;
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
_localClientInfo = DictIdx2LocalClientInfo[Idx];
|
// _localClientInfo = DictIdx2LocalClientInfo[Idx];
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public bool GetSocketIdxBySocket(Socket _socket, out int Idx)
|
// public bool GetSocketIdxBySocket(Socket _socket, out int Idx)
|
||||||
{
|
// {
|
||||||
if (_socket == null)
|
// if (_socket == null)
|
||||||
{
|
// {
|
||||||
Idx = -1;
|
// Idx = -1;
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!DictSocketHandle2Idx.ContainsKey(_socket.Handle))
|
// if (!DictSocketHandle2Idx.ContainsKey(_socket.Handle))
|
||||||
{
|
// {
|
||||||
Idx = -1;
|
// Idx = -1;
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
Idx = DictSocketHandle2Idx[_socket.Handle];
|
// Idx = DictSocketHandle2Idx[_socket.Handle];
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public bool CheckRemoteConnect(int Idx)
|
// public bool CheckRemoteConnect(int Idx)
|
||||||
{
|
// {
|
||||||
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
// if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
return false;
|
// return false;
|
||||||
return _localClientInfo.bRemoteConnect;
|
// return _localClientInfo.bRemoteConnect;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void SetRemoteConnectd(int Idx,bool bConnected)
|
// public void SetRemoteConnectd(int Idx,bool bConnected)
|
||||||
{
|
// {
|
||||||
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
// if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
return;
|
// return;
|
||||||
if (bConnected)
|
// if (bConnected)
|
||||||
AppNoSugarNet.log.Info("远端本地连接已连接!!!!");
|
// AppNoSugarNet.log.Info("远端本地连接已连接!!!!");
|
||||||
else
|
// else
|
||||||
AppNoSugarNet.log.Info("远端本地连接已断开连接!!!!");
|
// AppNoSugarNet.log.Info("远端本地连接已断开连接!!!!");
|
||||||
_localClientInfo.bRemoteConnect = bConnected;
|
// _localClientInfo.bRemoteConnect = bConnected;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void StopAllLocalClient()
|
// public void StopAllLocalClient()
|
||||||
{
|
// {
|
||||||
lock (DictIdx2LocalClientInfo)
|
// lock (DictIdx2LocalClientInfo)
|
||||||
{
|
// {
|
||||||
int[] Idxs = DictIdx2LocalClientInfo.Keys.ToArray();
|
// int[] Idxs = DictIdx2LocalClientInfo.Keys.ToArray();
|
||||||
for (int i = 0; i < Idxs.Length; i++)
|
// for (int i = 0; i < Idxs.Length; i++)
|
||||||
{
|
// {
|
||||||
CloseConnectByIdx((byte)Idxs[i]);
|
// CloseConnectByIdx((byte)Idxs[i]);
|
||||||
}
|
// }
|
||||||
DictIdx2LocalClientInfo.Clear();
|
// DictIdx2LocalClientInfo.Clear();
|
||||||
DictSocketHandle2Idx.Clear();
|
// DictSocketHandle2Idx.Clear();
|
||||||
ResetFree();
|
// ResetFree();
|
||||||
|
|
||||||
//清理事件
|
// //清理事件
|
||||||
OnClientNumberChange -= ClientNumberChange;
|
// OnClientNumberChange -= ClientNumberChange;
|
||||||
OnReceive -= ReceiveData;
|
// OnReceive -= ReceiveData;
|
||||||
OnDisconnected -= OnDisconnect;
|
// OnDisconnected -= OnDisconnect;
|
||||||
OnNetLog -= OnShowNetLog;
|
// OnNetLog -= OnShowNetLog;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#endregion
|
// #endregion
|
||||||
|
|
||||||
|
|
||||||
#region 缓存
|
// #region 缓存
|
||||||
public void EnqueueIdxWithMsg(byte Idx, byte[] data)
|
// public void EnqueueIdxWithMsg(byte Idx, byte[] data)
|
||||||
{
|
// {
|
||||||
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
// if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo))
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
IdxWithMsg Msg = AppNoSugarNet.local._localMsgPool.Dequeue();
|
// IdxWithMsg Msg = AppNoSugarNet.local._localMsgPool.Dequeue();
|
||||||
Msg.Idx = Idx;
|
// Msg.Idx = Idx;
|
||||||
Msg.data = data;
|
// Msg.data = data;
|
||||||
_localClientInfo.msgQueue.Enqueue(Msg);
|
// _localClientInfo.msgQueue.Enqueue(Msg);
|
||||||
}
|
// }
|
||||||
public bool GetDictMsgQueue(byte Idx,out List<IdxWithMsg> MsgList)
|
// public bool GetDictMsgQueue(byte Idx,out List<IdxWithMsg> MsgList)
|
||||||
{
|
// {
|
||||||
if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo) || _localClientInfo.msgQueue.Count < 1)
|
// if (!GetSocketByIdx(Idx, out LocalClientInfo _localClientInfo) || _localClientInfo.msgQueue.Count < 1)
|
||||||
{
|
// {
|
||||||
MsgList = null;
|
// MsgList = null;
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
MsgList = new List<IdxWithMsg>();
|
// MsgList = new List<IdxWithMsg>();
|
||||||
lock (_localClientInfo.msgQueue)
|
// lock (_localClientInfo.msgQueue)
|
||||||
{
|
// {
|
||||||
while (_localClientInfo.msgQueue.Count > 0)
|
// while (_localClientInfo.msgQueue.Count > 0)
|
||||||
{
|
// {
|
||||||
IdxWithMsg msg = _localClientInfo.msgQueue.Dequeue();
|
// IdxWithMsg msg = _localClientInfo.msgQueue.Dequeue();
|
||||||
MsgList.Add(msg);
|
// MsgList.Add(msg);
|
||||||
}
|
// }
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
#endregion
|
// #endregion
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -1,53 +1,53 @@
|
|||||||
namespace NoSugarNet.ClientCore
|
//namespace NoSugarNet.ClientCore
|
||||||
{
|
//{
|
||||||
public class IdxWithMsg
|
// public class IdxWithMsg
|
||||||
{
|
// {
|
||||||
public byte Idx;
|
// public byte Idx;
|
||||||
public byte[] data;
|
// public byte[] data;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public class LocalMsgQueuePool
|
// public class LocalMsgQueuePool
|
||||||
{
|
// {
|
||||||
Queue<IdxWithMsg> msg_pool;
|
// Queue<IdxWithMsg> msg_pool;
|
||||||
|
|
||||||
public LocalMsgQueuePool(int capacity)
|
// public LocalMsgQueuePool(int capacity)
|
||||||
{
|
// {
|
||||||
msg_pool = new Queue<IdxWithMsg>(capacity);
|
// msg_pool = new Queue<IdxWithMsg>(capacity);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 向 Queue 的末尾添加一个对象。
|
// /// 向 Queue 的末尾添加一个对象。
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="item"></param>
|
// /// <param name="item"></param>
|
||||||
public void Enqueue(IdxWithMsg item)
|
// public void Enqueue(IdxWithMsg item)
|
||||||
{
|
// {
|
||||||
lock (msg_pool)
|
// lock (msg_pool)
|
||||||
{
|
// {
|
||||||
item.Idx = 0;
|
// item.Idx = 0;
|
||||||
item.data = null;
|
// item.data = null;
|
||||||
msg_pool.Enqueue(item);
|
// msg_pool.Enqueue(item);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
//移除并返回在 Queue 的开头的对象。
|
// //移除并返回在 Queue 的开头的对象。
|
||||||
public IdxWithMsg Dequeue()
|
// public IdxWithMsg Dequeue()
|
||||||
{
|
// {
|
||||||
lock (msg_pool)
|
// lock (msg_pool)
|
||||||
{
|
// {
|
||||||
if(msg_pool.Count > 0)
|
// if(msg_pool.Count > 0)
|
||||||
return msg_pool.Dequeue();
|
// return msg_pool.Dequeue();
|
||||||
return new IdxWithMsg();
|
// return new IdxWithMsg();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public int Count
|
// public int Count
|
||||||
{
|
// {
|
||||||
get { return msg_pool.Count; }
|
// get { return msg_pool.Count; }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void Clear()
|
// public void Clear()
|
||||||
{
|
// {
|
||||||
msg_pool.Clear();
|
// msg_pool.Clear();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -44,5 +44,10 @@
|
|||||||
{
|
{
|
||||||
OnLog?.Invoke((int)logtype, str);
|
OnLog?.Invoke((int)logtype, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Log(int logtype, string str)
|
||||||
|
{
|
||||||
|
OnLog?.Invoke(logtype, str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,10 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\NoSugarNet.Adapter\NoSugarNet.Adapter.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Google.Protobuf">
|
<Reference Include="Google.Protobuf">
|
||||||
<HintPath>..\Lib\Google.Protobuf.dll</HintPath>
|
<HintPath>..\Lib\Google.Protobuf.dll</HintPath>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using NoSugarNet.DataHelper;
|
using NoSugarNet.Adapter.DataHelper;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NoSugarNet.ServerCore.Common
|
namespace NoSugarNet.ServerCore.Common
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using AxibugProtobuf;
|
using AxibugProtobuf;
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using NoSugarNet.ClientCore.Network;
|
using NoSugarNet.Adapter;
|
||||||
using NoSugarNet.DataHelper;
|
using NoSugarNet.Adapter.DataHelper;
|
||||||
using NoSugarNet.ServerCore.Common;
|
using NoSugarNet.ServerCore.Common;
|
||||||
using ServerCore.Common;
|
using ServerCore.Common;
|
||||||
using ServerCore.NetWork;
|
using ServerCore.NetWork;
|
||||||
@ -11,7 +11,7 @@ namespace ServerCore.Manager
|
|||||||
{
|
{
|
||||||
public class LocalClientManager
|
public class LocalClientManager
|
||||||
{
|
{
|
||||||
Dictionary<long, ServerLocalClient> mDictCommKey2ServerLocalClients = new Dictionary<long, ServerLocalClient>();
|
Dictionary<long, BackwardLocalClient> mDictCommKey2ServerLocalClients = new Dictionary<long, BackwardLocalClient>();
|
||||||
CompressAdapter mCompressAdapter;
|
CompressAdapter mCompressAdapter;
|
||||||
|
|
||||||
public long tReciveAllLenght { get; private set; }
|
public long tReciveAllLenght { get; private set; }
|
||||||
@ -58,7 +58,7 @@ namespace ServerCore.Manager
|
|||||||
/// <param name="uid"></param>
|
/// <param name="uid"></param>
|
||||||
/// <param name="tunnelId"></param>
|
/// <param name="tunnelId"></param>
|
||||||
/// <param name="serverClient"></param>
|
/// <param name="serverClient"></param>
|
||||||
void AddServerLocalClient(long uid, byte tunnelId,byte Idx, ServerLocalClient serverClient)
|
void AddServerLocalClient(long uid, byte tunnelId,byte Idx, BackwardLocalClient serverClient)
|
||||||
{
|
{
|
||||||
long CommKey = GetCommKey(uid, tunnelId, Idx);
|
long CommKey = GetCommKey(uid, tunnelId, Idx);
|
||||||
lock (mDictCommKey2ServerLocalClients)
|
lock (mDictCommKey2ServerLocalClients)
|
||||||
@ -79,11 +79,12 @@ namespace ServerCore.Manager
|
|||||||
|
|
||||||
if (!mDictCommKey2ServerLocalClients.ContainsKey(CommKey))
|
if (!mDictCommKey2ServerLocalClients.ContainsKey(CommKey))
|
||||||
return;
|
return;
|
||||||
|
mDictCommKey2ServerLocalClients[CommKey].Release();
|
||||||
mDictCommKey2ServerLocalClients.Remove(CommKey);
|
mDictCommKey2ServerLocalClients.Remove(CommKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetServerLocalClient(long uid, byte tunnelId, byte Idx,out ServerLocalClient serverLocalClient)
|
bool GetServerLocalClient(long uid, byte tunnelId, byte Idx,out BackwardLocalClient serverLocalClient)
|
||||||
{
|
{
|
||||||
serverLocalClient = null;
|
serverLocalClient = null;
|
||||||
|
|
||||||
@ -99,7 +100,7 @@ namespace ServerCore.Manager
|
|||||||
void CloseServerLocalClient(long uid, byte tunnelId, byte Idx)
|
void CloseServerLocalClient(long uid, byte tunnelId, byte Idx)
|
||||||
{
|
{
|
||||||
//隧道ID定位投递服务端本地连接
|
//隧道ID定位投递服务端本地连接
|
||||||
if (!GetServerLocalClient(uid, tunnelId, Idx, out ServerLocalClient _serverLocalClient))
|
if (!GetServerLocalClient(uid, tunnelId, Idx, out BackwardLocalClient _serverLocalClient))
|
||||||
return;
|
return;
|
||||||
_serverLocalClient.CloseConntect();
|
_serverLocalClient.CloseConntect();
|
||||||
RemoveServerLocalClient(uid, tunnelId, Idx);
|
RemoveServerLocalClient(uid, tunnelId, Idx);
|
||||||
@ -139,7 +140,7 @@ namespace ServerCore.Manager
|
|||||||
long CommID = TempRemoveCommIDList[i];
|
long CommID = TempRemoveCommIDList[i];
|
||||||
if (!mDictCommKey2ServerLocalClients.ContainsKey(CommID))
|
if (!mDictCommKey2ServerLocalClients.ContainsKey(CommID))
|
||||||
continue;
|
continue;
|
||||||
ServerLocalClient _serverLoackClient = mDictCommKey2ServerLocalClients[CommID];
|
BackwardLocalClient _serverLoackClient = mDictCommKey2ServerLocalClients[CommID];
|
||||||
_serverLoackClient.CloseConntect();
|
_serverLoackClient.CloseConntect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,7 +190,8 @@ namespace ServerCore.Manager
|
|||||||
{
|
{
|
||||||
//服务器本地局域网连接指定端口
|
//服务器本地局域网连接指定端口
|
||||||
TunnelClientData tunnelDataCfg = Config.cfgs[tunnelId];
|
TunnelClientData tunnelDataCfg = Config.cfgs[tunnelId];
|
||||||
ServerLocalClient serverLocalClient = new ServerLocalClient(uid, tunnelId, (byte)Idx);
|
BackwardLocalClient serverLocalClient = new BackwardLocalClient(uid, tunnelId, (byte)Idx);
|
||||||
|
serverLocalClient.BandEvent(ServerManager.g_Log.Log, OnServerLocalConnect, OnServerLocalDisconnect, OnServerLocalDataCallBack);
|
||||||
//连接成功
|
//连接成功
|
||||||
if (!serverLocalClient.Init(tunnelDataCfg.ServerLocalTargetIP, tunnelDataCfg.ServerLocalTargetPort))
|
if (!serverLocalClient.Init(tunnelDataCfg.ServerLocalTargetIP, tunnelDataCfg.ServerLocalTargetPort))
|
||||||
{
|
{
|
||||||
@ -219,7 +221,7 @@ namespace ServerCore.Manager
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//隧道ID定位投递服务端本地连接
|
//隧道ID定位投递服务端本地连接
|
||||||
if (!GetServerLocalClient(uid, tunnelId, Idx, out ServerLocalClient serverLocalClient))
|
if (!GetServerLocalClient(uid, tunnelId, Idx, out BackwardLocalClient serverLocalClient))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//断开服务端本地客户端连接
|
//断开服务端本地客户端连接
|
||||||
@ -230,7 +232,7 @@ namespace ServerCore.Manager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uid"></param>
|
/// <param name="uid"></param>
|
||||||
/// <param name="tunnelId"></param>
|
/// <param name="tunnelId"></param>
|
||||||
public void OnServerLocalConnect(long uid, byte tunnelId, byte Idx, ServerLocalClient serverLocalClient)
|
public void OnServerLocalConnect(long uid, byte tunnelId, byte Idx, BackwardLocalClient serverLocalClient)
|
||||||
{
|
{
|
||||||
ServerManager.g_Log.Debug($"OnServerLocalConnect {uid},{tunnelId},{Idx}");
|
ServerManager.g_Log.Debug($"OnServerLocalConnect {uid},{tunnelId},{Idx}");
|
||||||
if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
||||||
@ -253,7 +255,7 @@ namespace ServerCore.Manager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uid"></param>
|
/// <param name="uid"></param>
|
||||||
/// <param name="tunnelId"></param>
|
/// <param name="tunnelId"></param>
|
||||||
public void OnServerLocalDisconnect(long uid, byte tunnelId, byte Idx, ServerLocalClient serverLocalClient)
|
public void OnServerLocalDisconnect(long uid, byte tunnelId, byte Idx, BackwardLocalClient serverLocalClient)
|
||||||
{
|
{
|
||||||
ServerManager.g_Log.Debug($"OnServerLocalDisconnect {uid},{tunnelId},{Idx}");
|
ServerManager.g_Log.Debug($"OnServerLocalDisconnect {uid},{tunnelId},{Idx}");
|
||||||
if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
||||||
@ -282,7 +284,7 @@ namespace ServerCore.Manager
|
|||||||
{
|
{
|
||||||
//ServerManager.g_Log.Debug($"OnClientTunnelDataCallBack {uid},{tunnelId},{Idx}");
|
//ServerManager.g_Log.Debug($"OnClientTunnelDataCallBack {uid},{tunnelId},{Idx}");
|
||||||
//隧道ID定位投递服务端本地连接
|
//隧道ID定位投递服务端本地连接
|
||||||
if (!GetServerLocalClient(uid, tunnelId, Idx, out ServerLocalClient serverLocalClient))
|
if (!GetServerLocalClient(uid, tunnelId, Idx, out BackwardLocalClient serverLocalClient))
|
||||||
return;
|
return;
|
||||||
//记录数据长度
|
//记录数据长度
|
||||||
tReciveAllLenght += data.Length;
|
tReciveAllLenght += data.Length;
|
||||||
@ -331,7 +333,6 @@ namespace ServerCore.Manager
|
|||||||
}
|
}
|
||||||
SendDataToRemote(uid, tunnelId, Idx, data);
|
SendDataToRemote(uid, tunnelId, Idx, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendDataToRemote(long uid, byte tunnelId, byte Idx, byte[] data)
|
void SendDataToRemote(long uid, byte tunnelId, byte Idx, byte[] data)
|
||||||
{
|
{
|
||||||
if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
if (!ServerManager.g_ClientMgr.GetClientByUID(uid, out ClientInfo client))
|
||||||
|
@ -16,5 +16,10 @@
|
|||||||
{
|
{
|
||||||
Console.WriteLine(str);
|
Console.WriteLine(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Log(int logtype, string str)
|
||||||
|
{
|
||||||
|
Console.WriteLine(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,85 +1,85 @@
|
|||||||
using HaoYueNet.ClientNetwork.OtherMode;
|
//using HaoYueNet.ClientNetwork.OtherMode;
|
||||||
using ServerCore.Manager;
|
//using ServerCore.Manager;
|
||||||
using System;
|
//using System;
|
||||||
using System.Security.Cryptography;
|
//using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace NoSugarNet.ClientCore.Network
|
//namespace NoSugarNet.ClientCore.Network
|
||||||
{
|
//{
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 继承网络库,以支持网络功能
|
// /// 继承网络库,以支持网络功能
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public class ServerLocalClient : NetworkHelperCore_SourceMode
|
// public class ServerLocalClient : NetworkHelperCore_SourceMode
|
||||||
{
|
// {
|
||||||
public long mUID;
|
// public long mUID;
|
||||||
public byte mTunnelID;
|
// public byte mTunnelID;
|
||||||
public byte mIdx;
|
// public byte mIdx;
|
||||||
public long mReciveAllLenght;
|
// public long mReciveAllLenght;
|
||||||
public long mSendAllLenght;
|
// public long mSendAllLenght;
|
||||||
public ServerLocalClient(long UID,byte TunnelID, byte Idx)
|
// public ServerLocalClient(long UID,byte TunnelID, byte Idx)
|
||||||
{
|
// {
|
||||||
mUID = UID;
|
// mUID = UID;
|
||||||
mTunnelID = TunnelID;
|
// mTunnelID = TunnelID;
|
||||||
mIdx = Idx;
|
// mIdx = Idx;
|
||||||
//指定接收服务器数据事件
|
// //指定接收服务器数据事件
|
||||||
OnReceiveData += GetDataCallBack;
|
// OnReceiveData += GetDataCallBack;
|
||||||
//断开连接
|
// //断开连接
|
||||||
OnClose += OnConnectClose;
|
// OnClose += OnConnectClose;
|
||||||
OnConnected += NetworkConnected;
|
// OnConnected += NetworkConnected;
|
||||||
//网络库调试信息输出事件,用于打印网络内容
|
// //网络库调试信息输出事件,用于打印网络内容
|
||||||
OnLogOut += NetworkDeBugLog;
|
// OnLogOut += NetworkDeBugLog;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void NetworkConnected(bool IsConnect)
|
// public void NetworkConnected(bool IsConnect)
|
||||||
{
|
// {
|
||||||
NetworkDeBugLog($"NetworkConnected:{IsConnect}");
|
// NetworkDeBugLog($"NetworkConnected:{IsConnect}");
|
||||||
if (IsConnect)
|
// if (IsConnect)
|
||||||
{
|
// {
|
||||||
ServerManager.g_Local.OnServerLocalConnect(mUID, mTunnelID, mIdx, this);
|
// ServerManager.g_Local.OnServerLocalConnect(mUID, mTunnelID, mIdx, this);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
//连接失败
|
// //连接失败
|
||||||
NetworkDeBugLog("连接失败!");
|
// NetworkDeBugLog("连接失败!");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void NetworkDeBugLog(string str)
|
// public void NetworkDeBugLog(string str)
|
||||||
{
|
// {
|
||||||
//用于Unity内的输出
|
// //用于Unity内的输出
|
||||||
//Debug.Log("NetCoreDebug >> "+str);
|
// //Debug.Log("NetCoreDebug >> "+str);
|
||||||
Console.WriteLine("NetCoreDebug >> " + str);
|
// Console.WriteLine("NetCoreDebug >> " + str);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 接受包回调
|
// /// 接受包回调
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="CMDID">协议ID</param>
|
// /// <param name="CMDID">协议ID</param>
|
||||||
/// <param name="ERRCODE">错误编号</param>
|
// /// <param name="ERRCODE">错误编号</param>
|
||||||
/// <param name="data">业务数据</param>
|
// /// <param name="data">业务数据</param>
|
||||||
public void GetDataCallBack(byte[] data)
|
// public void GetDataCallBack(byte[] data)
|
||||||
{
|
// {
|
||||||
//NetworkDeBugLog("收到消息 数据长度=>" + data.Length);
|
// //NetworkDeBugLog("收到消息 数据长度=>" + data.Length);
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
//记录接收数据长度
|
// //记录接收数据长度
|
||||||
mReciveAllLenght += data.Length;
|
// mReciveAllLenght += data.Length;
|
||||||
//抛出网络数据
|
// //抛出网络数据
|
||||||
ServerManager.g_Local.OnServerLocalDataCallBack(mUID, mTunnelID, mIdx, data);
|
// ServerManager.g_Local.OnServerLocalDataCallBack(mUID, mTunnelID, mIdx, data);
|
||||||
}
|
// }
|
||||||
catch (Exception ex)
|
// catch (Exception ex)
|
||||||
{
|
// {
|
||||||
NetworkDeBugLog("逻辑处理错误:" + ex.ToString());
|
// NetworkDeBugLog("逻辑处理错误:" + ex.ToString());
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 关闭连接
|
// /// 关闭连接
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public void OnConnectClose()
|
// public void OnConnectClose()
|
||||||
{
|
// {
|
||||||
NetworkDeBugLog("OnConnectClose");
|
// NetworkDeBugLog("OnConnectClose");
|
||||||
ServerManager.g_Local.OnServerLocalDisconnect(mUID, mTunnelID,mIdx,this);
|
// ServerManager.g_Local.OnServerLocalDisconnect(mUID, mTunnelID,mIdx,this);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using NoSugarNet.DataHelper;
|
using NoSugarNet.Adapter.DataHelper;
|
||||||
using NoSugarNet.ServerCore;
|
using NoSugarNet.ServerCore;
|
||||||
using NoSugarNet.ServerCore.Common;
|
using NoSugarNet.ServerCore.Common;
|
||||||
using ServerCore.NetWork;
|
using ServerCore.NetWork;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\NoSugarNet.DataHelper\NoSugarNet.DataHelper.csproj" />
|
<ProjectReference Include="..\NoSugarNet.Adapter\NoSugarNet.Adapter.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
-->
|
-->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<History>True|2024-04-23T09:13:21.9642037Z;True|2024-04-23T17:02:04.8137007+08:00;True|2024-01-25T17:08:35.3176032+08:00;</History>
|
<History>True|2024-06-25T05:12:56.0566334Z;True|2024-04-23T17:13:21.9642037+08:00;True|2024-04-23T17:02:04.8137007+08:00;True|2024-01-25T17:08:35.3176032+08:00;</History>
|
||||||
<LastFailureDetails />
|
<LastFailureDetails />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
@ -20,8 +20,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSugarNet.ClientCli", "Sam
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSugarNet.ServerCli", "Sample\NoSugarNet.ServerCli\NoSugarNet.ServerCli.csproj", "{65220036-9A81-49FA-A5BC-DA06783D2E52}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSugarNet.ServerCli", "Sample\NoSugarNet.ServerCli\NoSugarNet.ServerCli.csproj", "{65220036-9A81-49FA-A5BC-DA06783D2E52}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSugarNet.DataHelper", "NoSugarNet.DataHelper\NoSugarNet.DataHelper.csproj", "{3C41B685-B46B-4057-826B-C8C6F395BFA8}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NetLib_Standard2", "NetLib_Standard2", "{4A660CAE-CD92-411C-9D8E-7CB677DB3C74}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NetLib_Standard2", "NetLib_Standard2", "{4A660CAE-CD92-411C-9D8E-7CB677DB3C74}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
Lib\NetLib_Standard2\HaoYueNet.ClientNetworkNet.Standard2.dll = Lib\NetLib_Standard2\HaoYueNet.ClientNetworkNet.Standard2.dll
|
Lib\NetLib_Standard2\HaoYueNet.ClientNetworkNet.Standard2.dll = Lib\NetLib_Standard2\HaoYueNet.ClientNetworkNet.Standard2.dll
|
||||||
@ -33,6 +31,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NetLib_Standard2", "NetLib_
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSugarNet.ClientCore.Standard2", "NoSugarNet.ClientCore.Standard2\NoSugarNet.ClientCore.Standard2.csproj", "{5DB2B608-6F99-430A-99AC-534410393955}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoSugarNet.ClientCore.Standard2", "NoSugarNet.ClientCore.Standard2\NoSugarNet.ClientCore.Standard2.csproj", "{5DB2B608-6F99-430A-99AC-534410393955}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSugarNet.Adapter", "NoSugarNet.Adapter\NoSugarNet.Adapter.csproj", "{961FA85B-B6A7-4F45-8239-9E91315253B4}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -55,14 +55,14 @@ Global
|
|||||||
{65220036-9A81-49FA-A5BC-DA06783D2E52}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{65220036-9A81-49FA-A5BC-DA06783D2E52}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{65220036-9A81-49FA-A5BC-DA06783D2E52}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{65220036-9A81-49FA-A5BC-DA06783D2E52}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{65220036-9A81-49FA-A5BC-DA06783D2E52}.Release|Any CPU.Build.0 = Release|Any CPU
|
{65220036-9A81-49FA-A5BC-DA06783D2E52}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3C41B685-B46B-4057-826B-C8C6F395BFA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3C41B685-B46B-4057-826B-C8C6F395BFA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3C41B685-B46B-4057-826B-C8C6F395BFA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3C41B685-B46B-4057-826B-C8C6F395BFA8}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{5DB2B608-6F99-430A-99AC-534410393955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{5DB2B608-6F99-430A-99AC-534410393955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{5DB2B608-6F99-430A-99AC-534410393955}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{5DB2B608-6F99-430A-99AC-534410393955}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{5DB2B608-6F99-430A-99AC-534410393955}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{5DB2B608-6F99-430A-99AC-534410393955}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{5DB2B608-6F99-430A-99AC-534410393955}.Release|Any CPU.Build.0 = Release|Any CPU
|
{5DB2B608-6F99-430A-99AC-534410393955}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{961FA85B-B6A7-4F45-8239-9E91315253B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{961FA85B-B6A7-4F45-8239-9E91315253B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{961FA85B-B6A7-4F45-8239-9E91315253B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{961FA85B-B6A7-4F45-8239-9E91315253B4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
-->
|
-->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<History>True|2024-06-18T03:37:53.3986849Z;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-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>
|
||||||
<LastFailureDetails />
|
<LastFailureDetails />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user