ET框架---SessionUserComponent学习笔记

SessionUserComponent

请大家关注我的微博:@NormanLin_BadPixel坏像素


我们一眼就看到了作者的注释。

/// <summary>
/// Session关联User对象组件
/// 用于Session断开时触发下线
/// </summary>
 public class SessionUserComponent : Component
    {
        // User对象
        public User User { get; set; }
        ...
    }

这个User属性会在添加这个组件的时候赋值。既在客户端发送登陆请求,在Gate服务器登陆时创建的User对象。同时会创建Gate服务器与客户端之间的会话Session,在这个Session上会添加这个组件并把前面创建的User对象赋值给SessionUserComponent.User。具体过程可以看通过注册登陆请求走一遍简单的消息传输

//释放User对象时将User对象从管理组件中移除
Game.Scene.GetComponent<UserComponent>()?.Remove(this.User.UserID);

之前创建User对象的时候把它记录在UserComponent里面,现在玩家退出,要把这条记录移除。

//正在匹配中发送玩家退出匹配请求
if (this.User.IsMatching)
{
    IPEndPoint matchIPEndPoint = config.MatchConfig.GetComponent<InnerConfig>().IPEndPoint;
    Session matchSession = Game.Scene.GetComponent<NetInnerComponent>().Get(matchIPEndPoint);
    await matchSession.Call(new G2M_PlayerExitMatch_Req() { UserID = this.User.UserID });
}

嗯,向匹配服务器发送玩家退出匹配的请求。我们去看看怎么处理。

protected override void Run(Session session, G2M_PlayerExitMatch_Req message, Action<M2G_PlayerExitMatch_Ack> reply)
{
    M2G_PlayerExitMatch_Ack response = new M2G_PlayerExitMatch_Ack();
    try
    {
        Matcher matcher = Game.Scene.GetComponent<MatcherComponent>().Remove(message.UserID);
        matcher?.Dispose();
        Log.Info($"玩家{message.UserID}退出匹配队列");

        reply(response);
    }
    catch (Exception e)
    {
        ReplyError(response, e, reply);
    }
}

不深究了,MatcherComponent我们学习过了。

//正在游戏中发送玩家退出房间请求
if(this.User.ActorID != 0)
{
    ActorProxy actorProxy = actorProxyComponent.Get(this.User.ActorID);
    await actorProxy.Call(new Actor_PlayerExitRoom_Req() { UserID = this.User.UserID });
}

之前我们把消息发送给匹配服务器,现在我们要把消息发送给指定的玩家角色。不过这个玩家角色具体在那个服务器上,我们不知道,所以我们通过ActorProxy去发送消息。

而接收Actor消息的服务器,是用NetInnerComponent监听接收端口的,并且用InnerMessageDispatcher处理消息。

// 收到actor rpc request
if (message is ActorRequest actorRpcRequest)
{
    Entity entity = Game.Scene.GetComponent<ActorManagerComponent>().Get(actorRpcRequest.Id);
    if (entity == null)
    {
        Log.Warning($"not found actor: {actorRpcRequest.Id}");
        ActorResponse response = new ActorResponse
        {
            Error = ErrorCode.ERR_NotFoundActor
        };
        session.Reply(packetInfo.RpcId, response);
        return;
    }

    entity.GetComponent<ActorComponent>().Add(new ActorMessageInfo() { Session = session, RpcId = packetInfo.RpcId, Message = actorRpcRequest });
    return;
}

我们看到,它会通过ID精准找到需要处理消息的对象,并把消息添加入ActorComponent内的任务待办任务队列中。

我们可以在Actor_PlayerExitRoom_ReqHandler里面找到对这个消息的处理,我们就不深究了。

//向登录服务器发送玩家下线消息
IPEndPoint realmIPEndPoint = config.RealmConfig.GetComponent<InnerConfig>().IPEndPoint;
Session realmSession = Game.Scene.GetComponent<NetInnerComponent>().Get(realmIPEndPoint);
realmSession.Send(new G2R_PlayerOffline_Ntt() { UserID = this.User.UserID });

this.User.Dispose();
this.User = null;

我们看看登陆服务器的处理。

protected override void Run(Session session, G2R_PlayerOffline_Ntt message)
{
    //玩家下线
    Game.Scene.GetComponent<OnlineComponent>().Remove(message.UserID);
    Log.Info($"玩家{message.UserID}下线");
}

很简单。

猜你喜欢

转载自blog.csdn.net/norman_lin/article/details/79991181