forked from sin365/NoSugarNet
归档
This commit is contained in:
parent
a5cc4b0521
commit
f154884419
33
NoSugarNet.ClientCore/App.cs
Normal file
33
NoSugarNet.ClientCore/App.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using NoSugarNet.ClientCore.Manager;
|
||||||
|
using NoSugarNet.ClientCore.Network;
|
||||||
|
using ServerCore.Manager;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore
|
||||||
|
{
|
||||||
|
public class App
|
||||||
|
{
|
||||||
|
public static string TokenStr;
|
||||||
|
public static long RID = -1;
|
||||||
|
public static string IP;
|
||||||
|
public static int Port;
|
||||||
|
public static LogManager log;
|
||||||
|
public static NetworkHelper networkHelper;
|
||||||
|
public static AppLogin login;
|
||||||
|
public static AppChat chat;
|
||||||
|
public static AppLocalClient local;
|
||||||
|
public static UserDataManager user;
|
||||||
|
|
||||||
|
public static void Init(string IP, int port)
|
||||||
|
{
|
||||||
|
log = new LogManager();
|
||||||
|
networkHelper = new NetworkHelper();
|
||||||
|
login = new AppLogin();
|
||||||
|
chat = new AppChat();
|
||||||
|
local = new AppLocalClient();
|
||||||
|
user = new UserDataManager();
|
||||||
|
networkHelper.Init(IP, port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
59
NoSugarNet.ClientCore/Common/CompressAdapter.cs
Normal file
59
NoSugarNet.ClientCore/Common/CompressAdapter.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore.Common
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩适配器
|
||||||
|
/// </summary>
|
||||||
|
public class CompressAdapter
|
||||||
|
{
|
||||||
|
IDataCompress mIDataCompress;
|
||||||
|
public CompressAdapter(ushort type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
//不压缩
|
||||||
|
case 0:
|
||||||
|
mIDataCompress = new NoCompress();
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public byte[] Compress(byte[] data);
|
||||||
|
public byte[] Decompress(byte[] data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NoCompress : IDataCompress
|
||||||
|
{
|
||||||
|
public byte[] Compress(byte[] data)
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
public byte[] Decompress(byte[] data)
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
NoSugarNet.ClientCore/Common/Helper.cs
Normal file
20
NoSugarNet.ClientCore/Common/Helper.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace NoSugarNet.ClientCore.Common
|
||||||
|
{
|
||||||
|
public static class Helper
|
||||||
|
{
|
||||||
|
public static long GetNowTimeStamp()
|
||||||
|
{
|
||||||
|
return GetTimeStamp(DateTime.Now);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取时间戳
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static long GetTimeStamp(DateTime dt)
|
||||||
|
{
|
||||||
|
TimeSpan ts = dt - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||||||
|
return Convert.ToInt64(ts.TotalSeconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
NoSugarNet.ClientCore/Common/ProtoBufHelper.cs
Normal file
20
NoSugarNet.ClientCore/Common/ProtoBufHelper.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using Google.Protobuf;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore.Common
|
||||||
|
{
|
||||||
|
public static class ProtoBufHelper
|
||||||
|
{
|
||||||
|
public static byte[] Serizlize(IMessage msg)
|
||||||
|
{
|
||||||
|
return msg.ToByteArray();
|
||||||
|
}
|
||||||
|
public static T DeSerizlize<T>(byte[] bytes)
|
||||||
|
{
|
||||||
|
var msgType = typeof(T);
|
||||||
|
object msg = Activator.CreateInstance(msgType);
|
||||||
|
((IMessage)msg).MergeFrom(bytes);
|
||||||
|
return (T)msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
NoSugarNet.ClientCore/Manager/AppChat.cs
Normal file
30
NoSugarNet.ClientCore/Manager/AppChat.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using AxibugProtobuf;
|
||||||
|
using NoSugarNet.ClientCore.Common;
|
||||||
|
using NoSugarNet.ClientCore.Event;
|
||||||
|
using NoSugarNet.ClientCore.Network;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore.Manager
|
||||||
|
{
|
||||||
|
public class AppChat
|
||||||
|
{
|
||||||
|
public AppChat()
|
||||||
|
{
|
||||||
|
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdChatmsg, RecvChatMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendChatMsg(string ChatMsg)
|
||||||
|
{
|
||||||
|
Protobuf_ChatMsg msg = new Protobuf_ChatMsg()
|
||||||
|
{
|
||||||
|
ChatMsg = ChatMsg,
|
||||||
|
};
|
||||||
|
App.networkHelper.SendToServer((int)CommandID.CmdChatmsg, ProtoBufHelper.Serizlize(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecvChatMsg(byte[] reqData)
|
||||||
|
{
|
||||||
|
Protobuf_ChatMsg_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_ChatMsg_RESP>(reqData);
|
||||||
|
EventSystem.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
225
NoSugarNet.ClientCore/Manager/AppLocalClient.cs
Normal file
225
NoSugarNet.ClientCore/Manager/AppLocalClient.cs
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
using AxibugProtobuf;
|
||||||
|
using NoSugarNet.ClientCore.Network;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using NoSugarNet.ClientCore.Common;
|
||||||
|
using NoSugarNet.ClientCore;
|
||||||
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
|
using NoSugarNet.ClientCore.Manager;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace ServerCore.Manager
|
||||||
|
{
|
||||||
|
public class AppLocalClient
|
||||||
|
{
|
||||||
|
|
||||||
|
Dictionary<byte, Protobuf_Cfgs_Single> mDictTunnelID2Cfg = new Dictionary<byte, Protobuf_Cfgs_Single>();
|
||||||
|
Dictionary<byte, LocalListener> mDictTunnelID2Listeners = new Dictionary<byte, LocalListener>();
|
||||||
|
CompressAdapter mCompressAdapter;
|
||||||
|
|
||||||
|
public AppLocalClient()
|
||||||
|
{
|
||||||
|
//初始化压缩适配器,暂时使用0,代表压缩类型
|
||||||
|
mCompressAdapter = new CompressAdapter(0);
|
||||||
|
//注册网络消息
|
||||||
|
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdCfgs, Recive_CmdCfgs);
|
||||||
|
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTunnelS2CConnect, Recive_TunnelS2CConnect);
|
||||||
|
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTunnelS2CDisconnect, Recive_TunnelS2CDisconnect);
|
||||||
|
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTunnelS2CData, Recive_TunnelS2CData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化连接,先获取到配置
|
||||||
|
/// </summary>
|
||||||
|
void InitListenerMode()
|
||||||
|
{
|
||||||
|
foreach (var cfg in mDictTunnelID2Cfg)
|
||||||
|
{
|
||||||
|
LocalListener listener = new LocalListener(1024, 1024, cfg.Key);
|
||||||
|
listener.Init();
|
||||||
|
listener.Start(new IPEndPoint(IPAddress.Any.Address, (int)cfg.Value.Port));
|
||||||
|
AddLocalListener(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 连接字典管理
|
||||||
|
/// <summary>
|
||||||
|
/// 追加监听者
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
/// <param name="serverClient"></param>
|
||||||
|
void AddLocalListener(LocalListener _listener)
|
||||||
|
{
|
||||||
|
lock (mDictTunnelID2Listeners)
|
||||||
|
{
|
||||||
|
mDictTunnelID2Listeners[_listener.mTunnelID] = _listener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除监听
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
/// <param name="serverClient"></param>
|
||||||
|
void RemoveLocalListener(LocalListener _listener)
|
||||||
|
{
|
||||||
|
lock (mDictTunnelID2Listeners)
|
||||||
|
{
|
||||||
|
if (mDictTunnelID2Listeners.ContainsKey(_listener.mTunnelID))
|
||||||
|
{
|
||||||
|
mDictTunnelID2Listeners[_listener.mTunnelID] = _listener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetLocalListener(byte tunnelId,out LocalListener _listener)
|
||||||
|
{
|
||||||
|
_listener = null;
|
||||||
|
if (!mDictTunnelID2Listeners.ContainsKey(tunnelId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_listener = mDictTunnelID2Listeners[tunnelId];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 解析服务端下行数据
|
||||||
|
public void Recive_CmdCfgs(byte[] reqData)
|
||||||
|
{
|
||||||
|
App.log.Debug("Recive_CmdCfgs");
|
||||||
|
Protobuf_Cfgs msg = ProtoBufHelper.DeSerizlize<Protobuf_Cfgs>(reqData);
|
||||||
|
|
||||||
|
for (int i = 0;msg.Cfgs.Count > 0;i++)
|
||||||
|
{
|
||||||
|
Protobuf_Cfgs_Single cfg = msg.Cfgs[i];
|
||||||
|
mDictTunnelID2Cfg[(byte)cfg.TunnelID] = cfg;
|
||||||
|
}
|
||||||
|
InitListenerMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Recive_TunnelS2CConnect(byte[] reqData)
|
||||||
|
{
|
||||||
|
App.log.Debug("Recive_TunnelS2CConnect");
|
||||||
|
Protobuf_S2C_Connect msg = ProtoBufHelper.DeSerizlize<Protobuf_S2C_Connect>(reqData);
|
||||||
|
OnServerLocalConnect((byte)msg.TunnelID,(byte)msg.Idx);
|
||||||
|
}
|
||||||
|
public void Recive_TunnelS2CDisconnect(byte[] reqData)
|
||||||
|
{
|
||||||
|
App.log.Debug("Recive_TunnelS2CDisconnect");
|
||||||
|
Protobuf_S2C_Disconnect msg = ProtoBufHelper.DeSerizlize<Protobuf_S2C_Disconnect>(reqData);
|
||||||
|
OnServerLocalDisconnect((byte)msg.TunnelID,(byte)msg.Idx);
|
||||||
|
}
|
||||||
|
public void Recive_TunnelS2CData(byte[] reqData)
|
||||||
|
{
|
||||||
|
App.log.Debug("Recive_TunnelS2CData");
|
||||||
|
Protobuf_S2C_DATA msg = ProtoBufHelper.DeSerizlize<Protobuf_S2C_DATA>(reqData);
|
||||||
|
OnServerLocalDataCallBack((byte)msg.TunnelID,(byte)msg.Idx, msg.HunterNetCoreData.ToArray());
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 两端本地端口连接事件通知
|
||||||
|
/// <summary>
|
||||||
|
/// 当客户端本地端口连接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
public void OnClientLocalConnect(byte tunnelId,byte _Idx)
|
||||||
|
{
|
||||||
|
if (!mDictTunnelID2Cfg.ContainsKey(tunnelId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
byte[] respData = ProtoBufHelper.Serizlize(new Protobuf_C2S_Connect()
|
||||||
|
{
|
||||||
|
TunnelID = tunnelId,
|
||||||
|
Idx = _Idx,
|
||||||
|
});
|
||||||
|
|
||||||
|
//告知给服务端,来自客户端本地的连接建立
|
||||||
|
App.networkHelper.SendToServer((int)CommandID.CmdTunnelC2SConnect, respData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当客户端本地端口连接断开
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
public void OnClientLocalDisconnect(byte tunnelId, byte _Idx)
|
||||||
|
{
|
||||||
|
//隧道ID定位投递服务端本地连接
|
||||||
|
if (!mDictTunnelID2Cfg.ContainsKey(tunnelId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
byte[] respData = ProtoBufHelper.Serizlize(new Protobuf_C2S_Disconnect()
|
||||||
|
{
|
||||||
|
TunnelID = tunnelId,
|
||||||
|
Idx= _Idx,
|
||||||
|
});
|
||||||
|
//告知给服务端,来自客户端本地的连接断开
|
||||||
|
App.networkHelper.SendToServer((int)CommandID.CmdTunnelC2SDisconnect, respData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当服务端本地端口连接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
public void OnServerLocalConnect(byte tunnelId,byte Idx)
|
||||||
|
{
|
||||||
|
if (!GetLocalListener(tunnelId, out LocalListener _listener))
|
||||||
|
return;
|
||||||
|
//TODO 维护本地状态
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当服务端本地端口连接断开
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
public void OnServerLocalDisconnect(byte tunnelId, byte Idx)
|
||||||
|
{
|
||||||
|
if (!GetLocalListener(tunnelId, out LocalListener _listener))
|
||||||
|
return;
|
||||||
|
_listener.CloseConnectByIdx(Idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 数据投递
|
||||||
|
/// <summary>
|
||||||
|
/// 来自服务端本地连接投递的Tunnel数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
public void OnServerLocalDataCallBack(byte tunnelId,byte Idx, byte[] data)
|
||||||
|
{
|
||||||
|
if (!GetLocalListener(tunnelId, out LocalListener _listener))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//解压
|
||||||
|
data = mCompressAdapter.Decompress(data);
|
||||||
|
_listener.SendSocketByIdx(Idx,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 来自客户端本地连接投递的Tunnel数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="tunnelId"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
public void OnClientTunnelDataCallBack(byte tunnelId,byte Idx, byte[] data)
|
||||||
|
{
|
||||||
|
//压缩
|
||||||
|
data = mCompressAdapter.Compress(data);
|
||||||
|
byte[] respData = ProtoBufHelper.Serizlize(new Protobuf_C2S_DATA()
|
||||||
|
{
|
||||||
|
TunnelID = tunnelId,
|
||||||
|
Idx = Idx,
|
||||||
|
HunterNetCoreData = ByteString.CopyFrom(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
//投递给服务端,来自客户端本地的连接数据
|
||||||
|
App.networkHelper.SendToServer((int)CommandID.CmdTunnelC2SData, respData);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
38
NoSugarNet.ClientCore/Manager/AppLogin.cs
Normal file
38
NoSugarNet.ClientCore/Manager/AppLogin.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using AxibugProtobuf;
|
||||||
|
using NoSugarNet.ClientCore.Common;
|
||||||
|
using NoSugarNet.ClientCore.Network;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore.Manager
|
||||||
|
{
|
||||||
|
public class AppLogin
|
||||||
|
{
|
||||||
|
public AppLogin()
|
||||||
|
{
|
||||||
|
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdLogin, RecvLoginMsg);
|
||||||
|
}
|
||||||
|
public void Login(string Account)
|
||||||
|
{
|
||||||
|
Protobuf_Login msg = new Protobuf_Login()
|
||||||
|
{
|
||||||
|
LoginType = 0,
|
||||||
|
Account = Account,
|
||||||
|
};
|
||||||
|
App.networkHelper.SendToServer((int)CommandID.CmdLogin, ProtoBufHelper.Serizlize(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecvLoginMsg(byte[] reqData)
|
||||||
|
{
|
||||||
|
Protobuf_Login_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Login_RESP>(reqData);
|
||||||
|
if (msg.Status == LoginResultStatus.Ok)
|
||||||
|
{
|
||||||
|
App.log.Debug("登录成功");
|
||||||
|
App.user.InitMainUserData(App.user.userdata.Account);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
App.log.Debug("登录失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
74
NoSugarNet.ClientCore/Manager/LocalClient/LocalClient.cs
Normal file
74
NoSugarNet.ClientCore/Manager/LocalClient/LocalClient.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//using HaoYueNet.ClientNetwork.OtherMode;
|
||||||
|
|
||||||
|
//namespace NoSugarNet.ClientCore
|
||||||
|
//{
|
||||||
|
// /// <summary>
|
||||||
|
// /// 继承网络库,以支持网络功能
|
||||||
|
// /// </summary>
|
||||||
|
// public class LocalClient : NetworkHelperCore_ListenerMode
|
||||||
|
// {
|
||||||
|
// public byte mTunnelID;
|
||||||
|
// public LocalClient(byte TunnelID)
|
||||||
|
// {
|
||||||
|
// mTunnelID = TunnelID;
|
||||||
|
// //指定接收服务器数据事件
|
||||||
|
// OnReceiveData += GetDataCallBack;
|
||||||
|
// //断开连接
|
||||||
|
// OnClose += OnConnectClose;
|
||||||
|
// OnConnected += NetworkConnected;
|
||||||
|
// //网络库调试信息输出事件,用于打印网络内容
|
||||||
|
// OnLogOut += NetworkDeBugLog;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void NetworkConnected(bool IsConnect)
|
||||||
|
// {
|
||||||
|
// NetworkDeBugLog($"LocalListener_Connected:{IsConnect}");
|
||||||
|
// if (IsConnect)
|
||||||
|
// {
|
||||||
|
// App.local.OnClientLocalConnect(mTunnelID,this);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// //连接失败
|
||||||
|
// NetworkDeBugLog("连接失败!");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void NetworkDeBugLog(string str)
|
||||||
|
// {
|
||||||
|
// //用于Unity内的输出
|
||||||
|
// //Debug.Log("NetCoreDebug >> "+str);
|
||||||
|
// Console.WriteLine("LocalListener_Debug >> " + 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
|
||||||
|
// {
|
||||||
|
// //抛出网络数据
|
||||||
|
// App.local.OnClientTunnelDataCallBack(mTunnelID, data);
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// NetworkDeBugLog("逻辑处理错误:" + ex.ToString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// 关闭连接
|
||||||
|
// /// </summary>
|
||||||
|
// public void OnConnectClose()
|
||||||
|
// {
|
||||||
|
// NetworkDeBugLog("LocalListener_OnConnectClose");
|
||||||
|
// App.local.OnClientLocalDisconnect(mTunnelID,this);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
187
NoSugarNet.ClientCore/Manager/LocalClient/LocalListener.cs
Normal file
187
NoSugarNet.ClientCore/Manager/LocalClient/LocalListener.cs
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
using HaoYueNet.ServerNetwork;
|
||||||
|
using NoSugarNet.ClientCore.Network;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore
|
||||||
|
{
|
||||||
|
public class LocalListener : TcpSaeaServer_SourceMode
|
||||||
|
{
|
||||||
|
public byte mTunnelID;
|
||||||
|
public LocalListener(int numConnections, int receiveBufferSize, byte TunnelID)
|
||||||
|
: base(numConnections, receiveBufferSize)
|
||||||
|
{
|
||||||
|
OnClientNumberChange += ClientNumberChange;
|
||||||
|
OnReceive += ReceiveData;
|
||||||
|
OnDisconnected += OnDisconnect;
|
||||||
|
OnNetLog += OnShowNetLog;
|
||||||
|
|
||||||
|
mTunnelID = TunnelID;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClientNumberChange(int num, AsyncUserToken token)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Client数发生变化");
|
||||||
|
//增加连接数
|
||||||
|
if (num > 0)
|
||||||
|
{
|
||||||
|
int Idx = AddDictSocket(token.Socket);
|
||||||
|
if (GetSocketByIdx(Idx, out Socket _socket))
|
||||||
|
{
|
||||||
|
App.local.OnClientLocalConnect(mTunnelID, (byte)Idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过下标发送
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Idx"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
public void SendSocketByIdx(int Idx, byte[] data)
|
||||||
|
{
|
||||||
|
if (GetSocketByIdx(Idx, out Socket _socket))
|
||||||
|
{
|
||||||
|
SendToSocket(_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)
|
||||||
|
{
|
||||||
|
App.log.Debug("收到消息 数据长度=>" + data.Length);
|
||||||
|
|
||||||
|
if (!GetSocketIdxBySocket(sk, out int Idx))
|
||||||
|
return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//抛出网络数据
|
||||||
|
App.local.OnClientTunnelDataCallBack(mTunnelID, (byte)Idx, data);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("逻辑处理错误:" + ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseConnectByIdx(byte Idx)
|
||||||
|
{
|
||||||
|
if (GetSocketByIdx(Idx, out Socket _socket))
|
||||||
|
{
|
||||||
|
_socket.Shutdown(SocketShutdown.Both);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 断开连接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sk"></param>
|
||||||
|
public void OnDisconnect(AsyncUserToken token)
|
||||||
|
{
|
||||||
|
Console.WriteLine("断开连接");
|
||||||
|
|
||||||
|
if (!GetSocketIdxBySocket(token.Socket, out int Idx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
App.local.OnClientLocalConnect(mTunnelID, (byte)Idx);
|
||||||
|
RemoveDictSocket(token.Socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnShowNetLog(string msg)
|
||||||
|
{
|
||||||
|
App.log.Debug(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 一个轻量级无用户连接管理
|
||||||
|
Dictionary<nint, int> DictSocketHandle2Idx = new Dictionary<nint, int>();
|
||||||
|
Dictionary<int, Socket> DictIdx2Socket = new Dictionary<int, Socket>();
|
||||||
|
int mSeedIdx = 0;
|
||||||
|
List<int> FreeIdxs = new List<int>();
|
||||||
|
int GetNextIdx()
|
||||||
|
{
|
||||||
|
if (FreeIdxs.Count > 0)
|
||||||
|
{
|
||||||
|
int Idx = FreeIdxs[0];
|
||||||
|
FreeIdxs.RemoveAt(0);
|
||||||
|
return Idx;
|
||||||
|
}
|
||||||
|
return mSeedIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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;
|
||||||
|
DictIdx2Socket[Idx] = socket;
|
||||||
|
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 (DictIdx2Socket.ContainsKey(Idx))
|
||||||
|
DictIdx2Socket.Remove(Idx);
|
||||||
|
DictSocketHandle2Idx.Remove(socket.Handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetSocketByIdx(int Idx, out Socket _socket)
|
||||||
|
{
|
||||||
|
if (!DictIdx2Socket.ContainsKey(Idx))
|
||||||
|
{
|
||||||
|
_socket = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_socket = DictIdx2Socket[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;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
20
NoSugarNet.ClientCore/Manager/LogManager.cs
Normal file
20
NoSugarNet.ClientCore/Manager/LogManager.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace NoSugarNet.ClientCore.Manager
|
||||||
|
{
|
||||||
|
public class LogManager
|
||||||
|
{
|
||||||
|
public void Debug(string str)
|
||||||
|
{
|
||||||
|
Console.WriteLine(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warning(string str)
|
||||||
|
{
|
||||||
|
Console.WriteLine(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string str)
|
||||||
|
{
|
||||||
|
Console.WriteLine(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
NoSugarNet.ClientCore/Manager/UserDataManager.cs
Normal file
56
NoSugarNet.ClientCore/Manager/UserDataManager.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using AxibugProtobuf;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore.Manager
|
||||||
|
{
|
||||||
|
public class UserDataBase
|
||||||
|
{
|
||||||
|
public long UID { get; set; }
|
||||||
|
public string Account { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MainUserDataBase : UserDataBase
|
||||||
|
{
|
||||||
|
public bool IsLoggedIn { get; set; } = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserDataManager
|
||||||
|
{
|
||||||
|
public UserDataManager()
|
||||||
|
{
|
||||||
|
//注册重连成功事件,以便后续自动登录
|
||||||
|
App.networkHelper.OnReConnected += OnReConnected;
|
||||||
|
}
|
||||||
|
public MainUserDataBase userdata { get;private set; } = new MainUserDataBase();
|
||||||
|
public bool IsLoggedIn => userdata.IsLoggedIn;
|
||||||
|
|
||||||
|
public void InitMainUserData(string UName)
|
||||||
|
{
|
||||||
|
userdata.Account = UName;
|
||||||
|
userdata.IsLoggedIn = true;
|
||||||
|
//以及其他数据初始化
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登出
|
||||||
|
/// </summary>
|
||||||
|
public void LoginOutData()
|
||||||
|
{
|
||||||
|
userdata.IsLoggedIn = false;
|
||||||
|
//以及其他数据清理
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当重连成功
|
||||||
|
/// </summary>
|
||||||
|
public void OnReConnected()
|
||||||
|
{
|
||||||
|
//如果之前已登录,则重新登录
|
||||||
|
if (userdata.IsLoggedIn)
|
||||||
|
{
|
||||||
|
App.login.Login(userdata.Account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
94
NoSugarNet.ClientCore/Network/NetMsg.cs
Normal file
94
NoSugarNet.ClientCore/Network/NetMsg.cs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
namespace NoSugarNet.ClientCore.Network
|
||||||
|
{
|
||||||
|
|
||||||
|
public class NetMsg
|
||||||
|
{
|
||||||
|
private static NetMsg instance = new NetMsg();
|
||||||
|
public static NetMsg Instance { get { return instance; } }
|
||||||
|
|
||||||
|
private Dictionary<int, List<Delegate>> netEventDic = new Dictionary<int, List<Delegate>>(128);
|
||||||
|
|
||||||
|
private NetMsg() { }
|
||||||
|
|
||||||
|
|
||||||
|
#region RegisterMsgEvent
|
||||||
|
|
||||||
|
public void RegNetMsgEvent(int cmd, Action<byte[]> callback)
|
||||||
|
{
|
||||||
|
InterRegNetMsgEvent(cmd, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterRegNetMsgEvent(int cmd, Delegate callback)
|
||||||
|
{
|
||||||
|
if (netEventDic.ContainsKey(cmd))
|
||||||
|
{
|
||||||
|
if (netEventDic[cmd].IndexOf(callback) < 0)
|
||||||
|
{
|
||||||
|
netEventDic[cmd].Add(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netEventDic.Add(cmd, new List<Delegate>() { callback });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region UnregisterCMD
|
||||||
|
|
||||||
|
public void UnregisterCMD(int evt, Action<byte[]> callback)
|
||||||
|
{
|
||||||
|
Delegate tempDelegate = callback;
|
||||||
|
InterUnregisterCMD(evt, tempDelegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InterUnregisterCMD(int cmd, Delegate callback)
|
||||||
|
{
|
||||||
|
if (netEventDic.ContainsKey(cmd))
|
||||||
|
{
|
||||||
|
netEventDic[cmd].Remove(callback);
|
||||||
|
if (netEventDic[cmd].Count == 0) netEventDic.Remove(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region PostEvent
|
||||||
|
public void PostNetMsgEvent(int cmd, byte[] arg)
|
||||||
|
{
|
||||||
|
List<Delegate> eventList = GetNetEventDicList(cmd);
|
||||||
|
if (eventList != null)
|
||||||
|
{
|
||||||
|
foreach (Delegate callback in eventList)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
((Action<byte[]>)callback)(arg);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
App.log.Error(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cmd"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private List<Delegate> GetNetEventDicList(int cmd)
|
||||||
|
{
|
||||||
|
if (netEventDic.ContainsKey(cmd))
|
||||||
|
{
|
||||||
|
List<Delegate> tempList = netEventDic[cmd];
|
||||||
|
if (null != tempList)
|
||||||
|
{
|
||||||
|
return tempList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
128
NoSugarNet.ClientCore/Network/NetworkHelper.cs
Normal file
128
NoSugarNet.ClientCore/Network/NetworkHelper.cs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
using AxibugProtobuf;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using HaoYueNet.ClientNetwork;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NoSugarNet.ClientCore.Network
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 继承网络库,以支持网络功能
|
||||||
|
/// </summary>
|
||||||
|
public class NetworkHelper : NetworkHelperCore
|
||||||
|
{
|
||||||
|
public NetworkHelper()
|
||||||
|
{
|
||||||
|
//指定接收服务器数据事件
|
||||||
|
OnReceiveData += GetDataCallBack;
|
||||||
|
//断开连接
|
||||||
|
OnClose += OnConnectClose;
|
||||||
|
OnConnected += NetworkConnected;
|
||||||
|
//网络库调试信息输出事件,用于打印网络内容
|
||||||
|
OnLogOut += NetworkDeBugLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void OnReConnectedHandler();
|
||||||
|
/// <summary>
|
||||||
|
/// 重连成功事件
|
||||||
|
/// </summary>
|
||||||
|
public event OnReConnectedHandler OnReConnected;
|
||||||
|
/// <summary>
|
||||||
|
/// 是否自动重连
|
||||||
|
/// </summary>
|
||||||
|
public bool bAutoReConnect = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 重连尝试时间
|
||||||
|
/// </summary>
|
||||||
|
const int ReConnectTryTime = 1000;
|
||||||
|
|
||||||
|
public void NetworkConnected(bool IsConnect)
|
||||||
|
{
|
||||||
|
NetworkDeBugLog($"NetworkConnected:{IsConnect}");
|
||||||
|
if (IsConnect)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//连接失败
|
||||||
|
NetworkDeBugLog("连接失败!");
|
||||||
|
//自动重连开关
|
||||||
|
if (bAutoReConnect)
|
||||||
|
ReConnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NetworkDeBugLog(string str)
|
||||||
|
{
|
||||||
|
//用于Unity内的输出
|
||||||
|
//Debug.Log("NetCoreDebug >> "+str);
|
||||||
|
Console.WriteLine("NetCoreDebug >> " + str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接受包回调
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="CMDID">协议ID</param>
|
||||||
|
/// <param name="ERRCODE">错误编号</param>
|
||||||
|
/// <param name="data">业务数据</param>
|
||||||
|
public void GetDataCallBack(int CMDID, int ERRCODE, byte[] data)
|
||||||
|
{
|
||||||
|
NetworkDeBugLog("收到消息 CMDID =>" + CMDID + " ERRCODE =>" + ERRCODE + " 数据长度=>" + data.Length);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//抛出网络数据
|
||||||
|
NetMsg.Instance.PostNetMsgEvent(CMDID, data);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
NetworkDeBugLog("逻辑处理错误:" + ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭连接
|
||||||
|
/// </summary>
|
||||||
|
public void OnConnectClose()
|
||||||
|
{
|
||||||
|
NetworkDeBugLog("OnConnectClose");
|
||||||
|
|
||||||
|
//自动重连开关
|
||||||
|
if (bAutoReConnect)
|
||||||
|
ReConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool bInReConnecting = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 自动重连
|
||||||
|
/// </summary>
|
||||||
|
void ReConnect()
|
||||||
|
{
|
||||||
|
if (bInReConnecting)
|
||||||
|
return;
|
||||||
|
bInReConnecting = true;
|
||||||
|
|
||||||
|
bool bflagDone = false;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//等待时间
|
||||||
|
Thread.Sleep(ReConnectTryTime);
|
||||||
|
App.log.Debug($"尝试自动重连{LastConnectIP}:{LastConnectPort}……");
|
||||||
|
//第一步
|
||||||
|
if (Init(LastConnectIP, LastConnectPort))
|
||||||
|
{
|
||||||
|
App.log.Debug($"自动重连成功!");
|
||||||
|
bflagDone = true;
|
||||||
|
App.log.Debug($"触发重连后的自动逻辑!");
|
||||||
|
OnReConnected?.Invoke();
|
||||||
|
}
|
||||||
|
} while (!bflagDone);
|
||||||
|
bInReConnecting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2972
NoSugarNet.ClientCore/Protobuf/ProtobufNoSugar.cs
Normal file
2972
NoSugarNet.ClientCore/Protobuf/ProtobufNoSugar.cs
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user