Unity Socket之NetMgr
发表于2019-01-08
Unity在iOS平台无法使用supersocket
代码如下:
using Message; using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using UnityEngine; namespace TFrame { /// <summary> /// 网络管理 /// </summary> public class NetMgr : MonoBehaviour { public static NetMgr Instance; private Socket socket; private byte[] buffer; private int size = 1024; private int protoId; private bool isReceiving = false; private List<byte> receiveCache = new List<byte>(); private bool isSending = false; private Queue<byte[]> sendCache = new Queue<byte[]>(); public delegate void Delegate(bool result); public Delegate connectCallBack; private string ip = "127.0.0.1"; private int port = 6650; //心跳时间 private float lastTickTime = 0; private float heartBeatTime = 3; private long lastTime = 0; public enum Status { None, Connected, }; public Status status = Status.None; public NetMgr() { buffer = new byte[size]; receiveCache = new List<byte>(); sendCache = new Queue<byte[]>(); Instance = this; MsgMgr.Instance.AddListener(typeof(SToCHeatBeat), OnHeratBeat); } public void Connect() { try { //socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Connect socket.Connect(IPAddress.Parse(ip), port); //BeginReceive socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, EndReceive, buffer); socket.SendTimeout = 3; Debug.Log("连接成功"); //状态 status = Status.Connected; connectCallBack(true); } catch (Exception e) { Debug.Log("连接失败:" + e.Message); connectCallBack(false); } } /// <summary> /// 接收回调 /// </summary> /// <param name="ar"></param> private void EndReceive(IAsyncResult ar) { try { int count = socket.EndReceive(ar); if (count > 0) { byte[] data = new byte[count]; Buffer.BlockCopy(buffer, 0, data, 0, count); OnReceive(data); socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, EndReceive, buffer); } else { //包尺寸有问题,断线处理 Debug.Log("包尺寸有问题,断线处理"); status = Status.None; connectCallBack(false); Close(); } } catch (Exception e) { Debug.Log("ReceiveCb失败:" + e.Message); status = Status.None; connectCallBack(false); } } /// <summary> /// 消息处理 /// </summary> /// <param name="data"></param> private void OnReceive(byte[] data) { //将接收到的数据放入数据池中 receiveCache.AddRange(data); //如果没在读数据 if (!isReceiving) { isReceiving = true; ReadData(); } } /// <summary> /// 读取数据 /// </summary> private void ReadData() { byte[] data = NetCode.Decode(ref protoId, ref receiveCache); if (data != null) { Type protoType = ProtoDic.GetProtoTypeByProtoId(protoId); object tos = ProtoBuf.Serializer.Deserialize(protoType, new MemoryStream(data)); MsgMgr.Instance.eventDict.Enqueue(new KeyValuePair<Type, object>(protoType, tos)); //尾递归,继续读取数据 ReadData(); } else { isReceiving = false; } } /// <summary> /// 发送 /// </summary> /// <param name="obj"></param> public void Send(object obj) { if (status != Status.Connected) { Debug.LogError("[Connection]还没链接就发送数据是不好的"); return; } if (!ProtoDic.ContainProtoType(obj.GetType())) { Debug.LogError("未知协议号"); return; } byte[] data = NetCode.Encode(obj); sendCache.Enqueue(data); Send(); } /// <summary> /// 发送 /// </summary> private void Send() { try { if (sendCache.Count == 0) { isSending = false; return; } isSending = true; byte[] data = sendCache.Dequeue(); socket.BeginSend(data, 0, data.Length, SocketFlags.None, null, null); isSending = false; Send(); } catch (Exception e) { Debug.Log(e.Message); } } private void FixedUpdate() { //心跳 if (status == Status.Connected) { if (Time.time - lastTickTime > heartBeatTime) { CToSHeatBeat hb = new CToSHeatBeat(); TimeSpan ts = new TimeSpan(DateTime.Now.Ticks); hb.time = (long)ts.TotalMilliseconds; lastTime = hb.time; Send(hb); lastTickTime = Time.time; Debug.LogWarning("发送心跳 " + hb.time); } } //断线重连 } void OnHeratBeat(object protocol) { SToCHeatBeat sthb = protocol as SToCHeatBeat; Debug.LogWarning("收到心跳 " + sthb.time + " lastTime " + lastTime); Debug.LogWarning("延迟:" + (lastTime - sthb.time) / 1000); } /// <summary> /// 关闭连接 /// </summary> /// <returns></returns> public void Close() { if (socket != null) { try { socket.Close(); } catch (Exception e) { Debug.Log("关闭失败:" + e.Message); } socket = null; } } //描述 public string GetDesc(byte[] bytes) { string str = ""; if (bytes == null) return str; for (int i = 0; i < bytes.Length; i++) { int b = (int)bytes[i]; str += b.ToString() + " "; } return str; } private void OnApplicationPause(bool pause) { Close(); } private void OnApplicationFocus(bool focus) { //重新登录 } /// <summary> /// 当应用程序退出或编辑器结束运行 /// </summary> private void OnApplicationQuit() { Debug.Log("Close"); Close(); } } }