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();
}
}