• 反馈
  • SendToClient和Response消息返回时序问题

对于IActorLocationRequest和IActorLocationResponse消息,比如

C2MXXX和M2C_XXX,M2C_XXX的处理过程中调用了SendToClient,假设发送的消息叫M2CInfo。
正常情况下,M2CInfo先于M2C_XXX返回,但是在客户端和服务器通信不频繁时,可能会出现M2CInfo晚于M2C
XXX。

出现这个问题的原因在于由于客户端一段时间内(大概一分钟)没有向服务器发送IActorLocationRequest消息,服务器会Dispose掉这个Unit的ActorMessageSender

这样,SendToClient发送M2C_Info时,就会触发从ActorLoation获取ActorId,这是一个异步操作,从而导致

M2CInfo会晚于M2C_XXX到达客户端。

本次测试环境是Gate和Map在同一进程,Response返回时会等待一帧,如下

PS:ET版本是7.2

很细!学习了。

M2CInfo在什么情况下需要晚于M2C_XXX处理?我认为这个问题可以通过正确设计业务逻辑来避免

  • wuzy 回复了此帖

    Liquor 一般来说M2CInfo用于更新客户端数据。通常客户端需要一个时机,就是确保request的所有response(包括M2CInfo)都收到了,如果能确保M2CInfo早于M2CXXX返回,在收到M2CXXX时,就是这个时机。

    我遇到的bug就是由于假定会先收到M2CInfo。一种解法就是SendToClient改成同步的,但总觉得这样也不太好,因为我们代码里有很多通过属性变更触发NotifyClient的代码,从而不太容易把SendToClient改成同步的(至少不太优雅),如下图,不知道能不能在框架层做这个保证。

    这个框架层不会保证,但是你自己可以写个方法,确保存在发送的actorsender,不存在就await获得再发送,这个await获取actorsender得加到你自己的逻辑中去

      egametang 这个把获取actorSender写在自己逻辑里面也不太合理吧, 意味着每次调用sendClient都要去检测actorSender是否存在。 那就是变相把sendClient变成同步逻辑。 按照默认设计的思维,先发送的消息理论是应该要先到的。 那sendClient是否就应该设计成为同步的呢, 这样才更符合使用者的习惯,虽然损失的性能。或者有其他的设计思路,比如actorSender用心跳去维护有效性,从而避免调用sendClient再去检测有效性。

        egametang 感谢,这确实是一种做法,不过我没放在逻辑层,而是直接加到了AMActorLocationRpcHandler里,以下是具体代码,测试确实没问题了

          evalli 很赞同你的说法,框架的实现应该 默认符合直觉逻辑,先发的就应该先到。

          wuzy 你这样搞,把一些奇怪的逻辑放到了整个基类中,很奇怪啊。无法就是把sender包装一下,await 发送完成再response,这有啥毛病

          就是原来是不等待的sender,改成await sender而已,很合理啊,之前的sender是新协程,不可能保证顺序。不过我可以改一下,让sender直接可以await即可

          egametang 主要是我们项目是通过修改属性,触发事件的方式来SentToClient(在我第二条评论里有截图),所以没法await啊,除非把修改属性都改成SetPropertyAsync这种形式,感觉也不是很好

            wuzy 这种情况跟你上面说的就不一样哦,你上面说的是放在response中

            • wuzy 回复了此帖

              egametang 一样的,比如客户端请求穿戴装备,后端收到请求可以直接写equip.worn=true,然后通过属性变更事件把worn属性同步到客户端

              这样的话你把那个actorsender超时去掉算了,我再想想怎么简化

              分下类,这种actorsender不会超时删除

              说点什么吧...