Merge pull request 'dev-tcptunnel' (#1) from dev-tcptunnel into master

Reviewed-on: #1
This commit is contained in:
sin365 2023-07-04 13:08:37 +08:00
commit a8be0154ec
46 changed files with 6195 additions and 160 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,13 +1,16 @@
using ClientCore;
using ClientCore.Data;
using ClientCore.Event;
App.Init("127.0.0.1", 23846);
App.Init("127.0.0.1", 23846, 23847);
//注册事件
EventSystem.Instance.RegisterEvent(EEvent.UserLogin, OnUserLogin);
EventSystem.Instance.RegisterEvent(EEvent.TcpTunnelHelloResp, OnTcpTunnelHelloResp);
EventSystem.Instance.RegisterEvent<long>(EEvent.UserJoin, OnUserJoin);
EventSystem.Instance.RegisterEvent<long>(EEvent.UserLeave, OnUserLeave);
EventSystem.Instance.RegisterEvent<string, string>(EEvent.OnChatMsg, OnChatMsg);
EventSystem.Instance.RegisterEvent<long, string>(EEvent.OnP2PChatMsg, OnP2PChatMsg);
while (true)
{
@ -17,6 +20,15 @@ while (true)
string[] CmdArr = CommandStr.Split(' ');
switch (Command)
{
case "info":
{
Console.WriteLine($"IsLogin:{App.userMgr.bLogin}");
if (App.userMgr.bLogin)
{
Console.WriteLine($"UID:{App.userMgr.MainPlayer.UID} NickName:{App.userMgr.MainPlayer.NickName}");
}
}
break;
case "login":
case "l":
if (CmdArr.Length < 2)
@ -26,6 +38,18 @@ while (true)
}
App.login.Login(CmdArr[1]);
break;
case "tcphey":
case "they":
App.p2ptcp.SendHellToSev();
break;
case "tu":
if (CmdArr.Length < 2)
{
Console.WriteLine("缺省用户名");
return;
}
App.p2ptcp.SendDoTunnel(Convert.ToInt64(CmdArr[1]));
break;
case "say":
if (CmdArr.Length < 2)
{
@ -34,22 +58,68 @@ while (true)
}
App.chat.SendChatMsg(CmdArr[1]);
break;
case "tusay":
if (CmdArr.Length < 3)
{
Console.WriteLine("缺省参数");
return;
}
App.p2pChat.SendChatMsg(Convert.ToInt64(CmdArr[1]), CmdArr[2]);
break;
case "tufile":
case "tuf":
if (CmdArr.Length < 3)
{
Console.WriteLine("缺省参数");
return;
}
App.p2pFile.sender_FilePushConfirmToTarget(Convert.ToInt64(CmdArr[1]), CmdArr[2]);
break;
case "ulist":
{
UserInfo[] ulist = App.userMgr.GetUserInfo();
Console.WriteLine("User总数"+ ulist.Length);
for (int i = 0; i < ulist.Length; i++)
{
Console.WriteLine($"[{i}] UID->{ulist[i].UID} | NickName->{ulist[i].NickName} | State->{ulist[i].State}");
}
}
break;
default:
Console.WriteLine("未知命令" + CommandStr);
break;
}
}
void OnUserLogin()
{
Console.WriteLine($"[User]登录成功");
App.userMgr.Send_GetUserList();
App.clientMgr.ConnectTcpTunnelServer();
}
void OnTcpTunnelHelloResp()
{
Console.WriteLine($"[TcpTunnel]TcpTunnelHelloResp");
}
void OnUserJoin(long UID)
{
Console.WriteLine($"[User]用户{UID}上线");
}
void OnUserLeave(long UID)
{
Console.WriteLine($"[User]用户{UID}下线");
}
void OnChatMsg(string str1, string str2)
{
Console.WriteLine($"[Chat]{str1}:{str2}");
}
void OnUserJoin(long UID)
void OnP2PChatMsg(long uid, string str2)
{
Console.WriteLine($"[User]用户{UID}上线");
}
void OnUserLeave(long UID)
{
Console.WriteLine($"[User]用户{UID}下线");
Console.WriteLine($"[P2PChatMsg]{uid}:{str2}");
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -15,19 +16,31 @@ namespace ClientCore
public static string IP;
public static int Port;
public static LogManager log;
public static NetworkHelper networkHelper;
public static ClientManager clientMgr;
public static P2PTcp p2ptcp;
public static P2PChat p2pChat;
public static P2PFile p2pFile;
public static NetworkHelper networkMain;
public static NetworkHelper networkTcp2S;
public static AppLogin login;
public static AppChat chat;
public static UserMgr userMgr;
public static void Init(string IP, int port)
public static void Init(string IP, int port, int tcptunnelport)
{
log = new LogManager();
networkHelper = new NetworkHelper();
login = new AppLogin();
chat = new AppChat();
userMgr = new UserMgr();
networkHelper.Init(IP, port);
clientMgr = new ClientManager();
clientMgr.SetIpData(IP, port, tcptunnelport);
p2ptcp = new P2PTcp();
p2pChat = new P2PChat();
p2pFile = new P2PFile();
networkMain = new NetworkHelper(Enum.ServerType.MainServer);
networkMain.Init(IP, port);
//networkTcp2S = new NetworkHelper(Enum.ServerType.TcpTunnelServer);
//networkTcp2S.Init(IP, tcptunnelport);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClientCore.Data
{
public class UserInfo
{
public long UID;//用户ID
public string NickName;//昵称
public int State;//状态
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClientCore.Enum
{
public enum ServerType
{
MainServer,
TcpTunnelServer,
TcpP2PTarget
}
}

View File

@ -9,8 +9,19 @@ namespace ClientCore.Event
public enum EEvent
{
// 添加你自己需要的事件类型
UserLogin,
UserJoin,
UserLeave,
OnChatMsg,
OnP2PChatMsg,
//打洞流程
TcpTunnelHelloResp,
//连接管理
OnSocketConnect,
OnSocketDisconnect,
//文件传输
}
}

View File

@ -18,7 +18,7 @@ namespace ClientCore.Manager
{
ChatMsg = ChatMsg,
};
App.networkHelper.SendToServer((int)CommandID.CmdChatmsg, ProtoBufHelper.Serizlize(msg));
App.networkMain.SendToServer((int)CommandID.CmdChatmsg, ProtoBufHelper.Serizlize(msg));
}
public void RecvChatMsg(byte[] reqData)

View File

@ -1,10 +1,17 @@
using AxibugProtobuf;
using ClientCore.Common;
using ClientCore.Event;
using ClientCore.Network;
namespace ClientCore.Manager
{
public class AppLogin
{
public AppLogin()
{
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdLogin, RecvCmdLogin);
}
public void Login(string Account)
{
Protobuf_Login msg = new Protobuf_Login()
@ -12,7 +19,14 @@ namespace ClientCore.Manager
LoginType = 0,
Account = Account,
};
App.networkHelper.SendToServer((int)CommandID.CmdLogin, ProtoBufHelper.Serizlize(msg));
App.networkMain.SendToServer((int)CommandID.CmdLogin, ProtoBufHelper.Serizlize(msg));
}
public void RecvCmdLogin(byte[] reqData)
{
Protobuf_Login_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Login_RESP>(reqData);
App.userMgr.SetMainPlayer(msg.UID, msg.NickName, 0);
EventSystem.Instance.PostEvent(EEvent.UserLogin);
}
}
}

View File

@ -0,0 +1,210 @@
using AxibugProtobuf;
using ClientCore.Common;
using ClientCore.Enum;
using ClientCore.Event;
using ClientCore.Network;
using HaoYueNet.ClientNetwork;
using System.Net.Sockets;
using System.Timers;
using static System.Runtime.CompilerServices.RuntimeHelpers;
namespace ClientCore.Manager
{
public class ClientManager
{
bool bTryReConTcpTunnelServer = false;
string IP;
int port;
int tcptunnelport;
int LastlocalPort = 0;
Dictionary<long, NetworkP2PHelper> DictUID2TcpTaret = new Dictionary<long, NetworkP2PHelper>();
public ClientManager()
{
//注册事件
EventSystem.Instance.RegisterEvent<ServerType, bool>(EEvent.OnSocketConnect, OnSocketConnect);
EventSystem.Instance.RegisterEvent<ServerType, long>(EEvent.OnSocketDisconnect, OnSocketDisconnect);
}
public void SetIpData(string IP, int port, int tcptunnelport)
{
this.IP = IP;
this.port = port;
this.tcptunnelport = tcptunnelport;
}
void OnSocketConnect(ServerType servertype, bool IsOk)
{
switch (servertype)
{
case ServerType.MainServer:
{
if (IsOk)
{
Console.WriteLine("MainServer连接成功");
}
else
{
Console.WriteLine("MainServer连接失败");
}
}
break;
case ServerType.TcpTunnelServer:
{
bTryReConTcpTunnelServer = false;
if (IsOk)
{
Console.WriteLine("TcpTunnelServer连接成功");
App.p2ptcp.SendHellToSev();
}
else
{
Console.WriteLine("TcpTunnelServer连接失败");
}
}
break;
case ServerType.TcpP2PTarget:
{
if (IsOk)
{
Console.WriteLine("TcpP2PTarget连接成功");
}
}
break;
}
}
void OnSocketDisconnect(ServerType servertype, long uid)
{
switch (servertype)
{
case ServerType.MainServer:
{
Console.WriteLine("MainServer连接断开");
}
break;
case ServerType.TcpTunnelServer:
{
Console.WriteLine("TcpTunnelServer连接断开");
Console.WriteLine("TcpTunnelServer,尝试重连");
ReConnectTcpTunnelServer();
}
break;
case ServerType.TcpP2PTarget:
{
Console.WriteLine("TcpP2PTarget连接断开");
RemoveTargetSocket(uid);
}
break;
}
}
public void ConnectTcpTunnelServer()
{
App.networkTcp2S = new NetworkHelper(Enum.ServerType.TcpTunnelServer);
App.networkTcp2S.Init(IP, tcptunnelport);
}
public void ReConnectTcpTunnelServer()
{
//TODO 因TEST 暂不重连
return;
if (bTryReConTcpTunnelServer)
return;
if (App.networkTcp2S != null && App.networkTcp2S.GetClientSocket() != null && App.networkTcp2S.GetClientSocket().Connected)
return;
bTryReConTcpTunnelServer = true;
Thread thread = new Thread(ReConnectTcpTunnelServerThread);
thread.IsBackground = true;
thread.Start();
}
private void ReConnectTcpTunnelServerThread()
{
Thread.Sleep(1000);
App.networkTcp2S.Init(IP, tcptunnelport);
}
#region P2PTarget
void AddTargetSocket(NetworkP2PHelper targetSocket)
{
DictUID2TcpTaret[targetSocket.mUID] = targetSocket;
}
void RemoveTargetSocket(long UID)
{
if (DictUID2TcpTaret.ContainsKey(UID))
{
DictUID2TcpTaret.Remove(UID);
}
}
NetworkP2PHelper GetTargetSocket(long UID)
{
if (DictUID2TcpTaret.ContainsKey(UID))
{
return DictUID2TcpTaret[UID];
}
return null;
}
/// <summary>
/// 发送给指定UID消息
/// </summary>
/// <param name="UID"></param>
/// <param name="CMDID"></param>
/// <param name="data"></param>
public void SendToTargetSocket(long UID, int CMDID, int ERRCODE, byte[] data)
{
NetworkP2PHelper target = GetTargetSocket(UID);
if (target == null)
return;
target.SendToSocket((int)CMDID, ERRCODE, data);
}
#endregion
#region TCP打洞对连
public void ConnectTCPTargetP2P(Protobuf_TcpTunnel_DoTunnel_RESP msg, int localPort)
{
LastlocalPort = localPort;
Thread thread = new Thread(ConnectTCPTargetP2PThread);
thread.IsBackground = true;
thread.Start(msg);
}
public void ConnectTCPTargetP2PThread(object obj)
{
Thread.Sleep(1000);
int userBindPort = LastlocalPort;
Protobuf_TcpTunnel_DoTunnel_RESP msg = (Protobuf_TcpTunnel_DoTunnel_RESP)obj;
Console.WriteLine("LocalEndPoint Port" + userBindPort);
NetworkP2PHelper targetSocket = new NetworkP2PHelper(Enum.ServerType.TcpP2PTarget, msg.TargetUID);
targetSocket.Init(msg.OtherIP, msg.OtherPort, true, userBindPort);
//尝试5次连接
for (int j = 0; j < 5; j++)
{
try
{
targetSocket.Connect(msg.OtherIP, msg.OtherPort);
Console.WriteLine("Connect成功{0},{1}", msg.OtherIP, msg.OtherPort);
AddTargetSocket(targetSocket);
break;
}
catch (Exception)
{
Console.WriteLine("Connect失败");
}
}
}
#endregion
}
}

