幀同步 客戶端同步 或 服務端同步 總結


客戶端同步 方式是,客戶端之間發送數據,獲得數據后,合並到最近的一幀 來處理。服務器心跳繼續保持

比如 ab之間 同步,服務器心跳 0.5秒一次,那么 一次比作 一幀。 a發b的時候,正好是 30幀時候,那么a以31幀的數據方式 給a b同時 接收。返回后 等待 心跳是 31的時候,再處理 之前 收的數據。

這樣的好處就是,服務器壓力小,服務器只要 負責心跳 以及 客戶端 相互發送就可,不需要 任何記錄操作。

但缺點很明顯,發送量太大,ab之間發送,就是2次 給 客戶端發,如果是 群體幾十號玩家相互發,那一個玩家發一條 ,服務器就要發好幾十條,最后變成n*n

 

所以,我改進了方法,采取 服務器同步法,同樣 服務器心跳不變,時時刻刻告訴客戶端 目前 是 第幾幀。

客戶端之間 相互發送,服務器 記錄 ,在心跳當中 發射。

比如  ab 之間 互發消息。服務器記錄的是 a 發的消息 和 在第幾幀發的,當然因為延遲,我們肯定是 要再多加1幀,告知 是下一幀 轉發客戶端。那么心跳在 下一幀的時候,就發現有 一條記錄,要求 ab都要收到 一條記錄,然后 心跳就 不僅僅是發幀,還包含了 相關數據。

這樣的好處就是,服務器 發送量 不會因為 並發大而 增加,發送量是 固定的。

壞處也有,就是 心跳每次都會檢索一次每個 客戶端 當前幀有沒有數據要 發送。

相互發送服務器 片段代碼,這里只負責存數據,不用來發送

 

       //同時通知雙方
        static void OnSendDouble(string Type, string Playid, string Otherid, NetIncomingMessage msg)
        {
            //這個區塊有存在
            JsonDatas message = new JsonDatas();
            message.jsons["type"] = Type;
            message.jsons["Frame"] = Frame + 1;
            message.jsons["playid"] = Playid;
            string json = JsonConvert.SerializeObject(message);
            //如果 這個幀 已經發射一次以上了
            if (ServerModel.getInstance().OnSendeMessageDictionary.ContainsKey(Playid + "," + (Frame + 1)))
            {
                //Console.WriteLine(" 已經多次 " + Playid + "," + (Frame + 1));
                ServerModel.getInstance().OnSendeMessageDictionary[Playid + "," + (Frame + 1)].Add(json);
            }
            else
            {
               // Console.WriteLine("第一次 " + Playid + "," + (Frame + 1));
                List<string> jsonlist = new List<string>();
                jsonlist.Add(json);
                ServerModel.getInstance().OnSendeMessageDictionary.Add(Playid + "," + (Frame + 1), jsonlist);
            }
            //如果 這個幀 已經發射一次以上了
            if (ServerModel.getInstance().OnSendeMessageDictionary.ContainsKey(Otherid + "," + (Frame + 1)))
            {
               // Console.WriteLine(" 已經多次 " + Otherid + "," + (Frame + 1));
                ServerModel.getInstance().OnSendeMessageDictionary[Otherid + "," + (Frame + 1)].Add(json);
            }
            else
            {
               // Console.WriteLine("第一次 " + Otherid + "," + (Frame + 1));
                List<string> jsonlist = new List<string>();
                jsonlist.Add(json);
                ServerModel.getInstance().OnSendeMessageDictionary.Add(Otherid + "," + (Frame + 1), jsonlist);
            }
        }
  public static void Confrontation()
        {
            while (true)
            {
                Thread.Sleep(500);
                //   Output("目前" + Frame);
                List<NetConnection> all = s_server.Connections; // get copy
                //   all.Remove(msg.SenderConnection);
                if (all.Count > 0)
                {
                    foreach (NetConnection NT in all)
                    {
                        NetOutgoingMessage om = s_server.CreateMessage();
                        JsonDatas message = new JsonDatas();
                        message.jsons["type"] = "7";
                        message.jsons["Frame"] = Frame;
                        message.jsons["TF"] = 0;
                        string id = ServerModel.getInstance().TSenderConnectionlDictionary[NT];
                        //如果 這個幀 有過發射
                        if (ServerModel.getInstance().OnSendeMessageDictionary.ContainsKey(id + "," + Frame))
                        {
                            message.jsons["TF"] = 1;
                            message.jsons["msg"] = JsonConvert.SerializeObject(ServerModel.getInstance().OnSendeMessageDictionary[id + "," + Frame]);
                            string json = JsonConvert.SerializeObject(message);
                            om.Write(json);
                            s_server.SendMessage(om, NT, NetDeliveryMethod.ReliableOrdered, 0);
                            ServerModel.getInstance().OnSendeMessageDictionary.Remove(id + "," + Frame);
                        }
                        else
                        {
                            string json = JsonConvert.SerializeObject(message);
                            om.Write(json);
                            s_server.SendMessage(om, NT, NetDeliveryMethod.ReliableOrdered, 0);
                        }
                    }
                }
                Frame++;
            }
        }

上面這個是心跳的片段代碼 

數據是 list方式,因為 可能一幀  會多次操作。key 是  id+幀  用完刪


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM