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 async void UpdateAsync(this ActorLocationSender self) { try { long instanceId = self.InstanceId; while (true) { if (self.InstanceId != instanceId) { return; } ActorTask actorTask = await self.GetAsync(); if (self.InstanceId != instanceId) { return; } if (actorTask.ActorRequest == null) { return; } await self.RunTask(actorTask); } } catch (Exception e) { Log.Error(e); } }
public static async void DisconnectPlayer(Player player) { if (player == null) { return; } Log.Info($"DisconnectPlayer Start, uid:{player.uid}"); // 向MapServer發送斷線訊息 if (player.InRoom()) { ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(player.mapUnitId); actorLocationSender.Send(new L2M_SessionDisconnect()); // Player移除mapUnitId player.LeaveRoom(); } player.isOnDisconnectingStage = true; // 更新Player await Game.Scene.GetComponent <PlayerComponent>().Update(player); Log.Info($"DisconnectPlayer End, uid:{player.uid}"); }
public static async ETTask GetActorId(this ActorLocationSender self) { using (await CoroutineLockComponent.Instance.Wait(self.Id)) { self.ActorId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(self.Id); } }
public static ActorLocationSender ActorLocation(long unitId) { /// 得到 ActorLocat ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId); return(actorLocationSender); }
/// <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 ETVoid DestroyAsync(SessionPlayerComponent self) { // 发送断线消息 ActorLocationSender actorLocationSender = await Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId); actorLocationSender.Send(new G2M_SessionDisconnect()).Coroutine(); Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id); }
/// <summary> /// 死亡判断 后结算 /// </summary> /// <param name="unit"></param> public static void RemoveUnit(this AttackComponent self) { Console.WriteLine(" AttackComponentHelper-172- type: " + self.GetParent <Unit>().UnitType + " 删除单元 Unit。"); ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.GetParent <Unit>().Id); actorLocationSender.Send(new Death_Map()); }
public override void Destroy(SessionPlayerComponent self) { // 发送断线消息 根据账号里的角色单元ID 获得 与MAP服务器通讯的 会话ActorMessageSender ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId); actorLocationSender.Send(new G2M_SessionDisconnect()); //给map服务器发送断线消息 Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id); //移除用户管理中的账号 }
public override void Destroy(SessionPlayerComponent self) { // 发送断线消息 ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId); _ = actorLocationSender.Send(new G2M_SessionDisconnect()); Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id); }
public async void Dispatch(Session session, ushort opcode, object message) { try { switch (message) { case IActorLocationRequest actorLocationRequest: // gate session收到actor rpc消息,先向actor 发送rpc请求,再将请求结果返回客户端 { long actorId = session.GetComponent <SessionUserComponent>().User.ActorID; ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(actorId); int rpcId = actorLocationRequest.RpcId; // 这里要保存客户端的rpcId IResponse response = await actorLocationSender.Call(actorLocationRequest); response.RpcId = rpcId; session.Reply(response); return; } case IActorLocationMessage actorLocationMessage: { long actorId = session.GetComponent <SessionUserComponent>().User.ActorID; ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(actorId); actorLocationSender.Send(actorLocationMessage); return; } case IActorRequest iActorRequest: { long actorId = session.GetComponent <SessionUserComponent>().User.ActorID; ActorMessageSender actorSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(actorId); int rpcId = iActorRequest.RpcId; // 这里要保存客户端的rpcId IResponse response = await actorSender.Call(iActorRequest); response.RpcId = rpcId; session.Reply(response); return; } case IActorMessage iactorMessage: { long actorId = session.GetComponent <SessionUserComponent>().User.ActorID; ActorMessageSender actorSender = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(actorId); actorSender.Send(iactorMessage); return; } } Game.Scene.GetComponent <MessageDispatherComponent>().Handle(session, new MessageInfo(opcode, message)); } catch (Exception e) { Log.Error(e); } }
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 async ETVoid Send(this ActorLocationSender self, IActorLocationMessage request) { if (request == null) { throw new Exception($"actor location send message is null"); } await Run(self, request); }
/// <summary> /// 发送巡逻目标点坐标 消息 /// </summary> /// <param name="self"></param> static void SendPatrolPosition(this PatrolComponent self) { /// 休息时间到 开始发送巡逻目标点坐标 消息 self.patrolMap = self.GetPatrolMap(); self.goalPoint = self.patrolPoint; ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.GetParent <Unit>().Id); actorLocationSender.Send(self.patrolMap); }
public static void RunError(this ActorLocationSender self, int errorCode) { while (self.WaitingTasks.Count > 0) { ActorTask actorTask = self.WaitingTasks.Dequeue(); actorTask.Tcs?.SetException(new RpcException(errorCode, "")); } self.WaitingTasks.Clear(); }
public static async ETTask <IActorLocationResponse> Call(this ActorLocationSender self, IActorLocationRequest request) { if (request == null) { throw new Exception($"actor location call message is null"); } return(await Run(self, request) as IActorLocationResponse); }
public static void Send(this ActorLocationSender self, IActorLocationMessage request) { if (request == null) { throw new Exception($"actor location send message is null"); } self.Run(request).Coroutine(); }
public static void Send(this ActorLocationSender self, IActorLocationMessage request) { if (request == null) { throw new Exception($"actor location send message is null"); } ActorTask task = new ActorTask(request); self.Add(task); }
/// <summary> /// 发送追击目标坐标 消息 /// </summary> /// <param name="self"></param> public static void SendSeePosition(this SeekComponent self) { // 发送一次目标点坐标 消息 self.seeMap = self.GetSeeMap(); if (self.seeMap != null) { ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get((self.Parent as Unit).Id); actorLocationSender.Send(self.seeMap); } }
/// <summary> /// 从队列里面取出一个消息进行处理 /// </summary> /// <param name="self"></param> /// <returns></returns> private static Task <ActorTask> GetAsync(this ActorLocationSender self) { if (self.WaitingTasks.Count > 0) { ActorTask task = self.WaitingTasks.Peek(); return(Task.FromResult(task)); //创建一个带返回值的、已完成的异步任务,其参数是取出的Task。 } self.Tcs = new TaskCompletionSource <ActorTask>(); //如果棧里面有消息 这里是不会执行的,只有当站里面没有消息,程序就会在这里等待 知道加入了新的消息 继续 return(self.Tcs.Task); //检测当前是否可以取堆栈里面缓存的消息 }
private static Task <ActorTask> GetAsync(this ActorLocationSender self) { if (self.WaitingTasks.Count > 0) { ActorTask task = self.WaitingTasks.Peek(); return(Task.FromResult(task)); } self.Tcs = new TaskCompletionSource <ActorTask>(); return(self.Tcs.Task); }
public static Task <IActorLocationResponse> Call(this ActorLocationSender self, IActorLocationRequest request) { if (request == null) { throw new Exception($"actor location call message is null"); } TaskCompletionSource <IActorLocationResponse> tcs = new TaskCompletionSource <IActorLocationResponse>(); ActorTask task = new ActorTask(request, tcs); self.Add(task); return(task.Tcs.Task); }
public async ETVoid DispatchAsync(Session session, ushort opcode, object message) { // 根据消息接口判断是不是Actor消息,不同的接口做不同的处理 switch (message) { case IActorLocationRequest actorLocationRequest: // gate session收到actor rpc消息,先向actor 发送rpc请求,再将请求结果返回客户端 { long unitId = session.GetComponent <SessionPlayerComponent>().Player.MapInstanceId; ActorLocationSender actorLocationSender = await Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId); int rpcId = actorLocationRequest.RpcId; // 这里要保存客户端的rpcId long instanceId = session.InstanceId; IResponse response = await actorLocationSender.Call(actorLocationRequest); response.RpcId = rpcId; // session可能已经断开了,所以这里需要判断 if (session.InstanceId == instanceId) { session.Reply(response); } break; } case IActorLocationMessage actorLocationMessage: { long unitId = session.GetComponent <SessionPlayerComponent>().Player.MapInstanceId; ActorLocationSender actorLocationSender = await Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId); actorLocationSender.Send(actorLocationMessage).Coroutine(); break; } case IActorRequest actorRequest: // 分发IActorRequest消息,目前没有用到,需要的自己添加 { break; } case IActorMessage actorMessage: // 分发IActorMessage消息,目前没有用到,需要的自己添加 { break; } default: { // 非Actor消息 Game.Scene.GetComponent <MessageDispatcherComponent>().Handle(session, new MessageInfo(opcode, message)); break; } } }
public async void Dispatch(Session session, ushort opcode, object message) { try { switch (message) { case IFrameMessage iFrameMessage: // 如果是帧消息,构造成OneFrameMessage发给对应的unit { long unitId = session.GetComponent <SessionPlayerComponent>().Player.UnitId; ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId); // 这里设置了帧消息的id,防止客户端伪造 iFrameMessage.Id = unitId; OneFrameMessage oneFrameMessage = new OneFrameMessage { Op = opcode, AMessage = ByteString.CopyFrom(session.Network.MessagePacker.SerializeTo(iFrameMessage)) }; actorLocationSender.Send(oneFrameMessage); return; } case IActorLocationRequest actorLocationRequest: // gate session收到actor rpc消息,先向actor 发送rpc请求,再将请求结果返回客户端 { long unitId = session.GetComponent <SessionPlayerComponent>().Player.UnitId; ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId); int rpcId = actorLocationRequest.RpcId; // 这里要保存客户端的rpcId IResponse response = await actorLocationSender.Call(actorLocationRequest); response.RpcId = rpcId; session.Reply(response); return; } case IActorLocationMessage actorLocationMessage: { long unitId = session.GetComponent <SessionPlayerComponent>().Player.UnitId; ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(unitId); actorLocationSender.Send(actorLocationMessage); return; } } Game.Scene.GetComponent <MessageDispatherComponent>().Handle(session, new MessageInfo(opcode, message)); } catch (Exception e) { Log.Error(e); } }
public override void Destroy(SessionPlayerComponent self) { // 发送断线消息 long id = self.Player.UnitId == 0L? self.Player.TankId : self.Player.UnitId; if (id != 0) { ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(id); //actorLocationSender.Send(new G2M_SessionDisconnect()); actorLocationSender.Send(new G2B_SessionDisconnect()); } Game.Scene.GetComponent <PlayerComponent>()?.Remove(self.Player.Id); }
public override void Destroy(SessionPlayerComponent self) { // 发送断线消息 ActorLocationSender actorLocationSender = Game.Scene.GetComponent <ActorLocationSenderComponent>().Get(self.Player.UnitId); actorLocationSender.Send(new G2M_SessionDisconnect()); ///20190621 下线或断线后,自动删除unit Game.Scene.GetComponent <UnitComponent>()?.Remove(self.Player.UnitId); ///20190804 下线或断线后,不自动删除Player //Game.Scene.GetComponent<PlayerComponent>()?.Remove(self.Player.Id); }
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, $"{MongoHelper.ToJson(iActorRequest)}"); } return(await self.RunInner(iActorRequest)); } }
private static void AllowGet(this ActorLocationSender self) { if (self.Tcs == null || self.WaitingTasks.Count <= 0) { return; } ActorTask task = self.WaitingTasks.Peek(); var t = self.Tcs; self.Tcs = null; t.SetResult(task); }
private static void Add(this ActorLocationSender self, ActorTask task) { if (self.IsDisposed) { throw new Exception("ActorLocationSender Disposed! dont hold ActorMessageSender"); } self.WaitingTasks.Enqueue(task); // failtimes > 0表示正在重试,这时候不能加到正在发送队列 if (self.FailTimes == 0) { self.AllowGet(); } }
/// <summary> /// /检测当前是否可以取堆栈里面缓存的消息 /// </summary> /// <param name="self"></param> private static void AllowGet(this ActorLocationSender self) { ///没有缓存消息 跳出 表示不可以取棧里数据 if (self.Tcs == null || self.WaitingTasks.Count <= 0) { return; } ActorTask task = self.WaitingTasks.Peek(); //取出第一个 但不移除 var t = self.Tcs; self.Tcs = null; t.SetResult(task); //设置了值 说明可以取了 }