using UnityEngine; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using System.Net; using System; using System.Text; using System.IO; using pb = Google.Protobuf; ///// ///// 聊天部分使用的 ///// //[Obsolete("-g",true)] //public class SocketManager //{ // private static SocketManager _instance; // public static SocketManager Instance // { // get // { // if (_instance == null) // { // _instance = new SocketManager(); // } // return _instance; // } // } // private string _currIP; // private int _currPort; // private bool _isConnected = false; // public bool IsConnceted { get { return _isConnected; } } // private Socket clientSocket = null; // private Thread receiveThread = null; // private DataBuffer _databuffer = new DataBuffer(); // byte[] _tmpReceiveBuff = new byte[4096]; // private sSocketData _socketData = new sSocketData(); // /// // /// 断开 // /// // private void _close() // { // if (!_isConnected) // return; // _isConnected = false; // if (receiveThread != null) // { // receiveThread.Abort(); // receiveThread = null; // } // if (clientSocket != null && clientSocket.Connected) // { // clientSocket.Close(); // clientSocket = null; // } // } // private void _ReConnect() // { // } // /// // /// 连接 // /// // private void _onConnet() // { // try // { // clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建套接字 // IPAddress ipAddress = IPAddress.Parse(_currIP); //解析IP地址 // IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, _currPort); // IAsyncResult result = clientSocket.BeginConnect(ipEndpoint, new AsyncCallback(_onConnect_Sucess), clientSocket);//异步连接 // bool success = result.AsyncWaitHandle.WaitOne(5000, true); // if (!success) //超时 // { // _onConnect_Outtime(); // } // clientSocket.SetKeepAlive(1000); // } // catch (System.Exception _e) // { // _onConnect_Fail(); // } // } // private void _onConnect_Sucess(IAsyncResult iar) // { // try // { // Socket client = (Socket)iar.AsyncState; // client.EndConnect(iar); // receiveThread = new Thread(new ThreadStart(_onReceiveSocket)); // receiveThread.IsBackground = true; // receiveThread.Start(); // _isConnected = true; // LogHelper.Log("连接成功"); // } // catch (Exception _e) // { // Close(); // } // } // private void _onConnect_Outtime() // { // _close(); // } // private void _onConnect_Fail() // { // _close(); // } // /// // /// 发送消息结果回掉,可判断当前网络状态 // /// // /// // private void _onSendMsg(IAsyncResult asyncSend) // { // try // { // Socket client = (Socket)asyncSend.AsyncState; // client.EndSend(asyncSend); // } // catch (Exception e) // { // LogHelper.Log("send msg exception:" + e.StackTrace); // } // } // /// // /// 接受网络数据 // /// // private void _onReceiveSocket() // { // while (true) // { // if (!clientSocket.Connected) // { // _isConnected = false; // _ReConnect(); // break; // } // try // { // int receiveLength = clientSocket.Receive(_tmpReceiveBuff); // if (receiveLength > 0) // { // _databuffer.AddBuffer(_tmpReceiveBuff, receiveLength);//将收到的数据添加到缓存器中 // while (_databuffer.GetData(out _socketData))//取出一条完整数据 // { // MessageCenter.Instance._netMessageDataQueue.Enqueue(_socketData); // } // } // } // catch (Exception e) // { // clientSocket.Disconnect(true); // clientSocket.Shutdown(SocketShutdown.Both); // clientSocket.Close(); // break; // } // } // } // /// // /// ProtoBuf序列化 // /// // /// // /// // public static byte[] ProtoBuf_Serializer(pb::IMessage data) // { // using (var ms = new MemoryStream()) // using (var os = new pb::CodedOutputStream(ms)) // { // data.WriteTo(os); // os.Flush(); // ms.Seek(0, SeekOrigin.Begin); // return ms.ToArray(); // } // } // /// // /// ProtoBuf反序列化 // /// // /// // /// // /// // public static T ProtoBuf_Deserialize(byte[] _data) where T : pb::IMessage, new() // { // var _parser = new pb::MessageParser(() => new T()); // return _parser.ParseFrom(_data); // } // /// // /// 连接服务器 // /// // /// // /// // public void Connect(string _currIP, int _currPort) // { // if (!IsConnceted) // { // this._currIP = _currIP; // this._currPort = _currPort; // _onConnet(); // } // else if (clientSocket == null || !clientSocket.Connected) // { // _ReConnect(); // } // } // /// // /// 发送消息基本方法 // /// // /// // /// // private void SendMsgBase(eProtocalCommand _protocalType, byte[] _data) // { // if (clientSocket == null || !clientSocket.Connected) // { // _ReConnect(); // return; // } // //byte[] _msgdata = DataToBytes(_protocalType, _data); // var sd = sSocketData.FromBytes(_protocalType, _data); // try // { // clientSocket.BeginSend(sd.ToBytes(), 0, sd.PackLen, SocketFlags.None, new AsyncCallback(_onSendMsg), clientSocket); // } // catch (System.Exception e) // { // LogHelper.Log(e.Message); // clientSocket.Disconnect(true); // clientSocket.Shutdown(SocketShutdown.Both); // clientSocket.Close(); // } // } // /// // /// 以二进制方式发送 // /// // /// // /// // public void SendMsg(eProtocalCommand _protocalType, ByteStreamBuff _byteStreamBuff) // { // SendMsgBase(_protocalType, _byteStreamBuff.ToArray()); // } // /// // /// 以ProtoBuf方式发送 // /// // /// // /// // public void SendMsg(eProtocalCommand _protocalType, pb::IMessage data) // { // SendMsgBase(_protocalType, ProtoBuf_Serializer(data)); // } // public void Close() // { // _close(); // } //} /// /// boss战部分使用的 /// public class TasPBSocketManager { private string _currIP; private int _currPort; private bool _isConnected = false; public bool IsConnceted { get { return _isConnected; } } private Socket clientSocket = null; private Thread receiveThread = null; private Task _receiveTask = null; private DataBuffer _databuffer = new DataBuffer(); byte[] _tmpReceiveBuff = new byte[4096]; private sSocketData _socketData = new sSocketData(); public Action OnConnected; public Action OnDisconnected; /// /// 断开 /// public void Close() { if (!_isConnected) return; _isConnected = false; if (receiveThread != null) { receiveThread.Abort(); receiveThread = null; } if (clientSocket != null && clientSocket.Connected) { //clientSocket.Disconnect(true); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); clientSocket = null; } } private void _ReConnect() { } /// /// 连接服务器 /// /// /// public void Connect(string _currIP, int _currPort) { if (!IsConnceted) { this._currIP = _currIP; this._currPort = _currPort; _onConnet(); } else if (clientSocket == null || !clientSocket.Connected) { _ReConnect(); } } /// /// 连接 /// private async void _onConnet() { try { clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建套接字 IPAddress ipAddress = IPAddress.Parse(_currIP); //解析IP地址 IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, _currPort); await clientSocket.ConnectAsync(ipEndpoint).WaitAsync(TimeSpan.FromSeconds(5)); clientSocket.SetKeepAlive(60 * 1000); receiveThread = new Thread(new ThreadStart(_onReceiveSocket)); receiveThread.IsBackground = true; receiveThread.Start(); _isConnected = true; LogHelper.Log("连接成功"); OnConnected?.Invoke(); } catch (TimeoutException e) { LogHelper.LogError("连接超时"); Close(); } catch (Exception _e) { LogHelper.LogError("连接失败" + _e.Message); Close(); } } /// /// 接受网络数据 /// private async void _onReceiveSocket() { while (true) { if (!clientSocket.Connected) { _isConnected = false; _ReConnect(); break; } try { var receiveLength = await clientSocket.ReceiveAsync(new ArraySegment(_tmpReceiveBuff), SocketFlags.None); // 将接收到的信息存入到内存缓冲区,并返回其字节数组的长度 if (receiveLength > 0) { _databuffer.AddBuffer(_tmpReceiveBuff, receiveLength);//将收到的数据添加到缓存器中 while (_databuffer.GetData(out _socketData))//取出一条完整数据 { MessageCenter.Instance._netMessageDataQueue.Enqueue(_socketData); } } else { // 收到0字节数据视为对端连接已断开 OnDisconnected?.Invoke(); LogHelper.Log("发现对端断开连接."); Close(); } } catch (Exception e) { Close(); break; } } } /// /// ProtoBuf反序列化 /// /// /// /// public static T ProtoBuf_Deserialize(byte[] _data) where T : pb::IMessage, new() { var _parser = new pb::MessageParser(() => new T()); return _parser.ParseFrom(_data); } /// /// 发送消息基本方法 /// private async void SendMsgBase() { if (this.IsConnceted) { if (clientSocket == null || !clientSocket.Connected) { _ReConnect(); return; } while (_msgQueue.TryDequeue(out var kv)) { LogHelper.Log($"send msg in queue {kv.Key}"); var msg = sSocketData.FromIMsg(kv.Key, kv.Value); try { await clientSocket.SendAsync(new ArraySegment(msg.ToBytes()), SocketFlags.None); } catch (Exception e) { LogHelper.Log(e.Message); Close(); } } } } public void Update() { SendMsgBase(); } /// /// 以ProtoBuf方式发送 /// /// /// public void SendMsg(eProtocalCommand _protocalType, pb::IMessage data) { _msgQueue.Enqueue(new KeyValuePair(_protocalType, data)); } private ConcurrentQueue> _msgQueue = new ConcurrentQueue>(); }