static async Task triggerTimer(long actorId, string actorType, string handlerType, Param param) { try { var handler = HotfixMgr.GetInstance <ITimerHandler>(handlerType); var agentType = handler.GetType().BaseType.GenericTypeArguments[0]; if (agentType.GetInterface(typeof(IComponentActorAgent).FullName) != null) { //actor var agent = await ActorManager.GetOrNew(agentType, actorId); var actor = (ComponentActor)agent.Owner; _ = actor.SendAsync(() => handler.InternalHandleTimer(agent, param), false); } else if (agentType.GetInterface(typeof(IComponentAgent).FullName) != null) { //component var actorAgentType = HotfixMgr.GetType(actorType, agentType); var compType = agentType.BaseType.GenericTypeArguments[0]; var agent = await ActorManager.GetOrNew(actorAgentType, actorId); var actor = (ComponentActor)agent.Owner; var comp = await actor.GetComponent(compType); _ = actor.SendAsync(() => handler.InternalHandleTimer(comp.GetAgent(agentType), param), false); } } catch (Exception e) { LOGGER.Error(e.ToString()); } }
public static async Task Remove(Channel channel) { if (channel != null) { channels.TryRemove(channel.Id, out var se); if (se == null) { return; } LOGGER.Info("移除channel {}", channel.Id); var actor = await ActorManager.Get <ComponentActor>(channel.Id); if (actor != null) { if (actor is IChannel chl) { _ = actor.SendAsync(chl.OnDisconnect); } if (actor.TransformAgent <IChannel>(out var chAgent)) { _ = actor.SendAsync(chAgent.OnDisconnect); } } } }
protected override void ChannelRead0(IChannelHandlerContext ctx, IMessage msg) { if (!Settings.Ins.AppRunning) { return; } //直接在当前io线程处理 IEventLoop group = ctx.Channel.EventLoop; group.Execute(async() => { var handler = TcpHandlerFactory.GetHandler(msg.GetMsgId()); LOGGER.Debug($"-------------server msg {msg.GetMsgId()} {msg.GetType()}"); if (handler == null) { LOGGER.Error("找不到对应的handler " + msg.GetMsgId()); return; } //握手 var channel = ctx.Channel.GetAttribute(ChannelManager.Att_Channel).Get(); if (channel != null) { var actor = await ActorManager.Get <ComponentActor>(channel.Id); if (actor != null) { if (actor is IChannel ise) { _ = actor.SendAsync(ise.Hand); } if (actor.TransformAgent <IChannel>(out var seAgent)) { _ = actor.SendAsync(seAgent.Hand); } } } handler.Time = DateTime.Now; handler.Ctx = ctx; handler.Msg = msg; if (handler is TcpActorHandler actorHandler) { actorHandler.Actor = await actorHandler.CacheActor(); if (actorHandler.Actor != null) { await actorHandler.Actor.SendAsync(actorHandler.ActionAsync); } else { LOGGER.Error($"handler actor 为空 {msg.GetMsgId()} {handler.GetType()}"); } } else { await handler.ActionAsync(); } }); }
public async Task <bool> OnLoadSucceed(bool isReload) { try { HttpHandlerFactory.SetExtraHandlerGetter(HotfixMgr.GetHttpHandler); TcpHandlerFactory.SetExtraHandlerGetter(Geek.Server.Message.MsgFactory.Create, msgId => HotfixMgr.GetHandler <BaseTcpHandler>(msgId)); if (isReload) { //热更 LOGGER.Info("hotfix load success"); await ActorManager.ActorsForeach((actor) => { actor.SendAsync(actor.ClearCacheAgent, false); return(Task.CompletedTask); }); } else { //起服 if (!await Start()) { return(false); } } return(true); } catch (Exception e) { LOGGER.Fatal("OnLoadSucceed执行异常"); LOGGER.Fatal(e.ToString()); return(false); } }
public void DispatchEvent(int evtType, Func <int, TActor, Type, Task <bool> > checkDispatchFunc, Param param = null) { lineActor.SendAsync(async() => { if (!eventHandlers.ContainsKey(evtType)) { return; } Event evt = new Event(); evt.EventId = evtType; evt.Data = param; var list = eventHandlers[evtType]; foreach (var evtInfo in list) { var actor = await ActorManager.Get <TActor>(evtInfo.ActorId); if (actor == null) { continue; } var info = evtInfo; //需要存个临时变量 _ = actor.SendAsync(async() => { try { var handler = HotfixMgr.GetInstance <IEventListener>(info.AgentHandler); var agentType = handler.GetType().BaseType.GenericTypeArguments[0]; if (agentType.GetInterface(typeof(IComponentActorAgent).FullName) != null) { //actor if (checkDispatchFunc != null && !(await checkDispatchFunc(evtType, actor, null))) { return; } await handler.InternalHandleEvent(actor.GetAgent(agentType), evt); } else if (agentType.GetInterface(typeof(IComponentAgent).FullName) != null) { //component var compType = agentType.BaseType.GenericTypeArguments[0]; if (checkDispatchFunc != null && !(await checkDispatchFunc(evtType, actor, compType))) { return; } var comp = await actor.GetComponent(compType); await handler.InternalHandleEvent(actor.GetAgent(agentType), evt); } } catch (Exception e) { LOGGER.Error(e.ToString()); } }, false); } }, false); }
async Task <bool> Start() { try { LOGGER.Info("start server......"); await HttpServer.Start(Settings.Ins.HttpPort); await TcpServer.Start(Settings.Ins.TcpPort, Settings.Ins.UseLibuv); LOGGER.Info("init mongodb......" + Settings.Ins.MongoUrl); MongoDBConnection.Singleton.Connect(Settings.Ins.MongoDB, Settings.Ins.MongoUrl); LOGGER.Info("启动回存timer......"); GlobalDBTimer.Singleton.Start(); LOGGER.Info("注册所有组件......"); ComponentTools.RegistAllComps(); LOGGER.Info("load配置表..."); (bool success, string msg) = GameDataManager.ReloadAll(); if (!success) { return(false); } LOGGER.Info("激活所有全局actor..."); var taskList = new List <Task>(); taskList.Add(activeActorAndItsComps <ServerActorAgent>(ServerActorID.GetID(ActorType.Normal))); //激活其他全局actor await Task.WhenAll(taskList); var serverActor = await ActorManager.GetOrNew <ServerActorAgent>(ServerActorID.GetID(ActorType.Normal)); _ = serverActor.SendAsync(serverActor.CheckCrossDay); return(true); }catch (Exception e) { LOGGER.Fatal("起服失败\n" + e.ToString()); return(false); } }
/// <summary> /// actor永久消失,清除actor数据库数据,比如公会解散,玩家清档等 /// </summary> public async Task Dieout() { if (GetAgent() is IDeadable deadable) { await deadable.Dieout(); } ReadOnly = true; ConstCompTypeList.Clear(); await Deactive(); await ActorManager.Remove(ActorId, false); var list = ComponentMgr.Singleton.GetAllComps(this); var die = new DieoutComp(); die.Init(this); await die.Active(); await die.Dieout(list); }
public static async Task RemoveAll() { var taskList = new List <Task>(); var list = channels.Values; foreach (var ch in list) { _ = ch.Ctx.CloseAsync(); var actor = await ActorManager.Get <ComponentActor>(ch.Id); if (actor != null) { var task = actor.SendAsync(() => Task.Delay(1)); taskList.Add(task); } await Remove(ch); } //保证此函数执行完后所有actor队列为空 if (await Task.WhenAll(taskList).WaitAsync(TimeSpan.FromSeconds(30))) { LOGGER.Error("remove all channel timeout"); } }
public async Task <bool> Stop() { try { await QuartzTimer.Stop(); await ChannelManager.RemoveAll(); await GlobalDBTimer.Singleton.OnShutdown(); await ActorManager.RemoveAll(); await TcpServer.Stop(); await HttpServer.Stop(); return(true); }catch (Exception e) { LOGGER.Fatal(e.ToString()); return(false); } }
protected override void ChannelRead0(IChannelHandlerContext ctx, IMessage msg) { if (!Settings.Ins.AppRunning) { return; } //直接在当前io线程处理 IEventLoop group = ctx.Channel.EventLoop; group.Execute(async() => { try { var handler = TcpHandlerFactory.GetHandler(msg.GetMsgId()); LOGGER.Debug($"-------------get msg {msg.GetMsgId()} {msg.GetType()}"); if (handler == null) { LOGGER.Error("找不到对应的handler " + msg.GetMsgId()); return; } //握手 var channel = ctx.Channel.GetAttribute(ChannelManager.Att_Channel).Get(); if (channel != null) { var actor = await ActorManager.Get <ComponentActor>(channel.Id); if (actor != null) { if (actor is IChannel ise) { _ = actor.SendAsync(ise.Hand); } if (actor.TransformAgent <IChannel>(out var seAgent)) { _ = actor.SendAsync(seAgent.Hand); } } } handler.Time = DateTime.Now; handler.Ctx = ctx; handler.Msg = msg; if (handler.GetType().Assembly != msg.GetType().Assembly) { //仅热更瞬间有极小几率触发 LOGGER.Debug("热更过程替换msg和handler 重新构造msg让msg和handler来自同一个dll"); var data = msg.Serialize(); var newMsg = TcpHandlerFactory.GetMsg(msg.GetMsgId()); newMsg.Deserialize(data); handler.Msg = newMsg; } if (handler is TcpActorHandler actorHandler) { actorHandler.Actor = await actorHandler.CacheActor(); if (actorHandler.Actor != null) { await actorHandler.Actor.SendAsync(actorHandler.ActionAsync); } else { LOGGER.Error($"handler actor 为空 {msg.GetMsgId()} {handler.GetType()}"); } } else { await handler.ActionAsync(); } } catch (Exception e) { LOGGER.Error(e.ToString()); } }); }
async Task activeActorAndItsComps <TActorAgent>(long actorId) where TActorAgent : IComponentActorAgent { var actor = await ActorManager.GetOrNew <TActorAgent>(actorId); await((ComponentActor)actor.Owner).ActiveAllComps(); }
async Task timerLoop() { var random = new System.Random(); int onceDelta = 1000; int delayTime = 0; int saveTime = random.Next(Settings.Ins.DataFlushTimeMin, Settings.Ins.DataFlushTimeMax); while (delayTime < saveTime * 1000) { //不能一次性delay,退出程序时监听不到 await Task.Delay(onceDelta); delayTime += onceDelta; if (!Working) { break; } } while (Working) { var start = DateTime.Now; await StateComponent.TimerSave(); var delta = DateTime.Now - start; LOGGER.Info("db timer save state time:{}毫秒", delta.TotalMilliseconds); if (!Working) { break; } await ActorManager.CheckIdle(); delta = DateTime.Now - start; LOGGER.Info("db timer loop time:{}毫秒", delta.TotalMilliseconds); if (!Working) { break; } int delay = 10000; if (delta.TotalSeconds < saveTime) { delay = (saveTime - (int)delta.TotalSeconds) * 1000; } delayTime = 0; while (delayTime < delay) { await Task.Delay(onceDelta); delayTime += onceDelta; if (!Working) { break; } } } LOGGER.Info("exit db timer loop..."); }