假设我们的数据包是这样的结构
[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对象方法