Unity SuperSocket之NetMgr

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地狱为王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值