区分消息_客户端NetMgr1(基于之前的修改)

26 阅读3分钟
修改一 因为现在要接受的类型是类对象类型,所以需要将队列中的接收类型进行更换
在之前的NetMgr中将
public Queue<string> sendMsgQueue = new Queue<string>(); 
public Queue<string> receiveQueue = new Queue<string>();
修改成
public Queue<BaseMsg> sendMsgQueue = new Queue<BaseMsg>(); 
public Queue<BaseMsg> receiveQueue = new Queue<BaseMsg>();

修改2 发送消息的修改

SendMeg()中将之前的socket.Send(Encoding.UTF8.GetBytes(sendMsgQueue.DEQueue()));
修改成
socket.Send(sendMsgQueue.Dequeue().Writing());  //因为现在的sendMsgQueue.Dequeue()就是一个类对象,调用类对象内部的序列化方法Writing() 就转成字节数组类型了;

修改3 接受消息的修改

//将反序列化的字符串 放容器中 
receiveQueue.Enqueue(Encoding.UTF8.GetString(receiveBytes,0,receiveNum));
改成
先获取消息ID  int msgID=BitConverter.ToInt32(receiveBytes, 0);
BaseMsg baseMsg = null; //临时接收
然后用Switch去判断消息ID
switch (msgID) 
{ 
    case 1001: 
        PlayerMsg msg = new PlayerMsg(); 
        msg.Reading(receiveBytes, 4);  //解析出来的数据放在Update中打印 所以需要放在接受队列中 
        baseMsg = msg; 
        break; } //如果消息为空 那就是不支持的类型 ,没有解析 
        if (baseMsg == null) continue; //收到消息 放入公共容器 
        receiveQueue.Enqueue(baseMsg); 
}

修改4 打印消息的修改

消息的打印是放在Update中的 
 //print(receiveQueue.Dequeue());
 修改成
 //取出消息
BaseMsg msg= receiveQueue.Dequeue();
//需要进行判断是哪个结构类
if(msg is PlayerMsg)
{
    PlayerMsg playerMsg = (PlayerMsg)msg;
    print(playerMsg.playerID);
    print(playerMsg.playerData.name);
    print(playerMsg.playerData.atk);
    print(playerMsg.playerData.lev);
}


代码如下

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;

public class NetMgr1 : MonoBehaviour
{
    //单例模式
    public static NetMgr1 instance;
    public static NetMgr1 Instance=>instance;

    private bool isConnected = false;  //是否连接到服务器的开关

    //因为可以接收结构类消息 所以 使用BaseMsg

    //创建一个队列 用来存储要发送的消息
    public Queue<BaseMsg> sendMsgQueue = new Queue<BaseMsg>();
    //创建一个队列  用来存储要接收的消息
    public Queue<BaseMsg> receiveQueue = new Queue<BaseMsg>();


    //接收消息的容器
    byte[] receiveBytes = new byte[1024*1024];
     int receiveNum;

    Socket socket;


    

    private void Awake()
    {
        instance = this;
    }

  

    private void Update()
    {
        if (receiveQueue.Count > 0)
        {
            //print(receiveQueue.Dequeue());
            //取出消息
            BaseMsg msg= receiveQueue.Dequeue();
            //需要进行判断是哪个结构类
            if(msg is PlayerMsg)
            {
                PlayerMsg playerMsg = (PlayerMsg)msg;
                print(playerMsg.playerID);
                print(playerMsg.playerData.name);
                print(playerMsg.playerData.atk);
                print(playerMsg.playerData.lev);
            }
        }
    }

    //连接服务器  传入IP和端口号
    public void Connect(string host, int port)
    {
        //1.判断是否是连接状态  如果是 就返回
        if (isConnected)
            return;
        //设置连接方式
        socket=new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //获取服务器的 IPEndPoint
        IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(host), port); //里面输入服务器的IP和端口号
        try
        {
            socket.Connect(ipPoint);  //连接 成功
            //Send("连接成功");
            //进行收发消息  
            //用线程池进行嗲用
            ThreadPool.QueueUserWorkItem(SendMsg);
            ThreadPool.QueueUserWorkItem(receiveMsg);

        }
        catch(SocketException e)
        {
            if (e.ErrorCode == 10061)
            {
                print("服务器拒绝连接");
            }
            else
            {
                print("连接服务器失败" + e.ErrorCode);
            }
            return;
        }
        
        
    }

    /// <summary>
    /// 发送消息 外部
    /// </summary>
    /// <param name="info"></param>
    public void Send(BaseMsg msg)
    {
        sendMsgQueue.Enqueue(msg);
    }

    public void SendMsg(object obj)
    {
        while (!isConnected)
        {
            if(sendMsgQueue.Count > 0)
            {

                //socket.Send(Encoding.UTF8.GetBytes(sendMsgQueue.Dequeue()));
                //序列化
                socket.Send(sendMsgQueue.Dequeue().Writing());
            }
        }
    }

    /// <summary>
    /// 不停的接收消息
    /// </summary>
    private void receiveMsg(object obj)
    {
        while (!isConnected)
        {
            if (socket.Available > 0)
            {
                //获取长度
                receiveNum = socket.Receive(receiveBytes);
                //解析
                // receiveQueue.Enqueue(Encoding.UTF8.GetString(receiveBytes,0,receiveNum));
                //因为是可以接受结构类  所以首先要获取他的消息ID 
                int msgID = BitConverter.ToInt32(receiveBytes, 0);
                BaseMsg baseMsg = null;  //临时接收
                switch (msgID)
                {
                    case 1001:
                        PlayerMsg msg = new PlayerMsg();
                        msg.Reading(receiveBytes, 4);  //前面的整型是消息ID 所以从4开始
                        //解析出来的数据放在Update中打印  所以需要放在接受队列中
                        baseMsg = msg;
                        break;
                }

                //如果消息为空 那就是不支持的类型 ,没有解析
                if (baseMsg == null)
                    continue;
                //收到消息 放入公共容器
                receiveQueue.Enqueue(baseMsg);
                
            }
        }
    }

    public void Close()
    {
        if(socket != null)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();

            //关闭接收和发送服务
            isConnected = false;
        }
    }
    private void OnDestroy()
    {
        Close();
    }
}