Unity 服务器踩坑 客户端网络架构 生产者消费者模式 (二)

假设我们的数据包是这样的结构

[Serializable] //序列化对象
[StructLayout(LayoutKind.Sequential, Pack = 1)] // 按1字节对齐
public class UserMsg
{
    public int messageID;
    public int clientID;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)] //限制200字节
    public byte[] message;
}

我们在客户端为了避免IO阻塞所以应该新建一个子线程来接收数据包

之所以使用生产者消费者模式有三个点

1.当数据包传送量大的时候,容易造成message堆积,每次都要等管理员处理完上一个消息才能接收下一个消息

2.线程中无法调用Unity许多方法,比如GameObject.Find("");所以我们需要一个置身事外的老哥来处理这些杂七杂八的事情

3.network只应该负责接收消息、传递消息而不能在其中处理消息,这种设计模式是不好的

所以我们打算采用类似于GPU和CPU的流水线模式,一个负责生产消息,一个负责处理消息

初始化客户端以后新建一个线程,负责接收消息, 接收完毕把消息传递到消息队列

生产者从一边生产消息,消费者从另一边消费消息

 Thread t = new Thread(new ThreadStart(()=> {
            while (true)
            {
                UserMsg u = receiveMessage();
               receive(u);
           }
        }));
        t.Start();

下面是委托的定义和初始化

    public delegate void receiveHandler(UserMsg u);
    public event receiveHandler receive;

    public ClientNetWork() {
        receive += new receiveHandler(ClientAdministrator.newMessage);
    }

消息队列和管理员处理消息的方法

public class ClientAdministrator : MonoBehaviour
{
    public static Queue<UserMsg> u=new Queue<UserMsg>();
    public static void newMessage(UserMsg user) {
        u.Enqueue(user);
    }
    public static void DealWithMessage(){
        //消费者消费一条消息
        UserMsg user=u.Dequeue();
        Debug.Log("消费者消费了一条消息");
    }
    private void Start()
    {
        
    }
    private void Update()
    {
        if (u.Count>0) {
            DealWithMessage();
        }
    }
}

假设我生产一条消息的时间是10分钟,消费一条消息的时间是f(x)(x为消息的大小)

那么原始设计模式客户端每次处理一条消息的时间是10+f(x)

使用上述设计模式,客户端处理消息的速度恒为f(x),而且消费者可以直接操作unity对象方法

猜你喜欢

转载自blog.csdn.net/qq_34204419/article/details/82700968