Unity SuperSocket之NetMgr
发表于2019-01-08
Unity SuperSocket之NetMgr
代码如下:
using Message; using SuperSocket.ClientEngine; using System; using System.Collections.Generic; using System.IO; using System.Net; using UnityEngine; /// <summary> /// 网络管理 /// </summary> public class NetMgr : MonoBehaviour { public static NetMgr Instance; private AsyncTcpSession socket = null; private int protoId; 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; //123.56.223.55 127.0.0.1 private string ip = "123.56.223.55"; //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; private void Awake() { Instance = this; MsgMgr.Instance.AddListener(typeof(SToCHeatBeat), OnHeratBeat); } public void Connect() { socket = new AsyncTcpSession(); socket.Connected += Connected; socket.DataReceived += DataReceived; socket.Error += Error; socket.Closed += Closed; socket.Connect(new IPEndPoint(IPAddress.Parse(ip), port)); } private void Connected(object sender, EventArgs e) { Debug.Log("连接成功"); status = Status.Connected; connectCallBack(true); } private void DataReceived(object sender, DataEventArgs e) { Debug.Log("收到消息"); try { byte[] buffer = new byte[e.Length]; Array.Copy(e.Data, buffer, e.Length); receiveCache.AddRange(buffer); 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)); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } private void Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e) { Debug.Log("连接出错:" + e.ToString()); connectCallBack(false); if (status == Status.Connected) { status = Status.None; Close(); } } private void Closed(object sender, EventArgs e) { Debug.Log("连接关闭:" + e.ToString()); } 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) { if (socket.IsConnected) { socket.Close(); } socket = null; } } /// <summary> /// 发送 /// </summary> /// <param name="obj"></param> public void Send(object obj) { if (status != Status.Connected) { Debug.LogError("还没链接"); return; } if (!ProtoDic.ContainProtoType(obj.GetType())) { Debug.LogError("未知协议号" + obj.GetType().ToString()); return; } byte[] data = NetCode.Encode(obj); sendCache.Enqueue(data); Send(); } void Send() { try { if (sendCache.Count == 0) { isSending = false; return; } isSending = true; byte[] data = sendCache.Dequeue(); socket.Send(new ArraySegment<byte>(data)); Debug.Log("发送"); isSending = false; Send(); } catch (Exception e) { Debug.Log(e.Message); } } //描述 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(); } }