View File

@ -0,0 +1,28 @@
using AxibugProtobuf;
using ClientCore.Common;
using ClientCore.Event;
using ClientCore.Network;
namespace ClientCore.Manager
{
public class P2PChat
{
public P2PChat()
{
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcpP2PChat, RecvChatMsg);
}
public void SendChatMsg(long UID, string ChatMsg)
{
Protobuf_TcpP2P_Chat msg = new Protobuf_TcpP2P_Chat()
{
ChatMsg = ChatMsg,
};
App.clientMgr.SendToTargetSocket(UID, (int)CommandID.CmdTcpP2PChat,(int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(msg));
}
public void RecvChatMsg(long uid, byte[] reqData)
{
Protobuf_TcpP2P_Chat msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpP2P_Chat>(reqData);
EventSystem.Instance.PostEvent(EEvent.OnP2PChatMsg, uid, msg.ChatMsg);
}
}
}

View File

@ -0,0 +1,408 @@
using AxibugProtobuf;
using ClientCore.Common;
using ClientCore.Event;
using ClientCore.Network;
using Google.Protobuf;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ClientCore.Manager
{
public class P2PFile
{
public int cPackSize = 5 * 1024;
public int WaitSendPackCount = 100;
//是否自动同意接收
public bool bAutoRecv = true;
public P2PFile()
{
//发送者协议注册
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcpP2PFilepushConfirmResp, RecvTcpP2PFilepushConfirmResp);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcpP2PFilepushResp, RecvTcpP2PFilepushResp);
//接收者协议注册
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcpP2PFilepushConfirm, RecvTcpP2PFilepushConfirm);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcpP2PFilepush, RecvTcpP2PFilepush);
}
#region
public void SendFilePushConfirm(long UID, FilePushTask taskinfo)
{
Protobuf_TcpP2P_FilePushConfirm msg = new Protobuf_TcpP2P_FilePushConfirm()
{
TaskID = taskinfo.TaskID,
PackSize = taskinfo.PackSize,
ContentType = taskinfo.ContentType,
FileHash = taskinfo.FileHash,
FileLenght = taskinfo.FileLenght,
FileName = taskinfo.FileName,
PackCount = taskinfo.PackCount,
};
App.clientMgr.SendToTargetSocket(UID, (int)CommandID.CmdTcpP2PFilepushConfirm, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(msg));
}
public void SendFilePush(long UID,int TaskID, long Index, byte[] data, int dataLength)
{
Protobuf_TcpP2P_FilePush msg = new Protobuf_TcpP2P_FilePush()
{
TaskID = TaskID,
PackIndex = Index,
PackLenght= dataLength,
FileData = ByteString.CopyFrom(data)
};
App.clientMgr.SendToTargetSocket(UID, (int)CommandID.CmdTcpP2PFilepush, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(msg));
}
void RecvTcpP2PFilepushConfirmResp(long uid, byte[] reqData)
{
Protobuf_TcpP2P_FilePushConfirm_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpP2P_FilePushConfirm_RESP>(reqData);
// 开始发送
if (msg.Agree == 1)
{
sender_AgreeRecvFile(msg.TaskID);
}
else
{
//TODO 被拒绝
}
}
void RecvTcpP2PFilepushResp(long uid, byte[] reqData)
{
//收到回执信息
Protobuf_TcpP2P_FilePush_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpP2P_FilePush_RESP>(reqData);
sender_StartPushFileThread(msg.TaskID, msg.FinishIndex);
}
#endregion
#region
Dictionary<int, FilePushTask> DictTaskID2Task_SendReady = new Dictionary<int, FilePushTask>();
Dictionary<int, FilePushTask> DictTaskID2Task_SendDo = new Dictionary<int, FilePushTask>();
/// <summary>
/// 发送者发送文件请求
/// </summary>
/// <param name="UID"></param>
/// <param name="path"></param>
public void sender_FilePushConfirmToTarget(long UID, string path)
{
FileInfo finfo = new FileInfo(path);
//向上取整
long packCount = (long)Math.Ceiling(finfo.Length / (float)cPackSize);
FilePushTask ftask = new FilePushTask()
{
TaskID = 1,//TODO
fromUID = App.userMgr.MainPlayer.UID,
targetUID = UID,
Path = path,
FileName = finfo.Name,
PackSize = cPackSize,
PackCount = packCount,
FileLenght = finfo.Length,
FileHash = "",//TODO
ContentType = "",//TODO
CurrIndex = -1,
ConfirmIndex= -1,
};
SendFilePushConfirm(UID, ftask);
DictTaskID2Task_SendReady[ftask.TaskID] = ftask;
}
public void sender_AgreeRecvFile(int TaskID)
{
if (DictTaskID2Task_SendReady.ContainsKey(TaskID))
{
FilePushTask task = DictTaskID2Task_SendReady[TaskID];
DictTaskID2Task_SendDo[TaskID] = task;
DictTaskID2Task_SendReady.Remove(TaskID);
sender_StartPushFile(TaskID);
}
}
//开始发送文件传输
void sender_StartPushFile(int TaskID)
{
if (!DictTaskID2Task_SendDo.ContainsKey(TaskID))
{
return;
}
FilePushTask task = DictTaskID2Task_SendDo[TaskID];
Thread thread = new Thread(sender_StartPushFileThread);
thread.IsBackground = true;
thread.Start(TaskID);
}
void sender_StartPushFileThread(int TaskID,long Index)
{
if (!DictTaskID2Task_SendDo.ContainsKey(TaskID))
return;
DictTaskID2Task_SendDo[TaskID].ConfirmIndex = Index;
}
/// <summary>
/// 开始发送线程用
/// </summary>
/// <param name="obj"></param>
void sender_StartPushFileThread(object obj)
{
int TaskID = (int)obj;
if (!DictTaskID2Task_SendDo.ContainsKey(TaskID))
return;
FilePushTask task = DictTaskID2Task_SendDo[TaskID];
//构造读取文件流对象
using (FileStream fsRead = new FileStream(task.Path, FileMode.Open)) //打开文件,不能创建新的
{
//开辟临时缓存内存
byte[] byteArrayRead = new byte[cPackSize]; // 1字节*1024 = 1k 1k*1024 = 1M内存
App.log.Debug($"[文件发送者]开始发送文件!!");
//通过死缓存去读文本中的内容
while (true)
{
//若发送下标,大于确认下标一定数量,则等待
while (task.CurrIndex - task.ConfirmIndex > WaitSendPackCount)
{
Thread.Sleep(10);
}
//readCount 这个是保存真正读取到的字节数
int readCount = fsRead.Read(byteArrayRead, 0, byteArrayRead.Length);
//TODO 大小
//if (readCount == cPackSize)
//{
//}
//else
//{
//}
task.CurrIndex++;
SendFilePush(task.targetUID, TaskID, task.CurrIndex, byteArrayRead, readCount);
//App.log.Debug($"发送文件片段,下标->{task.CurrIndex}");
//既然是死循环 那么什么时候我们停止读取文本内容 我们知道文本最后一行的大小肯定是小于缓存内存大小的
if (readCount < byteArrayRead.Length)
{
App.log.Debug($"[文件发送者]文件发送完毕!! task.CurrIndex->{task.CurrIndex}");
DictTaskID2Task_SendDo.Remove(TaskID);
fsRead.Close();
break; //结束循环
}
}
}
}
#endregion
#region
/// <summary>
///
/// </summary>
/// <param name="UID"></param>
/// <param name="TaskID"></param>
/// <param name="bAgree">[1]同意 [0]拒绝</param>
public void SendFilePushConfirm_Resp(long UID, int TaskID, int bAgree)
{
Protobuf_TcpP2P_FilePushConfirm_RESP msg = new Protobuf_TcpP2P_FilePushConfirm_RESP()
{
TaskID = TaskID,
Agree = bAgree
};
App.clientMgr.SendToTargetSocket(UID, (int)CommandID.CmdTcpP2PFilepushConfirmResp, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(msg));
}
/// <summary>
///
/// </summary>
/// <param name="UID"></param>
/// <param name="TaskID"></param>
/// <param name="Index"></param>
public void SendFilePush_Resp(long UID, int TaskID, long Index)
{
Protobuf_TcpP2P_FilePush_RESP msg = new Protobuf_TcpP2P_FilePush_RESP()
{
TaskID = TaskID,
FinishIndex = Index
};
App.clientMgr.SendToTargetSocket(UID, (int)CommandID.CmdTcpP2PFilepushResp, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(msg));
}
void RecvTcpP2PFilepushConfirm(long uid, byte[] reqData)
{
Protobuf_TcpP2P_FilePushConfirm msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpP2P_FilePushConfirm>(reqData);
receiver_AddRecvFileReady(new FilePushTask()
{
TaskID = msg.TaskID,
PackSize = cPackSize,
ContentType = msg.ContentType,
FileHash = msg.FileHash,
FileLenght = msg.FileLenght,
FileName = msg.FileName,
PackCount = msg.PackCount,
Path = "",//待插入
fromUID = uid,
targetUID = App.userMgr.MainPlayer.UID,
CurrIndex = -1,
ConfirmIndex= -1,//虽然用不上
});
//TODO 事件 EventSystem.Instance.PostEvent(EEvent.OnP2PChatMsg, uid, msg.ChatMsg);
}
void RecvTcpP2PFilepush(long uid, byte[] reqData)
{
Protobuf_TcpP2P_FilePush msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpP2P_FilePush>(reqData);
if (!DictTaskID2Task_RecvDataQueue.ContainsKey(msg.TaskID))
return;
if (msg == null)
{
}
DictTaskID2Task_RecvDataQueue[msg.TaskID].Enqueue(msg);
}
#endregion
#region
Dictionary<int, FilePushTask> DictTaskID2Task_RecvReady = new Dictionary<int, FilePushTask>();
Dictionary<int, FilePushTask> DictTaskID2Task_RecvDo = new Dictionary<int, FilePushTask>();
Dictionary<int, Queue<Protobuf_TcpP2P_FilePush>> DictTaskID2Task_RecvDataQueue = new Dictionary<int, Queue<Protobuf_TcpP2P_FilePush>>();
/// <summary>
/// 接收数据准备
/// </summary>
/// <param name="task"></param>
void receiver_AddRecvFileReady(FilePushTask task)
{
DictTaskID2Task_RecvReady[task.TaskID] = task;
//自动接收文件
if (bAutoRecv)
{
receiver_AgreeRecvFile(task.TaskID);
}
}
/// <summary>
/// 同意文件传输
/// </summary>
/// <param name="TaskID"></param>
public void receiver_AgreeRecvFile(int TaskID)
{
if (DictTaskID2Task_RecvReady.ContainsKey(TaskID))
{
FilePushTask task = DictTaskID2Task_RecvReady[TaskID];
DictTaskID2Task_RecvDo[TaskID] = task;
DictTaskID2Task_RecvReady.Remove(TaskID);
receiver_StartRecvFile(TaskID);
App.log.Debug("[文件接收者]:发送同意接收");
SendFilePushConfirm_Resp(task.fromUID, task.TaskID, 1);
}
}
/// <summary>
/// 开始接收文件传输
/// </summary>
/// <param name="TaskID"></param>
void receiver_StartRecvFile(int TaskID)
{
if (!DictTaskID2Task_RecvDo.ContainsKey(TaskID))
{
return;
}
FilePushTask task = DictTaskID2Task_RecvDo[TaskID];
DictTaskID2Task_RecvDataQueue[TaskID] = new Queue<Protobuf_TcpP2P_FilePush>();
Thread thread = new Thread(receiver_StartRecvFileThread);
thread.IsBackground = true;
thread.Start(TaskID);
App.log.Debug("[文件接收者]:准备接收线程");
}
/// <summary>
/// 接收任务线程
/// </summary>
/// <param name="obj"></param>
void receiver_StartRecvFileThread(object obj)
{
int TaskID = (int)obj;
FilePushTask task = null;
if (!DictTaskID2Task_RecvDo.ContainsKey(TaskID))
return;
task = DictTaskID2Task_RecvDo[TaskID];
string fullpath = System.Environment.CurrentDirectory + "//" + task.FileName;
FileInfo myFile = new FileInfo(fullpath);
FileStream fs = myFile.Create();
//int WriteLenght = 0;
//TODO 打开文件写入
while (true)
{
Queue<Protobuf_TcpP2P_FilePush> dataqueue = DictTaskID2Task_RecvDataQueue[TaskID];
bool bflag = false;
while (dataqueue.Count > 0)
{
Protobuf_TcpP2P_FilePush msg = dataqueue.Dequeue();
if (msg == null)
continue;
bflag = true;
byte[] bytedata = msg.FileData.ToArray();
if (msg.PackIndex - task.CurrIndex != 1)
{
App.log.Error($"[文件接收者]接收下标错误msg.PackIndex->{msg.PackIndex} task.CurrIndex=>{task.CurrIndex}");
}
//写入文件
fs.Write(bytedata, 0, msg.PackLenght);
//WriteLenght += msg.PackLenght;
task.CurrIndex = msg.PackIndex;
//todo 写入片段
//更新进度
//App.log.Debug($"[文件接收者]收到文件片段,下标->{task.CurrIndex}");
}
if (bflag)
{
//回执收到信息
SendFilePush_Resp(task.fromUID, TaskID, task.CurrIndex);
}
if (task.CurrIndex + 1 >= task.PackCount)
{
//文件接收完毕
App.log.Debug($"[文件接收者]文件接收完毕!! task.CurrIndex->{task.CurrIndex} task.PackCount->{task.PackCount}");
//删除进行中字典
DictTaskID2Task_RecvDo.Remove(TaskID);
//删除进行中数据队列
DictTaskID2Task_RecvDataQueue.Remove(TaskID);
break;
}
Thread.Sleep(10);
}
//TODO 结束写入
fs.Close();
}
#endregion
}
public class FilePushTask
{
public int TaskID;//传输任务ID
public long fromUID;//发送者UID
public long targetUID;
public string Path;
public long FileLenght;//文件长度
public string ContentType;//ContentType
public string FileName;//文件名
public int PackSize;//每个包大小
public long PackCount;//包数量
public string FileHash;//文件hash
public long CurrIndex;
public long ConfirmIndex;
}
}

View File

@ -0,0 +1,61 @@
using AxibugProtobuf;
using ClientCore.Common;
using ClientCore.Event;
using ClientCore.Network;
using System.Net;
using System.Net.Sockets;
namespace ClientCore.Manager
{
public class P2PTcp
{
bool bRegToSev = false;
public P2PTcp()
{
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcptunnelHello, RecvTcptunnelHello);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcptunnelDo, RecvCmdTcptunnelDo);
}
public void SendHellToSev()
{
Protobuf_TcpTunnel_HellToSev msg = new Protobuf_TcpTunnel_HellToSev()
{
UID = App.userMgr.MainPlayer.UID
};
App.networkTcp2S.SendToServer((int)CommandID.CmdTcptunnelHello, ProtoBufHelper.Serizlize(msg));
}
public void RecvTcptunnelHello(byte[] reqData)
{
Protobuf_TcpTunnel_HellToSev_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpTunnel_HellToSev_RESP>(reqData);
bRegToSev = true;
EventSystem.Instance.PostEvent(EEvent.TcpTunnelHelloResp);
}
public void SendDoTunnel(long targetUID)
{
Protobuf_TcpTunnel_DoTunnel msg = new Protobuf_TcpTunnel_DoTunnel()
{
UID = App.userMgr.MainPlayer.UID,
TargetUID = targetUID
};
App.networkTcp2S.SendToServer((int)CommandID.CmdTcptunnelDo, ProtoBufHelper.Serizlize(msg));
}
public void RecvCmdTcptunnelDo(byte[] reqData)
{
Protobuf_TcpTunnel_DoTunnel_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpTunnel_DoTunnel_RESP>(reqData);
//TODO 打洞
Console.WriteLine($"打洞目标信息 {msg.TargetUID} {msg.OtherIP} {msg.OtherPort}");
int localPort = ((IPEndPoint)App.networkTcp2S.GetClientSocket().LocalEndPoint).Port;
//断开连接
App.networkTcp2S.CloseConntect();
App.clientMgr.ConnectTCPTargetP2P(msg, localPort);
}
}
}

View File

@ -1,5 +1,6 @@
using AxibugProtobuf;
using ClientCore.Common;
using ClientCore.Data;
using ClientCore.Event;
using ClientCore.Network;
using System;
@ -7,27 +8,41 @@ using System.Security.Cryptography;
namespace ClientCore.Manager
{
public class UserInfo
{
public long UID;//用户ID
public string NickName;//昵称
public int State;//状态
}
public class UserMgr
{
public Dictionary<long, UserInfo> DictUID2User = new Dictionary<long, UserInfo>();
public UserInfo MainPlayer { get; private set; }
public bool bLogin => MainPlayer != null;
Dictionary<long, UserInfo> DictUID2User = new Dictionary<long, UserInfo>();
public UserMgr()
{
//网络事件注册
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserOnlinelist, RecvUserOnlinelist);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserJoin, RecvCmdUserJoin);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserLeave, RecvGetUserLeave);
}
public void SetMainPlayer(long uid,string account,int state)
{
MainPlayer = new UserInfo()
{
State = state,
NickName = account,
UID = uid
};
}
public void Send_GetUserList()
{
Protobuf_UserList msg = new Protobuf_UserList()
{
};
App.networkMain.SendToServer((int)CommandID.CmdUserOnlinelist, ProtoBufHelper.Serizlize(msg));
}
public void RecvUserOnlinelist(byte[] reqData)
{
Protobuf_UserList_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserList_RESP>(reqData);
for(int i = 0;i < msg.UserList.Count;i++)
{
UserMiniInfo mi = msg.UserList[i];
@ -86,5 +101,16 @@ namespace ClientCore.Manager
EventSystem.Instance.PostEvent(EEvent.UserLeave, UID);
}
}
public UserInfo[] GetUserInfo()
{
UserInfo[] ulist = new UserInfo[DictUID2User.Count];
long[] UIDs = DictUID2User.Keys.ToArray();
for (int i = 0; i < UIDs.Length; i++)
{
ulist[i] = DictUID2User[UIDs[i]];
}
return ulist;
}
}
}

View File

