ET服务端 怎么写正常的关服流程?http/rpc/终端等接收停服指令,断开客户端连接,通知缓存服把剩余数据实时入库?销毁各个组件?对应修改ET6 哪些文件?

文件夹:Server/Hotfix/Module/Console/
先推荐阅读一下ReloadConfigConsoleHandler.cs的代码

写GM指令,我是这样的:
1、Server\Model\Module\Console\ConsoleComponent
在头部先定义一个自己的标签

public const string UserTodo = “U”;

2、在Server/Hotfix/Module/Console/ 新建一个CS文件
UserTodoConsoleHandler.cs

[ConsoleHandler(ConsoleMode.UserTodo)]
    public class UserTodoConsoleHandler : IConsoleHandler
    {
        public async ETTask Run(ModeContex contex, string content)
        {
            switch (content)
            {
                case ConsoleMode.UserTodo:
                    contex.Parent.RemoveComponent<ModeContex>();                    
                    break;
                default:
                    string[] ss = content.Split(" ");
                    string name = ss[1];
                    string itemName = ss[2];
                    int itemCount = 1;
                    if (ss[3] != "") itemCount = Convert.ToInt32(ss[3]);
                    UnitComponent unitCom = null;
                    foreach (Entity e in Game.Scene.Children.Values)
                    {
                        if (e is Scene)
                        {
                            if (((Scene)e).Name == "Map1")
                            {
                                unitCom = ((Scene)e).GetComponent<UnitComponent>();
                            }
                        }
                    }
                    if (unitCom == null) return;
                    //ID为6的地图服务器
                    // Scene scene = Game.Scene.Get(StartSceneConfigCategory.Instance.Get(6).InstanceId);

                    foreach (Entity e in unitCom.Children.Values)
                    {
                        if (e is Unit)
                        {
                            Unit u = (Unit)e;
                            if (u.SubInfo.Name == name)
                            {
                                if (u.GetComponent<UserComponent>().Userdata.AddNewItem(itemName, itemCount))
                                {
                                    Log.Console(itemName + " 已成功添加给" + name + itemCount.ToString());
                                    return;
                                }
                                else
                                {
                                    Log.Console(itemName + " 添加给" + name + " 失败");
                                    return;
                                }
                            }
                        }
                    }
                    Log.Console(name + " 不在线");

                    break;
            }

            await ETTask.CompletedTask;
        }
    }

使用方法就是在服务端控制台输入:U 玩家名字 物品名 1
就会给玩家添加一个物品

如果要关服的话
1、先断开所有玩家的连接——我的UserComponent会自动储存数据,你可以自己先保存数据,再断开连接
2、保存服务器公共数据
3、终止进程
上面都是实现功能的代码,真实环境下肯定要做更严谨的处理,仅做参考

    做个gm帐号,也是一个普通游戏帐号,但是有gm权限可以响应gm消息指令,这个帐号发送消息给服务端,服务端收到就踢所有玩家下线。玩家下线就存数据库。下线完之后再通知中心服存库。所有操作完成,自己手动kill掉进程就行了

      3 个月 后

      langligelang 走console的话, 那进程启动不得开放console,每次操作得上服务器输入指令?(还没部署过外网,不太清楚console在linux上面是咋样操作的) 走http会不会好一些?

      egametang 手动关闭进程,能否通过watcher进程来关闭其他的进程。 我新增了一个http进程,尝试通过http进程给watcher进程发消息,来关闭进程。 但是不知道怎么给守护进程发消息?

        9 个月 后

        egametang 我也在弄这个,最后给watcher发消息,我创建session,一发就Dispose。😃
        最后我把加在Watcher的NetInnerComponent改成NetServerComponent了。。

          egametang 真的是把NetInnerComponent改成NetServerComponent吗🤣
          我搞了半天

            NetInnerComponent是用来发actor消息的 NetServerComponent才是做原始的session连接

            IxbxAx 你是从http给watcher发消息么,也可以发actor消息,不过需要修改下ActorId的生成规则。之前是随机生成的,这样可以直接发送actor消息给指定进程。不知道会不会存在坑(应该没有id为0的场景,这样应该不存在重复的问题)😀

              evalli 这么弄会不会所有进程的InstanceId都一样🙄

                evalli 那比如服务器用了两台机器,两台机器各有一个watcher进程,这样的话watcher的InstanceId就一样了吧。😨

                  IxbxAx 是的, 如果想用同样的进程id启动,那就再多加个参数,一起生成instanceId就行了,保证全局唯一就好了

                  说点什么吧...