帧同步 客户端同步 或 服务端同步 总结

客户端同步 方式是,客户端之间发送数据,获得数据后,合并到最近的一帧 来处理。服务器心跳继续保持

比如 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+帧  用完删

原文地址:https://www.cnblogs.com/big-zhou/p/12496184.html