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(EEvent.OnSocketDisconnect, OnSocketDisconnect); } private Dictionary _DictUID2Client = new Dictionary(); private Dictionary _DictScoket2Client = new Dictionary(); #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(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(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(); } /// /// /// /// /// /// /// 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(); } } }