zoukankan      html  css  js  c++  java
  • 帧同步 客户端同步 或 服务端同步 总结

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

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

  • 相关阅读:
    (PHP)redis Zset(有序集合 sorted set)操作
    (PHP)redis Set(集合)操作
    (PHP)redis Hash(哈希)操作
    (PHP)redis String(字符串)操作
    (PHP)redis List(列表)操作
    PHP连接 redis
    PHP json 对象 数组互相转换
    循环节长度 蓝桥杯
    三羊献瑞 蓝桥杯
    立方变自身
  • 原文地址:https://www.cnblogs.com/big-zhou/p/12496184.html
Copyright © 2011-2022 走看看