Unity中使用Socket进行Tcp连接-网络线程无法访问UI问题(五)

由于unity中的UI只能在主线程中访问,在网络线程中接收到的协议,无法直接用来处理UI方面显示逻辑。因此,可以先将网络线程接收到的协议缓存起来,在从主线程中一条一条取出来处理。

static void OnReceiveData()
    {
        if (buffCount<2)
        {
            return;//收到数据小于字节长度描述
        }
        int bodyLength = BitConverter.ToInt16(readBuff,0);
        if (buffCount < 2 + bodyLength)
        {
            Debug.Log("收到数据不完整");
            return;//长度不够一条完整消息
        }
        string recStr = Encoding.Default.GetString(readBuff,2, bodyLength);
        Debug.Log("收到服务器消息" + recStr);
        MsgBase msgBase = MsgBase.Decode(recStr);
        lock (MsgHandler.Instance.msgList)//多线程访问,加锁
        {
            MsgHandler.Instance.msgList.Add(msgBase);
        }
        int start = 2 + bodyLength;
        int count = buffCount - start;
        Array.Copy(readBuff,start,readBuff,0,count);
        buffCount -= start;
        OnReceiveData();
    }

在MsgHandler中接收协议,在主线程的Update中取协议进行处理,根据由协议名称注册的事件去触发相应的操作。 

class MsgHandler
{
    public delegate void MsgDelegate(MsgBase msg);

    private Dictionary<string, MsgDelegate> listeners = new Dictionary<string, MsgDelegate>();
    public List<MsgBase> msgList = new List<MsgBase>();
    private static MsgHandler instance;
    public static MsgHandler Instance
    {
        get
        {
            if (instance == null)
                instance = new MsgHandler();
            return instance;
        }
    }

    public void AddListener(string msgName, MsgDelegate listener)
    {
        if (!listeners.ContainsKey(msgName))
        {
            listeners.Add(msgName, listener);
        }
        else
        {
            listeners[msgName] = listener;
        }
    }
    public void Start()
    {
        AddListeners();
    }
    public void Update()//在主线程中取协议
    {
        if (!NetManager.isConnected) return;
        if (msgList.Count <= 0)
        {
            return;
        }

        MsgBase msg = msgList[0];
        msgList.RemoveAt(0);

        if (listeners.ContainsKey(msg.protoName))
        {
            listeners[msg.protoName](msg);//根据协议名称触发事件
        }
    }
    void AddListeners()
    {
        AddListener("MsgHeartbeat", OnHeartbeat);//根据协议名称注册相应事件
       
    }
    void OnHeartbeat(MsgBase msg)//心跳检测
    {
        Debug.Log("收到服务器心跳包");
        GameManager.Instance.ResetTimer();
    }  
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值