Unity SuperSocket之NetMgr

发表于2019-01-08
评论0 1.4k浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

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

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台