游戏请求协议Actor经常会出现延迟,甚至可能延迟到5秒
在问这个问题之前,说下这个项目因为当初是别人从头开始弄得, 应该是基于当初那个斗地主的项目,我仅参与了上层逻辑部分,对于底层部分不太了解,所以在部分问题的描述上可能不太对,还请各位看官谅解,谢谢。
我遇到了一个问题: 【问题描述】
射击游戏,比如一条协议,我发射子弹,子弹命中飞机后请求服务器,服务器返回结果,客户端显示结果,击杀或未击杀,这一块出现了延迟
我想要实现【这么一个功能】:
因为这是一个飞行射击的游戏,在上述请求的过程中,客户端的飞机依旧在移动,尽可能的让这条协议是尽快返回,客户端实时播放效果,看上去不那么的怪
但出现【如下问题】:
不是必现,在线人数多了就会更明显,有时候协议会请求过去后,好几秒才返回,这样在游戏中的体验就是玩家击中飞机后飞机还在飞,然后突然biubiubiu爆炸了,非常奇怪
我经过了以下尝试【思路细节与代码实现】:
接下来这段过程其中有很小白的地方,因为我不是技术出身,所以请各位见谅。
1.基于游戏的特殊性(每次攻击都需要判断金币、扣除金币巴拉巴拉的),所以 频繁更新的地方都是做了定时更新的,现在是1分钟会更新到数据库一次,甚至把一些不频繁更新的也放到了数据库,但是没有什么效果,这条路暂时GG
========以为是更新太频繁导致的,但是验证下来并没有用,以下是代码========
[Event(EventIdType.PersonalPool2DB)]
public class PersonalPool2DBEvent : AEvent<UserPersonalPool, bool> {
Dictionary<long, DateTime> UserUpdateTimeDic = new Dictionary<long, DateTime>();
public override void Run(UserPersonalPool bc, bool isUpdateCurrent) {
if (bc == null) return;
if (isUpdateCurrent) {
_ = Game.Scene.GetComponent<DBProxyComponent>().Save(bc);
}
else {
//..这里需要做延迟处理
if (UserUpdateTimeDic.ContainsKey(bc.UserId)) {
if(DateTime.Now >= UserUpdateTimeDic[bc.UserId]) {
bc.LastUpdateTime = DateTime.Now.ToString();
_ = Game.Scene.GetComponent<DBProxyComponent>().Save(bc);
UserUpdateTimeDic[bc.UserId] = DateTime.Now.AddMinutes(1);
}
}
else {
UserUpdateTimeDic.Add(bc.UserId, DateTime.Now);
}
}
}
}
2.之前写的过程中,写了比较多的await,所以怀疑是await原因,就去把大部分的await的地方都改成了不等待,默认他是成功,当然这样的操作是有风险,不过基本都是save操作,不过捯饬了一堆,最后GG。
========以为是await导致的,但是验证下来并没有用,以下是代码========
_ = Game.Scene.GetComponent<DBProxyComponent>().Save(Game.Scene.GetComponent<GlobalExchangeRecordComponent>().GameExchangeDbData);//保存数据
3.安卓已经上线,所以着手接入苹果支付,接入的过程中遇到一个问题,就是安卓整个流程是好的,我发货是在服务器上起了一个http的服,然后web支付成功收到回调后 通知这个地址;安卓一切都没问题,在接入苹果以后,苹果支付成功的payload字符串,我是先传到了我得服务器,然后我服务器推给了web,问题出现在这,我推给web后偶尔收不到任何回复,web那边看了一切正常,然后,整个服务器就卡死了,基本上会卡90100秒,随后把http的请求改成异步的,卡顿消失,正常发货到账,由此联想到会不会之前的问题也是这个的原因,所以随机把涉及到的请求改成一部的,这一步我走的是热更新reload,但是实际情况还是不太理想,这里贴一下代码:
这是之前用的post方法:
/// <summary>
/// Post请求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <returns></returns>
public string PostUrl(string url, string postData) {
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
byte[] data = Encoding.UTF8.GetBytes(postData);
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream()) {
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
//获取响应内容
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) {
result = reader.ReadToEnd();
}
return result;
}
改成异步是这样的:
/// <summary>
/// Post请求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <returns></returns>
public async ETTask<string> PostUrl(string url, string postData) {
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
byte[] data = Encoding.UTF8.GetBytes(postData);
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream()) {
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
var resp = await req.GetResponseAsync();
Stream stream = resp.GetResponseStream();
//获取响应内容
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) {
result = await reader.ReadToEndAsync();
}
return result;
}
但不能解决,报错如下【报错信息/截图】:
无法提供报错的信息,因为产品已经上线,小量买了点用户,大概在线二三十人就会遇到这个问题,目前没有分布,所有的服务器在allserver上,配置如下:
服务器配置:8H16G 100MB带宽 阿里云上海
最高在线:30人,其实十几人就有这个现象
目前实在没啥头绪了,打算明天给服务器加个定时器,每秒打个日志,看看到底卡顿的时候发生了啥;
谷歌/百度/必应但找不到答案。请问我该怎么解决?【截图相关代码片段】:
目前整个现象是在整个游戏生涯都有出现,每条协议都有这样的现象
之前在群里问过ET的大佬初见,他的意思是建议定时发送协议,不要收到就发,我还不太了解这个意思,但是我们的游戏理论上在延迟上是要能做到多低就得多低。
万般无奈,最近准备要提高买量了,所以还是来请教下各位大佬,还请帮忙看看啥问题呢
愿你眼里有光,心中有爱。
敬颂时祺.