public static async ETTask <IActorResponse> Call( this ActorMessageSenderComponent self, long actorId, int rpcId, MemoryStream memoryStream, bool needException = true ) { if (actorId == 0) { throw new Exception($"actor id is 0: {memoryStream.ToActorMessage()}"); } var tcs = ETTask <IActorResponse> .Create(true); self.requestCallback.Add(rpcId, new ActorMessageSender(actorId, memoryStream, tcs, needException)); self.Send(actorId, memoryStream); long beginTime = TimeHelper.ServerFrameTime(); IActorResponse response = await tcs; long endTime = TimeHelper.ServerFrameTime(); long costTime = endTime - beginTime; if (costTime > 200) { Log.Warning("actor rpc time > 200: {0} {1}", costTime, memoryStream.ToActorMessage()); } return(response); }
private async Task <IActorResponse> RunInner(IActorRequest iActorRequest) { try { if (ActorId == 0) { Log.Info($"actor send message fail, actorid: {Id}"); Dispose(); return(new ActorResponse() { Error = ErrorCode.ERR_ActorNotOnline }); } LastSendOrRecvTime = TimeHelper.CurrentLocalMilliseconds(); IActorResponse response = await ActorMessageSenderComponent.Instance.CallWithoutException(ActorId, iActorRequest); switch (response.Error) { case ErrorCode.ERR_NotFoundActor: { // 如果没找到Actor,重试 ++FailTimes; if (FailTimes > ActorLocationSender.MaxFailTimes) { Log.Info($"actor send message fail, actorid: {Id}"); Dispose(); return(response); } // 等待0.5s再发送 long instanceId = InstanceId; await TimerComponent.Instance.WaitAsync(500); if (InstanceId != instanceId) { throw new RpcException(ErrorCode.ERR_ActorRemove, $"{DCETRuntime.MongoHelper.ToJson(iActorRequest)}"); } ActorId = await LocationProxyComponent.Instance.Get(Id); return(await RunInner(iActorRequest)); } } LastSendOrRecvTime = TimeHelper.CurrentLocalMilliseconds(); FailTimes = 0; return(response); } catch (RpcException) { Dispose(); throw; } catch (Exception e) { Dispose(); throw new Exception($"{DCETRuntime.MongoHelper.ToJson(iActorRequest)}\n{e}"); } }
public async ETTask Handle(Entity entity, object actorMessage, Action <IActorResponse> reply) { Message msg = actorMessage as Message; if (msg == null) { Log.Error($"消息类型转换错误: {actorMessage.GetType().FullName} to {typeof (Message).Name}"); return; } E e = entity as E; if (e == null) { Log.Error($"Actor类型转换错误: {entity.GetType().Name} to {typeof (E).Name} --{typeof (Message).Name}"); return; } IActorResponse response = (IActorResponse)Activator.CreateInstance(GetResponseType()); response.RpcId = msg.RpcId; reply.Invoke(response); await this.Run(e, msg); }
private static async ETTask <IActorResponse> RunInner(this ActorLocationSender self, IActorRequest iActorRequest) { try { if (self.ActorId == 0) { Log.Info($"actor send message fail, actorid: {self.Id}"); self.Dispose(); return(new ActorResponse() { Error = ErrorCode.ERR_ActorNotOnline }); } self.LastSendOrRecvTime = TimeHelper.Now(); IActorResponse response = await ActorMessageSenderComponent.Instance.CallWithoutException(self.ActorId, iActorRequest); switch (response.Error) { case ErrorCode.ERR_NotFoundActor: { // 如果没找到Actor,重试 ++self.FailTimes; if (self.FailTimes > ActorLocationSender.MaxFailTimes) { Log.Info($"actor send message fail, actorid: {self.Id}"); self.Dispose(); return(response); } // 等待0.5s再发送 long instanceId = self.InstanceId; await TimerComponent.Instance.WaitAsync(500); if (self.InstanceId != instanceId) { throw new RpcException(ErrorCode.ERR_ActorRemove, $"{MongoHelper.ToJson(iActorRequest)}"); } self.ActorId = await LocationProxyComponent.Instance.Get(self.Id); return(await self.RunInner(iActorRequest)); } } self.LastSendOrRecvTime = TimeHelper.Now(); self.FailTimes = 0; return(response); } catch (RpcException) { self.Dispose(); throw; } catch (Exception e) { self.Dispose(); throw new Exception($"{MongoHelper.ToJson(iActorRequest)}\n{e}"); } }
public static void Check(this ActorMessageSenderComponent self) { long timeNow = TimeHelper.ServerNow(); foreach ((int key, ActorMessageSender value) in self.requestCallback) { // 因为是顺序发送的,所以,检测到第一个不超时的就退出 if (timeNow < value.CreateTime + ActorMessageSenderComponent.TIMEOUT_TIME) { break; } self.TimeoutActorMessageSenders.Add(key); } foreach (int rpcId in self.TimeoutActorMessageSenders) { ActorMessageSender actorMessageSender = self.requestCallback[rpcId]; self.requestCallback.Remove(rpcId); try { IActorResponse response = ActorHelper.CreateResponse((IActorRequest)actorMessageSender.MemoryStream.ToActorMessage(), ErrorCore.ERR_ActorTimeout); Run(actorMessageSender, response); } catch (Exception e) { Log.Error(e.ToString()); } } self.TimeoutActorMessageSenders.Clear(); }
/// <summary> /// 处理发送消息 /// </summary> /// <param name="self"></param> /// <param name="task"></param> /// <returns></returns> private static async Task RunTask(this ActorLocationSender self, ActorTask task) { //获得和其他服务器通讯的会话 ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId); //发送一个rpc消息 IActorResponse response = await actorMessageSender.Call(task.ActorRequest); // 发送成功 switch (response.Error) { case ErrorCode.ERR_NotFoundActor: // 如果没找到Actor,重试 ++self.FailTimes; // 失败MaxFailTimes次则清空actor发送队列,返回失败 if (self.FailTimes > ActorLocationSender.MaxFailTimes) { // 失败直接删除actorproxy Log.Info($"actor send message fail, actorid: {self.Id}"); self.RunError(response.Error); self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); //从字典中移除这个会话通道 return; } // 等待0.5s再发送 await Game.Scene.GetComponent <TimerComponent>().WaitAsync(500); self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id); //重新获得map服务器地址 self.Address = StartConfigComponent.Instance .Get(IdGenerater.GetAppIdFromId(self.ActorId)) .GetComponent <InnerConfig>().IPEndPoint; //得到IP self.AllowGet(); return; case ErrorCode.ERR_ActorNoMailBoxComponent: self.RunError(response.Error); self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); return; default: //发送成功 self.LastSendTime = TimeHelper.Now(); //记录最后发送时间 self.FailTimes = 0; self.WaitingTasks.Dequeue(); //出栈 if (task.Tcs == null) { return; } IActorLocationResponse actorLocationResponse = response as IActorLocationResponse; if (actorLocationResponse == null) { task.Tcs.SetException(new Exception($"actor location respose is not IActorLocationResponse, but is: {response.GetType().Name}")); } task.Tcs.SetResult(actorLocationResponse); //返回PRC消息回应 return; } }
private static async ETTask RunTask(this ActorLocationSender self, ActorTask task) { ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId); IActorResponse response = await actorMessageSender.Call(task.ActorRequest); // 发送成功 switch (response.Error) { case ErrorCode.ERR_NotFoundActor: // 如果没找到Actor,重试 ++self.FailTimes; // 失败MaxFailTimes次则清空actor发送队列,返回失败 if (self.FailTimes > ActorLocationSender.MaxFailTimes) { // 失败直接删除actorproxy Log.Info($"actor send message fail, actorid: {self.Id}"); self.RunError(response.Error); self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); return; } // 等待0.5s再发送 await Game.Scene.GetComponent <TimerComponent>().WaitAsync(500); self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id); self.AllowGet(); return; case ErrorCode.ERR_ActorNoMailBoxComponent: self.RunError(response.Error); self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); return; default: self.LastRecvTime = TimeHelper.Now(); self.FailTimes = 0; self.WaitingTasks.Dequeue(); // 如果所有的发送消息都得到了返回,发送任务完成,那么删除这个ActorLocationSender,及时回收发送对象 if (self.WaitingTasks.Count == 0) { self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); } if (task.Tcs != null) { IActorLocationResponse actorLocationResponse = response as IActorLocationResponse; if (actorLocationResponse == null) { task.Tcs.SetException(new Exception($"actor location respose is not IActorLocationResponse, but is: {response.GetType().Name}")); } task.Tcs.SetResult(actorLocationResponse); } return; } }
public static IActorResponse CreateResponse(IActorRequest iActorRequest, int error) { Type responseType = OpcodeTypeComponent.Instance.GetResponseType(iActorRequest.GetType()); IActorResponse response = (IActorResponse)Activator.CreateInstance(responseType); response.Error = error; response.RpcId = iActorRequest.RpcId; return(response); }
public void RunMessage(IActorResponse response) { ActorMessageSender actorMessageSender; if (!requestCallback.TryGetValue(response.RpcId, out actorMessageSender)) { Log.Error($"not found rpc, maybe request timeout, response message: {StringHelper.ToString(response)}"); return; } requestCallback.Remove(response.RpcId); actorMessageSender.Callback(response); }
public static void RunMessage(this ActorMessageSenderComponent self, IActorResponse response) { ActorMessageSender actorMessageSender; if (!self.requestCallback.TryGetValue(response.RpcId, out actorMessageSender)) { Log.Error($"not found rpc, maybe request timeout, response message: {StringHelper.MessageToStr(response)}"); return; } self.requestCallback.Remove(response.RpcId); actorMessageSender.Callback(response); }
public static void Run(ActorMessageSender self, IActorResponse response) { if (response.Error == ErrorCore.ERR_ActorTimeout) { self.Tcs.SetException(new Exception($"Rpc error: request, 注意Actor消息超时,请注意查看是否死锁或者没有reply: actorId: {self.ActorId} {self.MemoryStream.ToActorMessage()}, response: {response}")); return; } if (self.NeedException && ErrorCore.IsRpcNeedThrowException(response.Error)) { self.Tcs.SetException(new Exception($"Rpc error: actorId: {self.ActorId} request: {self.MemoryStream.ToActorMessage()}, response: {response}")); return; } self.Tcs.SetResult(response); }
private static async Task RunTask(this ActorLocationSender self, ActorTask task) { ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId); IActorResponse response = await actorMessageSender.Call(task.ActorRequest); // 发送成功 switch (response.Error) { case ErrorCode.ERR_NotFoundActor: // 如果没找到Actor,重试 ++self.FailTimes; // 失败MaxFailTimes次则清空actor发送队列,返回失败 if (self.FailTimes > ActorLocationSender.MaxFailTimes) { // 失败直接删除actorproxy Log.Info($"actor send message fail, actorid: {self.Id}"); self.RunError(response.Error); self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); return; } // 等待0.5s再发送 await Game.Scene.GetComponent <TimerComponent>().WaitAsync(500); self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id); self.Address = StartConfigComponent.Instance .Get(IdGenerater.GetAppIdFromId(self.ActorId)) .GetComponent <InnerConfig>().IPEndPoint; self.AllowGet(); return; case ErrorCode.ERR_ActorNoMailBoxComponent: self.RunError(response.Error); self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); return; default: self.LastSendTime = TimeHelper.Now(); self.FailTimes = 0; self.WaitingTasks.Dequeue(); task.Tcs?.SetResult(response); return; } }
public static void HandleIActorResponse(ushort opcode, long actorId, IActorResponse iActorResponse) { ActorMessageSenderComponent.Instance.RunMessage(actorId, iActorResponse); }
private static void FailResponse(IActorRequest iActorRequest, int error, Action <IActorResponse> reply) { IActorResponse response = ActorHelper.CreateResponse(iActorRequest, error); reply.Invoke(response); }
public static async ETVoid HandleIActorResponse(Session session, IActorResponse iActorResponse) { ActorMessageSenderComponent.Instance.RunMessage(iActorResponse); }
private static async ETTask <IActorResponse> CallInner(this ActorLocationSenderComponent self, ActorLocationSender actorLocationSender, int rpcId, MemoryStream memoryStream) { int failTimes = 0; long instanceId = actorLocationSender.InstanceId; actorLocationSender.LastSendOrRecvTime = TimeHelper.ServerNow(); while (true) { if (actorLocationSender.ActorId == 0) { actorLocationSender.ActorId = await LocationProxyComponent.Instance.Get(actorLocationSender.Id); if (actorLocationSender.InstanceId != instanceId) { throw new RpcException(ErrorCore.ERR_ActorLocationSenderTimeout2, $"{memoryStream.ToActorMessage()}"); } } if (actorLocationSender.ActorId == 0) { IActorRequest iActorRequest = (IActorRequest)memoryStream.ToActorMessage(); return(ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor)); } IActorResponse response = await ActorMessageSenderComponent.Instance.Call(actorLocationSender.ActorId, rpcId, memoryStream, false); if (actorLocationSender.InstanceId != instanceId) { throw new RpcException(ErrorCore.ERR_ActorLocationSenderTimeout3, $"{memoryStream.ToActorMessage()}"); } switch (response.Error) { case ErrorCore.ERR_NotFoundActor: { // 如果没找到Actor,重试 ++failTimes; if (failTimes > 20) { Log.Debug($"actor send message fail, actorid: {actorLocationSender.Id}"); actorLocationSender.Error = ErrorCore.ERR_NotFoundActor; // 这里不能删除actor,要让后面等待发送的消息也返回ERR_NotFoundActor,直到超时删除 return(response); } // 等待0.5s再发送 await TimerComponent.Instance.WaitAsync(500); if (actorLocationSender.InstanceId != instanceId) { throw new RpcException(ErrorCore.ERR_ActorLocationSenderTimeout4, $"{memoryStream.ToActorMessage()}"); } actorLocationSender.ActorId = 0; continue; } case ErrorCore.ERR_ActorTimeout: { throw new RpcException(response.Error, $"{memoryStream.ToActorMessage()}"); } } if (ErrorCore.IsRpcNeedThrowException(response.Error)) { throw new RpcException(response.Error, $"Message: {response.Message} Request: {memoryStream.ToActorMessage()}"); } return(response); } }
public static void RunMessage(this ActorMessageSenderComponent self, long actorId, IActorResponse response) { ActorMessageSender actorMessageSender; if (!self.requestCallback.TryGetValue(response.RpcId, out actorMessageSender)) { return; } self.requestCallback.Remove(response.RpcId); Run(actorMessageSender, response); }
private static async ETTask <IActorResponse> Run(this ActorLocationSender self, IActorRequest iActorRequest) { long instanceId = self.InstanceId; using (await CoroutineLockComponent.Instance.Wait(self.Id)) { if (self.InstanceId != instanceId) { throw new RpcException(ErrorCode.ERR_ActorRemove, ""); } ActorMessageSender actorMessageSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(self.ActorId); try { // ERR_NotFoundActor是需要抛异常的,但是这里不能抛 IActorResponse response = await actorMessageSender.CallWithoutException(iActorRequest); switch (response.Error) { case ErrorCode.ERR_NotFoundActor: // 如果没找到Actor,重试 ++self.FailTimes; // 失败MaxFailTimes次则清空actor发送队列,返回失败 if (self.FailTimes > ActorLocationSender.MaxFailTimes) { // 失败直接删除actorproxy Log.Info($"actor send message fail, actorid: {self.Id}"); self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); throw new RpcException(response.Error, ""); } // 等待0.5s再发送 await Game.Scene.GetComponent <TimerComponent>().WaitAsync(500); if (self.InstanceId != instanceId) { throw new RpcException(ErrorCode.ERR_ActorRemove, ""); } self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id); IActorResponse iActorResponse = await Run(self, iActorRequest); if (self.InstanceId != instanceId) { throw new RpcException(ErrorCode.ERR_ActorRemove, ""); } return(iActorResponse); case ErrorCode.ERR_ActorNoMailBoxComponent: self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); throw new RpcException(response.Error, ""); default: self.LastRecvTime = TimeHelper.Now(); self.FailTimes = 0; break; } return(response); } catch (Exception) { self.GetParent <ActorLocationSenderComponent>().Remove(self.Id); throw; } } }