@ -18,6 +18,11 @@
InterRegNetMsgEvent(cmd, callback);
}
public void RegNetMsgEvent(int cmd, Action<long,byte[]> callback)
{
InterRegNetMsgEvent(cmd, callback);
}
private void InterRegNetMsgEvent(int cmd, Delegate callback)
{
if (netEventDic.ContainsKey(cmd))
@ -42,6 +47,11 @@
InterUnregisterCMD(evt, tempDelegate);
}
public void UnregisterCMD(int evt, Action<long, byte[]> callback)
{
Delegate tempDelegate = callback;
InterUnregisterCMD(evt, tempDelegate);
}
private void InterUnregisterCMD(int cmd, Delegate callback)
{
if (netEventDic.ContainsKey(cmd))
@ -53,6 +63,25 @@
#endregion
#region PostEvent
public void PostNetMsgEvent(int cmd, long uid, byte[] arg)
{
List<Delegate> eventList = GetNetEventDicList(cmd);
if (eventList != null)
{
foreach (Delegate callback in eventList)
{
try
{
((Action<long,byte[]>)callback)(uid,arg);
}
catch (Exception e)
{
App.log.Error(e.Message);
}
}
}
}
public void PostNetMsgEvent(int cmd, byte[] arg)
{
List<Delegate> eventList = GetNetEventDicList(cmd);

View File

@ -1,4 +1,6 @@
using AxibugProtobuf;
using ClientCore.Enum;
using ClientCore.Event;
using HaoYueNet.ClientNetwork;
using System;
using System.Collections.Generic;
@ -13,7 +15,9 @@ namespace ClientCore.Network
/// </summary>
public class NetworkHelper : NetworkHelperCore
{
public NetworkHelper()
ServerType mServerType;
public long mUID { get; private set; } = -1;
public NetworkHelper(ServerType serverType,long UID = -1)
{
//指定接收服务器数据事件
OnDataCallBack += GetDataCallBack;
@ -22,15 +26,21 @@ namespace ClientCore.Network
//网络库调试信息输出事件,用于打印连接断开,收发事件
OnLogOut += NetworkDeBugLog;
OnConnected += NetworkConnected;
mServerType = serverType;
mUID = UID;
}
public void NetworkConnected(bool IsConnect)
{
if (IsConnect)
{
EventSystem.Instance.PostEvent(EEvent.OnSocketConnect, mServerType, true);
NetworkDeBugLog("服务器连接成功");
}
else
{
EventSystem.Instance.PostEvent(EEvent.OnSocketConnect, mServerType, false);
NetworkDeBugLog("服务器连接失败");
//to do 重连逻辑
}
@ -52,11 +62,18 @@ namespace ClientCore.Network
/// <param name="data">业务数据</param>
public void GetDataCallBack(int CMDID, int ERRCODE, byte[] data)
{
NetworkDeBugLog("收到消息 CMDID =>" + CMDID + " ERRCODE =>" + ERRCODE + " 数据长度=>" + data.Length);
//NetworkDeBugLog("收到消息 CMDID =>" + CMDID + " ERRCODE =>" + ERRCODE + " 数据长度=>" + data.Length);
try
{
//抛出网络数据
NetMsg.Instance.PostNetMsgEvent(CMDID, data);
if (mServerType == ServerType.TcpP2PTarget)
{
NetMsg.Instance.PostNetMsgEvent(CMDID, mUID,data);
}
else
{
NetMsg.Instance.PostNetMsgEvent(CMDID, data);
}
}
catch (Exception ex)
{
@ -71,6 +88,7 @@ namespace ClientCore.Network
public void OnConnectClose()
{
NetworkDeBugLog("OnConnectClose");
EventSystem.Instance.PostEvent(EEvent.OnSocketDisconnect, mServerType, mUID);
}
}
}

View File

@ -0,0 +1,94 @@
using AxibugProtobuf;
using ClientCore.Enum;
using ClientCore.Event;
using HaoYueNet.ClientNetwork;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClientCore.Network
{
/// <summary>
/// 继承网络库,以支持网络功能
/// </summary>
public class NetworkP2PHelper : NetworkHelperP2PCore
{
ServerType mServerType;
public long mUID { get; private set; } = -1;
public NetworkP2PHelper(ServerType serverType,long UID = -1)
{
//指定接收服务器数据事件
OnDataCallBack += GetDataCallBack;
//断开连接
OnClose += OnConnectClose;
//网络库调试信息输出事件,用于打印连接断开,收发事件
OnLogOut += NetworkDeBugLog;
OnConnected += NetworkConnected;
mServerType = serverType;
mUID = UID;
}
public void NetworkConnected(bool IsConnect)
{
if (IsConnect)
{
EventSystem.Instance.PostEvent(EEvent.OnSocketConnect, mServerType, true);
NetworkDeBugLog("服务器连接成功");
}
else
{
EventSystem.Instance.PostEvent(EEvent.OnSocketConnect, mServerType, false);
NetworkDeBugLog("服务器连接失败");
//to do 重连逻辑
}
}
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
{
//抛出网络数据
if (mServerType == ServerType.TcpP2PTarget)
{
NetMsg.Instance.PostNetMsgEvent(CMDID, mUID,data);
}
else
{
NetMsg.Instance.PostNetMsgEvent(CMDID, data);
}
}
catch (Exception ex)
{
NetworkDeBugLog("逻辑处理错误:" + ex.ToString());
}
}
/// <summary>
/// 关闭连接
/// </summary>
public void OnConnectClose()
{
NetworkDeBugLog("OnConnectClose");
EventSystem.Instance.PostEvent(EEvent.OnSocketDisconnect, mServerType, mUID);
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -28,27 +28,32 @@ namespace AxibugProtobuf {
"dG9idWZfTG9naW4SLAoJbG9naW5UeXBlGAEgASgOMhkuQXhpYnVnUHJvdG9i",
"dWYuTG9naW5UeXBlEi4KCmRldmljZVR5cGUYAiABKA4yGi5BeGlidWdQcm90",
"b2J1Zi5EZXZpY2VUeXBlEg8KB0FjY291bnQYAyABKAkSEAoIUGFzc3dvcmQY",
"BCABKAkifwoTUHJvdG9idWZfTG9naW5fUkVTUBINCgVUb2tlbhgBIAEoCRIV",
"Cg1MYXN0TG9naW5EYXRlGAIgASgJEg8KB1JlZ0RhdGUYAyABKAkSMQoGU3Rh",
"dHVzGAQgASgOMiEuQXhpYnVnUHJvdG9idWYuTG9naW5SZXN1bHRTdGF0dXMi",
"IwoQUHJvdG9idWZfQ2hhdE1zZxIPCgdDaGF0TXNnGAEgASgJIkgKFVByb3Rv",
"YnVmX0NoYXRNc2dfUkVTUBIQCghOaWNrTmFtZRgBIAEoCRIPCgdDaGF0TXNn",
"GAIgASgJEgwKBERhdGUYAyABKAMqnAEKCUNvbW1hbmRJRBIOCgpDTURfREVG",
"QVVMEAASDgoJQ01EX0xPR0lOENAPEhAKC0NNRF9DSEFUTVNHEKAfEhgKE0NN",
"RF9VU0VSX09OTElORUxJU1QQiCcSEgoNQ01EX1VTRVJfSk9JThCnJxITCg5D",
"TURfVVNFUl9MRUFWRRCoJxIaChVDTURfVVNFUl9TVEFURV9VUERBVEUQqScq",
"KwoJRXJyb3JDb2RlEhAKDEVSUk9SX0RFRkFVTBAAEgwKCEVSUk9SX09LEAEq",
"PgoJTG9naW5UeXBlEg8KC0Jhc2VEZWZhdWx0EAASDgoKSGFvWXVlQXV0aBAB",
"EgcKA0JGMxADEgcKA0JGNBAEKksKCkRldmljZVR5cGUSFgoSRGV2aWNlVHlw",
"ZV9EZWZhdWx0EAASBgoCUEMQARILCgdBbmRyb2lkEAISBwoDSU9TEAMSBwoD",
"UFNWEAQqTgoRTG9naW5SZXN1bHRTdGF0dXMSIQodTG9naW5SZXN1bHRTdGF0",
"dXNfQmFzZURlZmF1bHQQABIGCgJPSxABEg4KCkFjY291bnRFcnIQAkICSAFi",
"BnByb3RvMw=="));
"BCABKAkingEKE1Byb3RvYnVmX0xvZ2luX1JFU1ASDQoFVG9rZW4YASABKAkS",
"FQoNTGFzdExvZ2luRGF0ZRgCIAEoCRIPCgdSZWdEYXRlGAMgASgJEjEKBlN0",
"YXR1cxgEIAEoDjIhLkF4aWJ1Z1Byb3RvYnVmLkxvZ2luUmVzdWx0U3RhdHVz",
"EgsKA1VJRBgFIAEoAxIQCghOaWNrTmFtZRgGIAEoCSIjChBQcm90b2J1Zl9D",
"aGF0TXNnEg8KB0NoYXRNc2cYASABKAkiSAoVUHJvdG9idWZfQ2hhdE1zZ19S",
"RVNQEhAKCE5pY2tOYW1lGAEgASgJEg8KB0NoYXRNc2cYAiABKAkSDAoERGF0",
"ZRgDIAEoAyrqAgoJQ29tbWFuZElEEg4KCkNNRF9ERUZBVUwQABIOCglDTURf",
"TE9HSU4Q0A8SEAoLQ01EX0NIQVRNU0cQoB8SGAoTQ01EX1VTRVJfT05MSU5F",
"TElTVBCIJxISCg1DTURfVVNFUl9KT0lOEKcnEhMKDkNNRF9VU0VSX0xFQVZF",
"EKgnEhoKFUNNRF9VU0VSX1NUQVRFX1VQREFURRCpJxIYChNDTURfVENQVFVO",
"TkVMX0hFTExPEIknEhUKEENNRF9UQ1BUVU5ORUxfRE8QiicSFQoQQ01EX1RD",
"UF9QMlBfQ0hBVBCRThIhChxDTURfVENQX1AyUF9GSUxFUFVTSF9DT05GSVJN",
"EPlVEiYKIUNNRF9UQ1BfUDJQX0ZJTEVQVVNIX0NPTkZJUk1fUkVTUBD6VRIZ",
"ChRDTURfVENQX1AyUF9GSUxFUFVTSBD7VRIeChlDTURfVENQX1AyUF9GSUxF",
"UFVTSF9SRVNQEPxVKj4KCUVycm9yQ29kZRIQCgxFUlJPUl9ERUZBVUwQABIM",
"CghFUlJPUl9PSxABEhEKDUVSUk9SX05PVEZJTkQQZCo+CglMb2dpblR5cGUS",
"DwoLQmFzZURlZmF1bHQQABIOCgpIYW9ZdWVBdXRoEAESBwoDQkYzEAMSBwoD",
"QkY0EAQqSwoKRGV2aWNlVHlwZRIWChJEZXZpY2VUeXBlX0RlZmF1bHQQABIG",
"CgJQQxABEgsKB0FuZHJvaWQQAhIHCgNJT1MQAxIHCgNQU1YQBCpOChFMb2dp",
"blJlc3VsdFN0YXR1cxIhCh1Mb2dpblJlc3VsdFN0YXR1c19CYXNlRGVmYXVs",
"dBAAEgYKAk9LEAESDgoKQWNjb3VudEVychACQgJIAWIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::AxibugProtobuf.CommandID), typeof(global::AxibugProtobuf.ErrorCode), typeof(global::AxibugProtobuf.LoginType), typeof(global::AxibugProtobuf.DeviceType), typeof(global::AxibugProtobuf.LoginResultStatus), }, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_Login), global::AxibugProtobuf.Protobuf_Login.Parser, new[]{ "LoginType", "DeviceType", "Account", "Password" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_Login_RESP), global::AxibugProtobuf.Protobuf_Login_RESP.Parser, new[]{ "Token", "LastLoginDate", "RegDate", "Status" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_Login_RESP), global::AxibugProtobuf.Protobuf_Login_RESP.Parser, new[]{ "Token", "LastLoginDate", "RegDate", "Status", "UID", "NickName" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_ChatMsg), global::AxibugProtobuf.Protobuf_ChatMsg.Parser, new[]{ "ChatMsg" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_ChatMsg_RESP), global::AxibugProtobuf.Protobuf_ChatMsg_RESP.Parser, new[]{ "NickName", "ChatMsg", "Date" }, null, null, null, null)
}));
@ -86,6 +91,34 @@ namespace AxibugProtobuf {
///更新在线用户状态 下行 对应 Protobuf_UserState_RESP
/// </summary>
[pbr::OriginalName("CMD_USER_STATE_UPDATE")] CmdUserStateUpdate = 5033,
/// <summary>
///TCP打洞请求 上行 | 下行 对应 Protobuf_TcpTunnel_HellToSev | Protobuf_TcpTunnel_HellToSev_RESP
/// </summary>
[pbr::OriginalName("CMD_TCPTUNNEL_HELLO")] CmdTcptunnelHello = 5001,
/// <summary>
///TCP打洞请求 下行 对应 Protobuf_TcpTunnel_DoTunnel | Protobuf_TcpTunnel_DoTunnel_RESP
/// </summary>
[pbr::OriginalName("CMD_TCPTUNNEL_DO")] CmdTcptunnelDo = 5002,
/// <summary>
///TCPP2P聊天 Protobuf_TcpP2P_Chat
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_CHAT")] CmdTcpP2PChat = 10001,
/// <summary>
///TCPP2P 文件传输上下行分开
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH_CONFIRM")] CmdTcpP2PFilepushConfirm = 11001,
/// <summary>
///TCPP2文件传输 下行 对应 Protobuf_TcpP2P_FilePushConfirm_RESP
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH_CONFIRM_RESP")] CmdTcpP2PFilepushConfirmResp = 11002,
/// <summary>
///TCPP2文件传输 过程 上行 对应 Protobuf_TcpP2P_FilePush
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH")] CmdTcpP2PFilepush = 11003,
/// <summary>
///TCPP2文件传输 过程 下行 对应 Protobuf_TcpP2P_FilePush_RESP
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH_RESP")] CmdTcpP2PFilepushResp = 11004,
}
public enum ErrorCode {
@ -97,6 +130,10 @@ namespace AxibugProtobuf {
///成功
/// </summary>
[pbr::OriginalName("ERROR_OK")] ErrorOk = 1,
/// <summary>
///用户不存在
/// </summary>
[pbr::OriginalName("ERROR_NOTFIND")] ErrorNotfind = 100,
}
public enum LoginType {
@ -463,6 +500,8 @@ namespace AxibugProtobuf {
lastLoginDate_ = other.lastLoginDate_;
regDate_ = other.regDate_;
status_ = other.status_;
uID_ = other.uID_;
nickName_ = other.nickName_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@ -527,6 +566,34 @@ namespace AxibugProtobuf {
}
}
/// <summary>Field number for the "UID" field.</summary>
public const int UIDFieldNumber = 5;
private long uID_;
/// <summary>
///UID
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long UID {
get { return uID_; }
set {
uID_ = value;
}
}
/// <summary>Field number for the "NickName" field.</summary>
public const int NickNameFieldNumber = 6;
private string nickName_ = "";
/// <summary>
///昵称
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string NickName {
get { return nickName_; }
set {
nickName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Protobuf_Login_RESP);
@ -544,6 +611,8 @@ namespace AxibugProtobuf {
if (LastLoginDate != other.LastLoginDate) return false;
if (RegDate != other.RegDate) return false;
if (Status != other.Status) return false;
if (UID != other.UID) return false;
if (NickName != other.NickName) return false;
return Equals(_unknownFields, other._unknownFields);
}
@ -554,6 +623,8 @@ namespace AxibugProtobuf {
if (LastLoginDate.Length != 0) hash ^= LastLoginDate.GetHashCode();
if (RegDate.Length != 0) hash ^= RegDate.GetHashCode();
if (Status != global::AxibugProtobuf.LoginResultStatus.BaseDefault) hash ^= Status.GetHashCode();
if (UID != 0L) hash ^= UID.GetHashCode();
if (NickName.Length != 0) hash ^= NickName.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@ -586,6 +657,14 @@ namespace AxibugProtobuf {
output.WriteRawTag(32);
output.WriteEnum((int) Status);
}
if (UID != 0L) {
output.WriteRawTag(40);
output.WriteInt64(UID);
}
if (NickName.Length != 0) {
output.WriteRawTag(50);
output.WriteString(NickName);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
@ -611,6 +690,14 @@ namespace AxibugProtobuf {
output.WriteRawTag(32);
output.WriteEnum((int) Status);
}
if (UID != 0L) {
output.WriteRawTag(40);
output.WriteInt64(UID);
}
if (NickName.Length != 0) {
output.WriteRawTag(50);
output.WriteString(NickName);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
@ -632,6 +719,12 @@ namespace AxibugProtobuf {
if (Status != global::AxibugProtobuf.LoginResultStatus.BaseDefault) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Status);
}
if (UID != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(UID);
}
if (NickName.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(NickName);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
@ -655,6 +748,12 @@ namespace AxibugProtobuf {
if (other.Status != global::AxibugProtobuf.LoginResultStatus.BaseDefault) {
Status = other.Status;
}
if (other.UID != 0L) {
UID = other.UID;
}
if (other.NickName.Length != 0) {
NickName = other.NickName;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@ -685,6 +784,14 @@ namespace AxibugProtobuf {
Status = (global::AxibugProtobuf.LoginResultStatus) input.ReadEnum();
break;
}
case 40: {
UID = input.ReadInt64();
break;
}
case 50: {
NickName = input.ReadString();
break;
}
}
}
#endif
@ -715,6 +822,14 @@ namespace AxibugProtobuf {
Status = (global::AxibugProtobuf.LoginResultStatus) input.ReadEnum();
break;
}
case 40: {
UID = input.ReadInt64();
break;
}
case 50: {
NickName = input.ReadString();
break;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -28,27 +28,32 @@ namespace AxibugProtobuf {
"dG9idWZfTG9naW4SLAoJbG9naW5UeXBlGAEgASgOMhkuQXhpYnVnUHJvdG9i",
"dWYuTG9naW5UeXBlEi4KCmRldmljZVR5cGUYAiABKA4yGi5BeGlidWdQcm90",
"b2J1Zi5EZXZpY2VUeXBlEg8KB0FjY291bnQYAyABKAkSEAoIUGFzc3dvcmQY",
"BCABKAkifwoTUHJvdG9idWZfTG9naW5fUkVTUBINCgVUb2tlbhgBIAEoCRIV",
"Cg1MYXN0TG9naW5EYXRlGAIgASgJEg8KB1JlZ0RhdGUYAyABKAkSMQoGU3Rh",
"dHVzGAQgASgOMiEuQXhpYnVnUHJvdG9idWYuTG9naW5SZXN1bHRTdGF0dXMi",
"IwoQUHJvdG9idWZfQ2hhdE1zZxIPCgdDaGF0TXNnGAEgASgJIkgKFVByb3Rv",
"YnVmX0NoYXRNc2dfUkVTUBIQCghOaWNrTmFtZRgBIAEoCRIPCgdDaGF0TXNn",
"GAIgASgJEgwKBERhdGUYAyABKAMqnAEKCUNvbW1hbmRJRBIOCgpDTURfREVG",
"QVVMEAASDgoJQ01EX0xPR0lOENAPEhAKC0NNRF9DSEFUTVNHEKAfEhgKE0NN",
"RF9VU0VSX09OTElORUxJU1QQiCcSEgoNQ01EX1VTRVJfSk9JThCnJxITCg5D",
"TURfVVNFUl9MRUFWRRCoJxIaChVDTURfVVNFUl9TVEFURV9VUERBVEUQqScq",
"KwoJRXJyb3JDb2RlEhAKDEVSUk9SX0RFRkFVTBAAEgwKCEVSUk9SX09LEAEq",
"PgoJTG9naW5UeXBlEg8KC0Jhc2VEZWZhdWx0EAASDgoKSGFvWXVlQXV0aBAB",
"EgcKA0JGMxADEgcKA0JGNBAEKksKCkRldmljZVR5cGUSFgoSRGV2aWNlVHlw",
"ZV9EZWZhdWx0EAASBgoCUEMQARILCgdBbmRyb2lkEAISBwoDSU9TEAMSBwoD",
"UFNWEAQqTgoRTG9naW5SZXN1bHRTdGF0dXMSIQodTG9naW5SZXN1bHRTdGF0",
"dXNfQmFzZURlZmF1bHQQABIGCgJPSxABEg4KCkFjY291bnRFcnIQAkICSAFi",
"BnByb3RvMw=="));
"BCABKAkingEKE1Byb3RvYnVmX0xvZ2luX1JFU1ASDQoFVG9rZW4YASABKAkS",
"FQoNTGFzdExvZ2luRGF0ZRgCIAEoCRIPCgdSZWdEYXRlGAMgASgJEjEKBlN0",
"YXR1cxgEIAEoDjIhLkF4aWJ1Z1Byb3RvYnVmLkxvZ2luUmVzdWx0U3RhdHVz",
"EgsKA1VJRBgFIAEoAxIQCghOaWNrTmFtZRgGIAEoCSIjChBQcm90b2J1Zl9D",
"aGF0TXNnEg8KB0NoYXRNc2cYASABKAkiSAoVUHJvdG9idWZfQ2hhdE1zZ19S",
"RVNQEhAKCE5pY2tOYW1lGAEgASgJEg8KB0NoYXRNc2cYAiABKAkSDAoERGF0",
"ZRgDIAEoAyrqAgoJQ29tbWFuZElEEg4KCkNNRF9ERUZBVUwQABIOCglDTURf",
"TE9HSU4Q0A8SEAoLQ01EX0NIQVRNU0cQoB8SGAoTQ01EX1VTRVJfT05MSU5F",
"TElTVBCIJxISCg1DTURfVVNFUl9KT0lOEKcnEhMKDkNNRF9VU0VSX0xFQVZF",
"EKgnEhoKFUNNRF9VU0VSX1NUQVRFX1VQREFURRCpJxIYChNDTURfVENQVFVO",
"TkVMX0hFTExPEIknEhUKEENNRF9UQ1BUVU5ORUxfRE8QiicSFQoQQ01EX1RD",
"UF9QMlBfQ0hBVBCRThIhChxDTURfVENQX1AyUF9GSUxFUFVTSF9DT05GSVJN",
"EPlVEiYKIUNNRF9UQ1BfUDJQX0ZJTEVQVVNIX0NPTkZJUk1fUkVTUBD6VRIZ",
"ChRDTURfVENQX1AyUF9GSUxFUFVTSBD7VRIeChlDTURfVENQX1AyUF9GSUxF",
"UFVTSF9SRVNQEPxVKj4KCUVycm9yQ29kZRIQCgxFUlJPUl9ERUZBVUwQABIM",
"CghFUlJPUl9PSxABEhEKDUVSUk9SX05PVEZJTkQQZCo+CglMb2dpblR5cGUS",
"DwoLQmFzZURlZmF1bHQQABIOCgpIYW9ZdWVBdXRoEAESBwoDQkYzEAMSBwoD",
"QkY0EAQqSwoKRGV2aWNlVHlwZRIWChJEZXZpY2VUeXBlX0RlZmF1bHQQABIG",
"CgJQQxABEgsKB0FuZHJvaWQQAhIHCgNJT1MQAxIHCgNQU1YQBCpOChFMb2dp",
"blJlc3VsdFN0YXR1cxIhCh1Mb2dpblJlc3VsdFN0YXR1c19CYXNlRGVmYXVs",
"dBAAEgYKAk9LEAESDgoKQWNjb3VudEVychACQgJIAWIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::AxibugProtobuf.CommandID), typeof(global::AxibugProtobuf.ErrorCode), typeof(global::AxibugProtobuf.LoginType), typeof(global::AxibugProtobuf.DeviceType), typeof(global::AxibugProtobuf.LoginResultStatus), }, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_Login), global::AxibugProtobuf.Protobuf_Login.Parser, new[]{ "LoginType", "DeviceType", "Account", "Password" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_Login_RESP), global::AxibugProtobuf.Protobuf_Login_RESP.Parser, new[]{ "Token", "LastLoginDate", "RegDate", "Status" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_Login_RESP), global::AxibugProtobuf.Protobuf_Login_RESP.Parser, new[]{ "Token", "LastLoginDate", "RegDate", "Status", "UID", "NickName" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_ChatMsg), global::AxibugProtobuf.Protobuf_ChatMsg.Parser, new[]{ "ChatMsg" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::AxibugProtobuf.Protobuf_ChatMsg_RESP), global::AxibugProtobuf.Protobuf_ChatMsg_RESP.Parser, new[]{ "NickName", "ChatMsg", "Date" }, null, null, null, null)
}));
@ -86,6 +91,34 @@ namespace AxibugProtobuf {
///更新在线用户状态 下行 对应 Protobuf_UserState_RESP
/// </summary>
[pbr::OriginalName("CMD_USER_STATE_UPDATE")] CmdUserStateUpdate = 5033,
/// <summary>
///TCP打洞请求 上行 | 下行 对应 Protobuf_TcpTunnel_HellToSev | Protobuf_TcpTunnel_HellToSev_RESP
/// </summary>
[pbr::OriginalName("CMD_TCPTUNNEL_HELLO")] CmdTcptunnelHello = 5001,
/// <summary>
///TCP打洞请求 下行 对应 Protobuf_TcpTunnel_DoTunnel | Protobuf_TcpTunnel_DoTunnel_RESP
/// </summary>
[pbr::OriginalName("CMD_TCPTUNNEL_DO")] CmdTcptunnelDo = 5002,
/// <summary>
///TCPP2P聊天 Protobuf_TcpP2P_Chat
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_CHAT")] CmdTcpP2PChat = 10001,
/// <summary>
///TCPP2P 文件传输上下行分开
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH_CONFIRM")] CmdTcpP2PFilepushConfirm = 11001,
/// <summary>
///TCPP2文件传输 下行 对应 Protobuf_TcpP2P_FilePushConfirm_RESP
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH_CONFIRM_RESP")] CmdTcpP2PFilepushConfirmResp = 11002,
/// <summary>
///TCPP2文件传输 过程 上行 对应 Protobuf_TcpP2P_FilePush
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH")] CmdTcpP2PFilepush = 11003,
/// <summary>
///TCPP2文件传输 过程 下行 对应 Protobuf_TcpP2P_FilePush_RESP
/// </summary>
[pbr::OriginalName("CMD_TCP_P2P_FILEPUSH_RESP")] CmdTcpP2PFilepushResp = 11004,
}
public enum ErrorCode {
@ -97,6 +130,10 @@ namespace AxibugProtobuf {
///成功
/// </summary>
[pbr::OriginalName("ERROR_OK")] ErrorOk = 1,
/// <summary>
///用户不存在
/// </summary>
[pbr::OriginalName("ERROR_NOTFIND")] ErrorNotfind = 100,
}
public enum LoginType {
@ -463,6 +500,8 @@ namespace AxibugProtobuf {
lastLoginDate_ = other.lastLoginDate_;
regDate_ = other.regDate_;
status_ = other.status_;
uID_ = other.uID_;
nickName_ = other.nickName_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@ -527,6 +566,34 @@ namespace AxibugProtobuf {
}
}
/// <summary>Field number for the "UID" field.</summary>
public const int UIDFieldNumber = 5;
private long uID_;
/// <summary>
///UID
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long UID {
get { return uID_; }
set {
uID_ = value;
}
}
/// <summary>Field number for the "NickName" field.</summary>
public const int NickNameFieldNumber = 6;
private string nickName_ = "";
/// <summary>
///昵称
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string NickName {
get { return nickName_; }
set {
nickName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Protobuf_Login_RESP);
@ -544,6 +611,8 @@ namespace AxibugProtobuf {
if (LastLoginDate != other.LastLoginDate) return false;
if (RegDate != other.RegDate) return false;
if (Status != other.Status) return false;
if (UID != other.UID) return false;
if (NickName != other.NickName) return false;
return Equals(_unknownFields, other._unknownFields);
}
@ -554,6 +623,8 @@ namespace AxibugProtobuf {
if (LastLoginDate.Length != 0) hash ^= LastLoginDate.GetHashCode();
if (RegDate.Length != 0) hash ^= RegDate.GetHashCode();
if (Status != global::AxibugProtobuf.LoginResultStatus.BaseDefault) hash ^= Status.GetHashCode();
if (UID != 0L) hash ^= UID.GetHashCode();
if (NickName.Length != 0) hash ^= NickName.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@ -586,6 +657,14 @@ namespace AxibugProtobuf {
output.WriteRawTag(32);
output.WriteEnum((int) Status);
}
if (UID != 0L) {
output.WriteRawTag(40);
output.WriteInt64(UID);
}
if (NickName.Length != 0) {
output.WriteRawTag(50);
output.WriteString(NickName);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
@ -611,6 +690,14 @@ namespace AxibugProtobuf {
output.WriteRawTag(32);
output.WriteEnum((int) Status);
}
if (UID != 0L) {
output.WriteRawTag(40);
output.WriteInt64(UID);
}
if (NickName.Length != 0) {
output.WriteRawTag(50);
output.WriteString(NickName);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
@ -632,6 +719,12 @@ namespace AxibugProtobuf {
if (Status != global::AxibugProtobuf.LoginResultStatus.BaseDefault) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Status);
}
if (UID != 0L) {
size += 1 + pb::CodedOutputStream.ComputeInt64Size(UID);
}
if (NickName.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(NickName);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
@ -655,6 +748,12 @@ namespace AxibugProtobuf {
if (other.Status != global::AxibugProtobuf.LoginResultStatus.BaseDefault) {
Status = other.Status;
}
if (other.UID != 0L) {
UID = other.UID;
}
if (other.NickName.Length != 0) {
NickName = other.NickName;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@ -685,6 +784,14 @@ namespace AxibugProtobuf {
Status = (global::AxibugProtobuf.LoginResultStatus) input.ReadEnum();
break;
}
case 40: {
UID = input.ReadInt64();
break;
}
case 50: {
NickName = input.ReadString();
break;
}
}
}
#endif
@ -715,6 +822,14 @@ namespace AxibugProtobuf {
Status = (global::AxibugProtobuf.LoginResultStatus) input.ReadEnum();
break;
}
case 40: {
UID = input.ReadInt64();
break;
}
case 50: {
NickName = input.ReadString();
break;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -15,15 +15,23 @@ enum CommandID
CMD_USER_LEAVE = 5032; //线 Protobuf_UserOffline_RESP
CMD_USER_STATE_UPDATE = 5033; //线 Protobuf_UserState_RESP
//CMD_TUNNEL_UDPSERVER_INFO = 6000; //UDP服务器信息 | Protobuf_UDPServer_Info | Protobuf_UDPServer_Info_RESP
//CMD_TUNNEL_2Server_OK = 6001; //UDP建立连接 Protobuf_MakeTunnel_RESP
//CMD_TUNNEL_MAKE = 6002; // | Protobuf_MakeTunnel | Protobuf_MakeTunnel_RESP
CMD_TCPTUNNEL_HELLO = 5001; //TCP打洞请求 | Protobuf_TcpTunnel_HellToSev | Protobuf_TcpTunnel_HellToSev_RESP
CMD_TCPTUNNEL_DO = 5002; //TCP打洞请求 Protobuf_TcpTunnel_DoTunnel | Protobuf_TcpTunnel_DoTunnel_RESP
CMD_TCP_P2P_CHAT = 10001; //TCPP2P聊天 Protobuf_TcpP2P_Chat
//TCPP2P
CMD_TCP_P2P_FILEPUSH_CONFIRM = 11001; //TCPP2文件传输 Protobuf_TcpP2P_FilePushConfirm
CMD_TCP_P2P_FILEPUSH_CONFIRM_RESP = 11002; //TCPP2文件传输 Protobuf_TcpP2P_FilePushConfirm_RESP
CMD_TCP_P2P_FILEPUSH = 11003; //TCPP2文件传输 Protobuf_TcpP2P_FilePush
CMD_TCP_P2P_FILEPUSH_RESP = 11004; //TCPP2文件传输 Protobuf_TcpP2P_FilePush_RESP
}
enum ErrorCode
{
ERROR_DEFAUL = 0;//使
ERROR_OK = 1; //
ERROR_NOTFIND = 100; //
}
enum LoginType
@ -66,6 +74,8 @@ message Protobuf_Login_RESP
string LastLoginDate = 2;//
string RegDate = 3;//
LoginResultStatus Status = 4;// [1][0]
int64 UID = 5;//UID
string NickName = 6;//
}

View File

@ -0,0 +1,77 @@
syntax = "proto3";
package AxibugProtobuf;
option optimize_for = SPEED;
//Tcp打洞请求
message Protobuf_TcpTunnel_HellToSev
{
int64 UID = 1;//UID
}
//Tcp打洞请求
message Protobuf_TcpTunnel_HellToSev_RESP
{
}
//Tcp打洞请求
message Protobuf_TcpTunnel_DoTunnel
{
int64 UID = 1;//UID
int64 targetUID = 2;//UID
}
//
message Protobuf_TcpTunnel_DoTunnel_RESP
{
int64 targetUID = 1;//UID
string myIP = 2;//IP
int32 myPort = 3;//Port
string otherIP = 4;//IP
int32 otherPort = 5;//Port
}
////////////////////////////TCP P2P聊天//////////////////
//TCPP2P聊天
message Protobuf_TcpP2P_Chat
{
string ChatMsg = 1;//
}
////////////////////////////TCP P2P文件传输//////////////////
//TCPP2P文件传输
message Protobuf_TcpP2P_FilePushConfirm
{
int64 FileLenght = 1;//
string ContentType = 2;//ContentType
string FileName = 3;//
int32 TaskID = 4;//ID
int32 PackSize = 5;//
int64 PackCount = 6;//
string FileHash = 7;//hash
}
message Protobuf_TcpP2P_FilePushConfirm_RESP
{
int32 TaskID = 1;//ID
int32 Agree = 2;//[0] [1]
}
//TCPP2P文件传输
message Protobuf_TcpP2P_FilePush
{
int32 TaskID = 1;//ID
int64 PackIndex = 2;//
bytes File_Data = 3;//
int32 PackLenght = 4;//
}
message Protobuf_TcpP2P_FilePush_RESP
{
int32 TaskID = 1;//ID
int64 FinishIndex = 2;//
}

View File

@ -1,6 +1,7 @@
using ServerCore.Manager;
ServerManager.InitServer(23846);
Console.ForegroundColor = ConsoleColor.Green;
ServerManager.InitServer(23846, 23847);
while (true)
{
@ -12,6 +13,9 @@ while (true)
case "list":
Console.WriteLine("当前在线:" + ServerManager.g_ClientMgr.GetOnlineClientCount());
break;
case "tlist":
Console.WriteLine("当前TcpTunnel在线:" + ServerManager.g_TcpTunnelMgr.GetOnlineClientCount());
break;
default:
Console.WriteLine("未知命令" + CommandStr);
break;

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerCore.Common.Enum
{
public enum ServerType
{
MainServer,
TcpTunnelServer
}
}

View File

@ -10,6 +10,10 @@ namespace ServerCore.Event
{
// 添加你自己需要的事件类型
OnUserJoin,
OnUserLeave
OnUserLeave,
//连接管理
OnSocketDisconnect,
}
}

View File

@ -1,4 +1,5 @@
using AxibugProtobuf;
using ServerCore.Common.Enum;
using ServerCore.Event;
using System.Net.Sockets;
using System.Timers;
@ -26,40 +27,51 @@ namespace ServerCore.Manager
private long _RemoveOfflineCacheMin;
public ClientManager()
{
//事件
EventSystem.Instance.RegisterEvent<ServerType,Socket>(EEvent.OnSocketDisconnect, OnSocketDisconnect);
}
#region
void OnSocketDisconnect(ServerType serverType, Socket socket)
{
if (serverType != ServerType.MainServer)
return;
RemoveClientBySocket(socket);
}
#endregion
public void Init(long ticktime, long RemoveOfflineCacheMin)
{
//换算成毫秒
_RemoveOfflineCacheMin = RemoveOfflineCacheMin * 1000;
_ClientCheckTimer = new System.Timers.Timer();
_ClientCheckTimer.Interval = ticktime;
_ClientCheckTimer.AutoReset = true;
_ClientCheckTimer.Elapsed += new ElapsedEventHandler(ClientCheckClearOffline_Elapsed);
_ClientCheckTimer.Enabled = true;
}
//public void Init(long ticktime, long RemoveOfflineCacheMin)
//{
// //换算成毫秒
// _RemoveOfflineCacheMin = RemoveOfflineCacheMin * 1000;
// _ClientCheckTimer = new System.Timers.Timer();
// _ClientCheckTimer.Interval = ticktime;
// _ClientCheckTimer.AutoReset = true;
// _ClientCheckTimer.Elapsed += new ElapsedEventHandler(ClientCheckClearOffline_Elapsed);
// _ClientCheckTimer.Enabled = true;
//}
public long GetNextUID()
{
return ++TestUIDSeed;
}
private void ClientCheckClearOffline_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime CheckDT = DateTime.Now.AddMinutes(-1 * _RemoveOfflineCacheMin);
ClientInfo[] OfflineClientlist = ClientList.Where(w => w.IsOffline == true && w.LogOutDT < CheckDT).ToArray();
//private void ClientCheckClearOffline_Elapsed(object sender, ElapsedEventArgs e)
//{
// DateTime CheckDT = DateTime.Now.AddMinutes(-1 * _RemoveOfflineCacheMin);
// ClientInfo[] OfflineClientlist = ClientList.Where(w => w.IsOffline == true && w.LogOutDT < CheckDT).ToArray();
Console.WriteLine("开始清理离线过久的玩家的缓存");
for (int i = 0; i < OfflineClientlist.Length; i++)
{
//to do 掉线处理
RemoveClient(OfflineClientlist[i]);
}
GC.Collect();
}
// Console.WriteLine("开始清理离线过久的玩家的缓存");
// for (int i = 0; i < OfflineClientlist.Length; i++)
// {
// //to do 掉线处理
// RemoveClient(OfflineClientlist[i]);
// }
// GC.Collect();
//}
//通用处理
@ -118,6 +130,8 @@ namespace ServerCore.Manager
/// <param name="client"></param>
public void RemoveClient(ClientInfo client)
{
EventSystem.Instance.PostEvent(EEvent.OnUserLeave, client.UID);
lock (ClientList)
{
if (_DictUIDClient.ContainsKey(client.UID))
@ -150,22 +164,21 @@ namespace ServerCore.Manager
}
/// <summary>
/// 设置玩家离线
/// </summary>
/// <param name="sk"></param>
public void SetClientOfflineForSocket(Socket sk)
{
if (!_DictSocketClient.ContainsKey(sk))
return;
///// <summary>
///// 设置玩家离线
///// </summary>
///// <param name="sk"></param>
//public void SetClientOfflineForSocket(Socket sk)
//{
// if (!_DictSocketClient.ContainsKey(sk))
// return;
// Console.WriteLine("标记玩家UID" + _DictSocketClient[sk].UID + "为离线");
// _DictSocketClient[sk].IsOffline = true;
// _DictSocketClient[sk].LogOutDT = DateTime.Now;
// EventSystem.Instance.PostEvent(EEvent.OnUserLeave, _DictSocketClient[sk].UID);
//}
Console.WriteLine("标记玩家UID" + _DictSocketClient[sk].UID + "为离线");
_DictSocketClient[sk].IsOffline = true;
_DictSocketClient[sk].LogOutDT = DateTime.Now;
EventSystem.Instance.PostEvent(EEvent.OnUserLeave, _DictSocketClient[sk].UID);
}
public void RemoveClientForSocket(Socket sk)
public void RemoveClientBySocket(Socket sk)
{
if (!_DictSocketClient.ContainsKey(sk))
return;

View File

@ -23,7 +23,9 @@ namespace ServerCore.Manager
Status = LoginResultStatus.Ok,
RegDate = "",
LastLoginDate = "",
Token = ""
Token = "",
UID = cinfo.UID,
NickName= cinfo.NickName,
});
ServerManager.g_ClientMgr.ClientSend(cinfo, (int)CommandID.CmdLogin, (int)ErrorCode.ErrorOk, respData);

View File

@ -10,20 +10,28 @@ namespace ServerCore.Manager
public static LogManager g_Log;
public static LoginManager g_Login;
public static ChatManager g_Chat;
public static P2PUserManager g_P2PMgr;
public static UserManager g_UserMgr;
public static TcpTunnelClientManager g_TcpTunnelMgr;
public static IOCPNetWork g_SocketMgr;
public static IOCPNetWork g_SocketTcpTunnelMgr;
public static void InitServer(int port)
public static void InitServer(int port, int tcptunnelport)
{
g_ClientMgr = new ClientManager();
//g_ClientMgr.Init(10000, 10000);
g_Log = new LogManager();
g_Login = new LoginManager();
g_Chat = new ChatManager();
g_P2PMgr = new P2PUserManager();
g_SocketMgr = new IOCPNetWork(1024, 1024);
g_UserMgr = new UserManager();
g_TcpTunnelMgr = new TcpTunnelClientManager();
g_SocketMgr = new IOCPNetWork(1024, 1024,Common.Enum.ServerType.MainServer);
g_SocketMgr.Init();
g_SocketMgr.Start(new IPEndPoint(IPAddress.Any.Address, port));
Console.WriteLine("监听:" + port);
g_SocketMgr.Start(new IPEndPoint(IPAddress.Any.Address, port));
g_SocketTcpTunnelMgr = new IOCPNetWork(1024, 1024, Common.Enum.ServerType.TcpTunnelServer);
g_SocketTcpTunnelMgr.Init();
g_SocketTcpTunnelMgr.Start(new IPEndPoint(IPAddress.Any.Address, tcptunnelport));
Console.WriteLine("监听:" + tcptunnelport);
Console.WriteLine("Succeed!");
}
}

View File

@ -0,0 +1,175 @@
using AxibugProtobuf;
using ServerCore.Common;
using ServerCore.Common.Enum;
using ServerCore.Event;
using ServerCore.NetWork;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Timers;
using static System.Runtime.CompilerServices.RuntimeHelpers;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace ServerCore.Manager
{
public class TCPTunnelClientInfo
{
public long UID { get; set; }
public string IP { get; set; }
public int Port { get; set; }
public Socket _Socket { get; set; }
}
public class TcpTunnelClientManager
{
private System.Timers.Timer _ClientCheckTimer;
private long _RemoveOfflineCacheMin;
public TcpTunnelClientManager()
{
//消息注册
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcptunnelHello, TcpTunnelHello);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdTcptunnelDo, TcptunnelDo);
//事件注册
EventSystem.Instance.RegisterEvent<ServerType, Socket>(EEvent.OnSocketDisconnect, OnSocketDisconnect);
}
private Dictionary<long, TCPTunnelClientInfo> _DictUID2Client = new Dictionary<long, TCPTunnelClientInfo>();
private Dictionary<Socket, TCPTunnelClientInfo> _DictScoket2Client = new Dictionary<Socket, TCPTunnelClientInfo>();
#region
void OnSocketDisconnect(ServerType serverType, Socket socket)
{
if (serverType != ServerType.TcpTunnelServer)
return;
RemoveClientBySocket(socket);
}
#endregion
void AddClient(long UID,Socket _socket)
{
IPEndPoint ipEndPoint = (IPEndPoint)_socket.RemoteEndPoint;
if (!_DictUID2Client.ContainsKey(UID))
{
TCPTunnelClientInfo cinfo = new TCPTunnelClientInfo()
{
UID = UID,
IP = ipEndPoint.Address.ToString(),
Port = ipEndPoint.Port,
_Socket = _socket
};
_DictScoket2Client[_socket] = cinfo;
_DictUID2Client[UID] = cinfo;
}
else
{
_DictUID2Client[UID].UID = UID;
_DictUID2Client[UID].IP = ipEndPoint.Address.ToString();
_DictUID2Client[UID].Port = ipEndPoint.Port;
_DictUID2Client[UID]._Socket = _socket;
_DictScoket2Client[_socket] = _DictUID2Client[UID];
}
}
void RemoveClient(long UID)
{
if (_DictUID2Client.ContainsKey(UID))
{
_DictScoket2Client.Remove(_DictUID2Client[UID]._Socket);
_DictUID2Client.Remove(UID);
}
}
void RemoveClientBySocket(Socket _socket)
{
if (_DictScoket2Client.ContainsKey(_socket))
{
RemoveClient(_DictScoket2Client[_socket].UID);
}
}
TCPTunnelClientInfo GetClient(long UID)
{
if (_DictUID2Client.ContainsKey(UID))
{
return _DictUID2Client[UID];
}
else
return null;
}
public void TcpTunnelHello(Socket _socket, byte[] reqData)
{
ServerManager.g_Log.Debug("收到TcpTunnel 打洞端口Hello");
Protobuf_TcpTunnel_HellToSev msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpTunnel_HellToSev>(reqData);
AddClient(msg.UID, _socket);
Protobuf_TcpTunnel_HellToSev_RESP resp = new Protobuf_TcpTunnel_HellToSev_RESP();
ClientSend(msg.UID, (int)CommandID.CmdTcptunnelHello, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(resp));
}
public void TcptunnelDo(Socket _socket, byte[] reqData)
{
ServerManager.g_Log.Debug("收到TcpTunnel 打洞端口Hello");
Protobuf_TcpTunnel_DoTunnel msg = ProtoBufHelper.DeSerizlize<Protobuf_TcpTunnel_DoTunnel>(reqData);
TCPTunnelClientInfo Other = GetClient(msg.TargetUID);
if (Other == null || msg.UID == msg.TargetUID)
{
Protobuf_TcpTunnel_DoTunnel_RESP respToErr = new Protobuf_TcpTunnel_DoTunnel_RESP();
ClientSend(msg.UID, (int)CommandID.CmdTcptunnelDo, (int)ErrorCode.ErrorNotfind, ProtoBufHelper.Serizlize(respToErr));
return;
}
//发给自己
TCPTunnelClientInfo mine = GetClient(msg.UID);
Protobuf_TcpTunnel_DoTunnel_RESP respToMine = new Protobuf_TcpTunnel_DoTunnel_RESP()
{
MyIP = mine.IP,
MyPort = mine.Port,
OtherIP = Other.IP,
OtherPort= Other.Port,
TargetUID = msg.TargetUID,
};
ClientSend(msg.UID, (int)CommandID.CmdTcptunnelDo, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(respToMine));
//发给对方
Protobuf_TcpTunnel_DoTunnel_RESP respToOther = new Protobuf_TcpTunnel_DoTunnel_RESP()
{
MyIP = Other.IP,
MyPort = Other.Port,
OtherIP = mine.IP,
OtherPort = mine.Port,
TargetUID = msg.UID,
};
ClientSend(msg.TargetUID, (int)CommandID.CmdTcptunnelDo, (int)ErrorCode.ErrorOk, ProtoBufHelper.Serizlize(respToOther));
//TODO 暂时服务器不断开,交由客户端收到后主动断开
//断开两边
//mine._Socket.Close();
//TCPTunnelClientInfo other = GetClient(msg.TargetUID);
//other._Socket.Close();
}
/// <summary>
///
/// </summary>
/// <param name="UID"></param>
/// <param name="CMDID"></param>
/// <param name="ERRCODE"></param>
/// <param name="data"></param>
public void ClientSend(long UID, int CMDID, int ERRCODE, byte[] data)
{
if (_DictUID2Client.ContainsKey(UID))
{
ServerManager.g_SocketTcpTunnelMgr.SendToSocket(_DictUID2Client[UID]._Socket, CMDID, ERRCODE, data);
}
}
public int GetOnlineClientCount()
{
return _DictUID2Client.Count();
}
}
}

View File

@ -9,9 +9,9 @@ using System.Timers;
namespace ServerCore.Manager
{
public class P2PUserManager
public class UserManager
{
public P2PUserManager()
public UserManager()
{
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserOnlinelist, RecvGetUserList);
@ -21,7 +21,7 @@ namespace ServerCore.Manager
}
#region
#region
void OnUserJoin(long UID)
{
ServerManager.g_Log.Debug($"P2PUserManager->OnUserJoin UID->{UID}");

View File

@ -1,28 +1,21 @@
using AxibugProtobuf;
using HaoYueNet.ServerNetwork;
using ServerCore.Common.Enum;
using ServerCore.Event;
using ServerCore.Manager;
using System.Net;
using System.Net.Sockets;
namespace ServerCore.NetWork
{
public class IOCPNetWork : SocketManager
{
public IOCPNetWork(int numConnections, int receiveBufferSize)
ServerType mServerType;
public IOCPNetWork(int numConnections, int receiveBufferSize, ServerType serverType)
: base(numConnections, receiveBufferSize)
{
m_clientCount = 0;
m_maxConnectNum = numConnections;
m_revBufferSize = receiveBufferSize;
// allocate buffers such that the maximum number of sockets can have one outstanding read and
//write posted to the socket simultaneously
m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToAlloc, receiveBufferSize);
m_pool = new SocketEventPool(numConnections);
m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
mServerType = serverType;
ClientNumberChange += IOCPNetWork_ClientNumberChange;
}
private void IOCPNetWork_ClientNumberChange(int num, AsyncUserToken token)
@ -38,22 +31,25 @@ namespace ServerCore.NetWork
/// <param name="data">业务数据</param>
public override void DataCallBack(AsyncUserToken token, int CMDID, byte[] data)
{
DataCallBackToOld(token.Socket, CMDID, data);
//DataCallBackToOld(token.Socket, CMDID, data);
ServerManager.g_Log.Debug("收到消息 CMDID =>" + CMDID + " 数据长度=>" + data.Length);
//抛出网络数据
NetMsg.Instance.PostNetMsgEvent(CMDID, token.Socket, data);
}
public void DataCallBackToOld(Socket sk, int CMDID, byte[] data)
{
ServerManager.g_Log.Debug("收到消息 CMDID =>" + CMDID + " 数据长度=>" + data.Length);
try
{
//抛出网络数据
NetMsg.Instance.PostNetMsgEvent(CMDID, sk, data);
}
catch (Exception ex)
{
Console.WriteLine("逻辑处理错误:" + ex.ToString());
}
}
//public void DataCallBackToOld(Socket sk, int CMDID, byte[] data)
//{
// ServerManager.g_Log.Debug("收到消息 CMDID =>" + CMDID + " 数据长度=>" + data.Length);
// try
// {
// //抛出网络数据
// NetMsg.Instance.PostNetMsgEvent(CMDID, sk, data);
// }
// catch (Exception ex)
// {
// Console.WriteLine("逻辑处理错误:" + ex.ToString());
// }
//}
/// <summary>
/// 断开连接
@ -61,18 +57,10 @@ namespace ServerCore.NetWork
/// <param name="sk"></param>
public override void OnClose(AsyncUserToken token)
{
OnCloseToOld(token.Socket);
ServerManager.g_Log.Debug($"断开连接,ServerType->{mServerType} | {((IPEndPoint)token.Socket.LocalEndPoint).Address}");
//ServerManager.g_ClientMgr.SetClientOfflineForSocket(token.Socket);
//TODO 要删除不同的
EventSystem.Instance.PostEvent(EEvent.OnSocketDisconnect, mServerType, token.Socket);
}
/// <summary>
/// 断开连接
/// </summary>
/// <param name="sk"></param>
public void OnCloseToOld(Socket sk)
{
Console.WriteLine("断开连接");
ServerManager.g_ClientMgr.SetClientOfflineForSocket(sk);
}
}
}

View File

@ -65,18 +65,19 @@ namespace ServerCore.NetWork
public void PostNetMsgEvent(int cmd, Socket arg1, byte[] arg2)
{
List<Delegate> eventList = GetNetEventDicList(cmd);
if (eventList != null)
if (eventList == null)
return;
for (int i = 0; i < eventList.Count; i++)
{
foreach (Delegate callback in eventList)
Delegate callback = eventList[i];
try
{
try
{
((Action<Socket, byte[]>)callback)(arg1, arg2);
}
catch (Exception e)
{
ServerManager.g_Log.Error(e.Message);
}
((Action<Socket, byte[]>)callback)(arg1, arg2);
}
catch (Exception e)
{
ServerManager.g_Log.Error(e.Message);
}
}
}