ET框架---DBProxyComponent学习笔记(完善MessageDispatherComponent学习笔记)

DBProxyComponent

这个组件跟LocationProxyComponent很像,也是服务器之间通信的组件。而DBProxyComponent应该是跟管理数据库服务的服务器通信的组件。

我们看到,在添加该组件的时候会在Awake方法里面获取到数据库服务器所在的IP地址,之后每次代理发送的时候,会通过NetInnerComponent创建跟数据库服务器的会话,并发送请求。

我们知道,这个请求在服务器被接受时,最后会在DBCacheComponent执行,那么,它是怎么分发到DBCacheComponent的呢?这里,我们一起来探索一下。

首先,我们来回忆一下我们的消息分发组件MessageDispatherComponent。在这个组件里面,我们给所有有MessageHandlerAttribute特性并且实现IMHandler的类都注册了事件,事件名是通过iMHandler.GetMessageType()方法获取消息类型再通过OpcodeTypeComponent获取到的操作符。

Type messageType = iMHandler.GetMessageType();
ushort opcode = this.Entity.GetComponent<OpcodeTypeComponent>().GetOpcode(messageType);

这一段在之前的学习笔记里面漏讲了,其实还是很重要的。不过这里结合实例来讲比较容易理解。

我们看到,实现iMHandler接口的有两个类,AMHandleAMRpcHandle,这两个都是抽象类,前者用于接收消息并处理,后者不仅接收消息并处理,在处理结束后还会返回结果。我们需要注意的是,这两个抽象类的泛型跟GetMessageType方法。

public abstract class AMRpcHandler<Request, Response>: IMHandler where Request : class, IRequest where Response : class, IResponse 
...
public Type GetMessageType()
{
    return typeof (Request);
}
public abstract class AMHandler<Message> : IMHandler where Message : class
...
public Type GetMessageType()
{
    return typeof(Message);
}

我们看到,iMHandler.GetMessageType() 获取到的类是派生类的泛型类。这样会导致什么呢?

举个例子。

[Message(InnerOpcode.DBSaveRequest)]
[ProtoContract]
public partial class DBSaveRequest: IRequest

这是对数据库保存一条信息的请求,它的操作符是InnerOpcode.DBSaveRequest

[MessageHandler(AppType.DB)]
public class DBSaveRequestHandler : AMRpcHandler<DBSaveRequest, DBSaveResponse>

这是处理DBSaveRequest事件的类,在MessageDispatherComponent注册所有事件的时候,会查询到这个类有MessageHandler特性,并且实现了IMHandler接口,是AMRpcHandler的派生类嘛,而它所注册事件的名称,就是泛型DBSaveRequest的操作符InnerOpcode.DBSaveRequest。这样,当消息事件分发器接收到DBSaveRequest请求的时候,会把消息调度到DBSaveRequestHandler处理。

而我们之前对Session的学习也已经知道了发送消息时的打包方式,会记录消息的操作符。而接收到消息的时候,也会解析得到这个操作符,然后通过MessageDispatherComponent调度消息。忘记的去复习


至此,我们终于走完了消息创建-打包-发送-接收-解包-分发到相对应处理器处理的整个流程。

如果我们要自定义一个消息,怎么做呢?

  1. 确定这个消息是否是请求(需要回复)。如果需要回复,则实现IRequest接口并且定义自定义回复结构,继承IResponse。记得添加Message特性并且标注操作符,新的操作符可以添加到自定义枚举里。或者添加到InnerOpcodeOpcodeOuterOpcode里面。还得添加ProtoContract,这是Protobuf-net的用法。
  2. 定义消息结构,既消息的内容。消息的内容有必要的话得按照Protobuf-net的用法定义特性。
  3. 定义处理消息的类。根据消息类型继承AMRpcHandler或者AMHandler,并把消息类型当作泛型传入。处理消息的类需要添加MessageHandler特性并且标注AppType
  4. 具体的处理消息方法需要重写处理类的Run方法。

经过上面的步骤,我们的MessageDispatherComponentOpcodeTypeComponent就会识别这些类,并注册相应的事件。当我们接收到相应的消息时,也会正确分发给对应的处理器处理。


扯远了,我们来看看数据库操作相关的请求消息会分配会分配给谁处理。

[MessageHandler(AppType.DB)]
public class DBSaveRequestHandler : AMRpcHandler<DBSaveRequest, DBSaveResponse>

喏,就是这个家伙了。我们看看它的Run方法。

DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
if (string.IsNullOrEmpty(message.CollectionName))
{
    message.CollectionName = message.Disposer.GetType().Name;
}

if (message.NeedCache)
{
    dbCacheComponent.AddToCache(message.Disposer, message.CollectionName);
}
await dbCacheComponent.Add(message.Disposer, message.CollectionName);

正如我们最开是说的,请求在服务器被接受时,最后会在DBCacheComponent执行。

其他的事件都差不多其实。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值