Unity 客戶端網路架構 生產者消費者模式
阿新 • • 發佈:2018-12-09
假設我們的資料包是這樣的結構
[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物件方法