任务13:后端-注册登录需要创建的组件类与打开OuterMessageDispatcher分发注释

本节课开始前:我们来看服务端是怎么创建 Session的

public void OnAccept(AChannel channel)
        {
            Session session = ComponentFactory.CreateWithParent<Session, AChannel>(this, channel);
            this.sessions.Add(session.Id, session);
            session.Start();
        }

目前还不需要太明白原理,先知道服务端只要收到消息或请求,他就会调用这个OnAccept方法,我们可以看到这里创建了一个Session,并且用这个session的id作为key,存到了sessions集合中。

ET是通过Channel (通信通道)实时同步消息的,一个信道是一个用户的实时连接,搭配一个session。Channel实时在同步,拿到消息后由session分发消息(有时候是直接返回给客户端,有时要转分发给Map、Gate),当然session也负责发起消息与请求。

因为Session是通信的核心类,需要建立一个Session的正确思路,所以上面交待了一下他的背景。

为了实现用户登录注册,我们前面讲了安装好MongoDB,在服务端项目中创建了数据相关的实体类AccountInfo,UserInfo,网关实体类:User,地图实体类:Gamer,Room。

本节课我们继续来做所需要的组件类。

网关组件 UserComponent,SessionUserComponent,SessionKeyComponent

UserComponent很简单,提供了Dictionary<long, User> idUsers来存放所有的User

还有Add,Get,Remove,GetAll几个增,减,获取某个User或全部User的方法。

UserComponent.cs 

\Server\ET.Core\Landlords\Component\UserComponent.cs

using System.Collections.Generic;
using System.Linq;

namespace ETModel
{
    /// <summary>
    /// 在线User对象管理组件
    /// </summary>
    public class UserComponent : Component
    {
        private readonly Dictionary<long, User> idUsers = new Dictionary<long, User>();

        /// <summary>
        /// 添加User对象
        /// </summary>
        /// <param name="user"></param>
        public void Add(User user)
        {
            if(Get(user.UserID) == null)
            {
                this.idUsers.Add(user.UserID, user);
            }
            else
            {
                Log.Error("重复登录!");
            }
        }

        /// <summary>
        /// 获取User对象
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public User Get(long id)
        {
            this.idUsers.TryGetValue(id, out User gamer);
            return gamer;
        }

        /// <summary>
        /// 移除User对象
        /// </summary>
        /// <param name="id"></param>
        public void Remove(long id)
        {
            this.idUsers.Remove(id);
        }

        /// <summary>
        /// User对象总数量
        /// </summary>
        public int Count
        {
            get
            {
                return this.idUsers.Count;
            }
        }

        /// <summary>
        /// 获取所有User对象
        /// </summary>
        /// <returns></returns>
        public User[] GetAll()
        {
            return this.idUsers.Values.ToArray();
        }

        public override void Dispose()
        {
            if (this.IsDisposed)
            {
                return;
            }

            base.Dispose();

            foreach (User user in this.idUsers.Values)
            {
                user.Dispose();
            }
        }
    }
}

SessionUserComponent.cs 

\Server\ET.Core\Landlords\Component\SessionUserComponent.cs

也好理解,这个组件是Add到Session对象上的,就提供了

public User User { get; set; } 很明显就是把User与Seesion绑定起来,以供使用。

using System.Net;

namespace ETModel
{
    /// <summary>
    /// Gate服务器上 Session关联User对象组件
    /// 用于Session断开时触发下线
    /// </summary>
    public class SessionUserComponent : Component
    {
        //Gate服务器上 Session绑定的User对象
        public User User { get; set; }
    }
}

SessionKeyComponent.cs

\Server\ET.Core\Landlords\Component\SessionKeyComponent.cs

下节课我们就会讲到用户登录的实现过程,先到到网关gate请求登录,验证账号名密码后,就会到realm上获得一个sessionKey,这说明你是认证过的合法用户了,SessionKeyComponent就是用这个sessionKey作为key,UserID作为值存起来了,这样就能识别非法请求,一概不理或作处理。

using System.Collections.Generic;

namespace ETModel
{
    public class SessionKeyComponent : Component
    {
        private readonly Dictionary<long, long> sessionKey = new Dictionary<long, long>();
        
        public void Add(long key, long userId)
        {
            this.sessionKey.Add(key, userId);
            this.TimeoutRemoveKey(key);
        }

        public long Get(long key)
        {
            long userId;
            this.sessionKey.TryGetValue(key, out userId);
            return userId;
        }

        public void Remove(long key)
        {
            this.sessionKey.Remove(key);
        }

        private async void TimeoutRemoveKey(long key)
        {
            await Game.Scene.GetComponent<TimerComponent>().WaitAsync(20000);
            this.sessionKey.Remove(key);
        }
    }
}

Map上的组件 LandlordsComponent

本节作为了解,先知道他的存在,因为登录、注册还不用进入地图,所以先不详细介绍,暂时用不到。

realm组件 OnlineComponent

这个组件有一个 Dictionary<long, int> dictionary,用来存UserID和gateAppID,记录在线用户。

可以用这个组件添加的移除在线用户,获取用户的网关gateAppID。

\Server\ET.Core\Landlords\Component\OnlineComponent.cs

using System.Collections.Generic;

namespace ETModel
{
    /// <summary>
    /// 在线组件,用于记录在线玩家 无扩展
    /// </summary>
    public class OnlineComponent : Component
    {
        /// <summary>
        /// 参数1:永久UserID 参数2:User对应Player所在的Gate的app编号
        /// </summary>
        private readonly Dictionary<long, int> dictionary = new Dictionary<long, int>();

        /// <summary>
        /// 添加在线玩家 参数1:永久Id 参数2:所在Gate的app编号
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="gateAppId"></param>
        public void Add(long userId, int gateAppId)
        {
            dictionary.Add(userId, gateAppId);
        }

        /// <summary>
        /// 获取在线玩家网关服务器ID
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public int GetGateAppId(long userId)
        {
            int gateAppId;
            dictionary.TryGetValue(userId, out gateAppId);
            return gateAppId;
        }

        /// <summary>
        /// 移除在线玩家
        /// </summary>
        /// <param name="userId"></param>
        public void Remove(long userId)
        {
            dictionary.Remove(userId);
        }
    }
}

[很重要!]有了前面创建的实体与组件类,打开OuterMessageDispatcher类中的下图所示注释

\Server\Hotfix\Module\Message\OuterMessageDispatcher.cs

数据组件 DBProxyComponent

这个组件框架在ET.Core\Module\DB目录提供了,我们操作MongoDB就要用到,下节课的内容。

通过过去这两节课,我们就准备好了注册,登录功能需要的实体类与组件类了,我们只需要在下节课,通过实现前端的请求+后端对应请求的System、处理Handler,就能完成登录注册功能了,掌握并且完成好后,今后的网络通信功能都是类似的ECS结构。

随着功能增加,实操应用增加,你会越来越熟悉、灵活使用,并且前面不太理解的东西会得到印证变得比较理解。

posted @ 2023-02-01 09:47  Domefy  阅读(24)  评论(0编辑  收藏  举报