目录
Overview
easy的路由器(Route)是:Server服务,net/agent 链接,编码解码(json/protobuf/...),controller逻辑控制器等沟通的桥梁。
接收消息的流程,从端->net.Agent->调度Server提供的编码解码->Server提供的路由器->逻辑控制器;
路由器接口
package route
import (
"github.com/slclub/easy/route/element"
"github.com/slclub/easy/typehandle"
)
type Router interface {
element.Distributer
Register(ID element.MID, msg any, handle typehandle.HandleMessage)
Route(msg any, ag any) error
PathMap() *element.PathMap
}
路由器类
路由器类像是个脚手架,将各个组件组织到一起;
package route
import (
"github.com/slclub/easy/route/bind"
"github.com/slclub/easy/route/element"
"github.com/slclub/easy/route/encode"
"github.com/slclub/easy/typehandle"
)
/**
* r := NewRouter()
*
* r.Binding(bind.NewBindJson(r.PathMap()), encode.NewJson(r.PathMap()))
*/
type Route struct {
DistributeCollection
pathMap *element.PathMap
}
func NewRouter() Router {
r := &Route{
DistributeCollection: DistributeCollection{},
pathMap: element.NewPahtMap(),
}
binder := bind.NewBindProto(r.PathMap())
r.Binding(encode.NewProtobuf(r.PathMap()), binder)
return r
}
/** 注册路由
* The r is a Router
* r.Register(MSG_LOGIN_REQ, &JsonLoginReq{}, loginRequest) // with handle registory
* if it is no handle needed can replace with nil
* Just register messages and MessageID
* r.Binder().Register(MSG_LOGIN_REQ, &JsonLoginReq{}) //
* Just register pathMap with handler and message id.
* r.Binder().RegisterHandle(id element.MID, handle typehandle.HandleMessage)
*/
func (self *Route) Register(ID element.MID, msg any, handle typehandle.HandleMessage) {
self.Binder().Register(ID, msg)
self.Binder().RegisterHandle(ID, handle)
}
// Automatic excuted it in your Server
// The binder achieve the element.RouteExecuter
func (self *Route) Route(msg any, ag any) error {
return self.Binder().Route(msg, ag)
}
// 获取路由表
// 将消息ID 和消息结构体 定义在此表中
// 用 Binder.Register 等方法注册
func (self *Route) PathMap() *element.PathMap {
return self.pathMap
}
路由器element 元素
插件绑定
// 为route 绑定插件
type Distributer interface {
DistributePlug
// 绑定 解码器=typehandle.Encoder ; 绑定器 = element.Binder
// Binding(encoder typehandle.Encoder, binder Binder)
Binding(plugins ...any)
}
路由器分发接口
依据消息分发到对应的handle控制器
type RouteExecuter interface {
// 路由分发消息 给 对应的handle
Route(msg any, ag any) error
}
绑定注册器和执行器
type Binder interface {
// 绑定消息ID 和消息
Register(id MID, msg any)
// 绑定 handle 到 路由
RegisterHandle(id MID, handle typehandle.HandleMessage)
// 继承执行器
RouteExecuter
}
注册容器
package element
import (
"github.com/slclub/easy/typehandle"
"reflect"
)
type PathMap struct {
idTypes map[MID]*MessageRouterType
typeTypes map[reflect.Type]*MessageRouterType
}
// 消息类型,消息ID,消息处理器
type MessageRouterType struct {
MID MID
Type reflect.Type
Handle typehandle.HandleMessage
}
type MID int // message ID
// PathMap
func NewPahtMap() *PathMap {
return &PathMap{
idTypes: make(map[MID]*MessageRouterType),
typeTypes: make(map[reflect.Type]*MessageRouterType),
}
}
func (self *PathMap) Add(mt *MessageRouterType) {
self.idTypes[mt.MID] = mt
self.typeTypes[mt.Type] = mt
}
func (self *PathMap) GetByMID(mid MID) *MessageRouterType {
return self.idTypes[mid]
}
func (self *PathMap) GetNewByMID(mid MID) *MessageRouterType {
va := self.idTypes[mid]
if va != nil {
return va
}
return new(MessageRouterType)
}
func (self *PathMap) GetByType(t reflect.Type) *MessageRouterType {
return self.typeTypes[t]
}
绑定器实现
package route
import (
"github.com/slclub/easy/log"
"github.com/slclub/easy/route/element"
"github.com/slclub/easy/vendors/encode"
"github.com/slclub/go-tips"
)
// 路由器 组件 集合器
type DistributeCollection struct {
binder element.Binder
coder encode.Encoder
}
func (self *DistributeCollection) Binder() element.Binder {
return self.binder
}
func (self *DistributeCollection) Encoder() encode.Encoder {
return self.coder
}
// func (self *DistributeCollection) Binding(coder typehandle.Encoder, binder element.Binder) {
func (self *DistributeCollection) Binding(plugins ...any) {
if plugins == nil || len(plugins) == 0 {
return
}
for _, plug := range plugins {
if tips.IsNil(plug) {
log.Fatal("EASY.ROUTER.Binding empty plugin")
continue
}
switch val := plug.(type) {
case encode.Encoder:
self.coder = val
case element.Binder:
self.binder = val
}
}
}
绑定路由器到Server
默认绑定easy/route
func NewWSServer() *WSServer {
ser := Server{
router: route.NewRouter(),
hook: newHookAgent(),
}
return &WSServer{
Server: ser,
}
}
路由分发消息给handle控制器
net/agent/Agent 接收消息,调用处理此处理函数;
路由器(route)是由Server.Router()提供;
route.Encoder()解码链接接收的消息;
route.Route分发解析好的消息提供给逻辑handle控制器;
// function handle 路由分发
func dealHandle(serv *Server) agent.AgentHandle {
return func(data []byte, ag agent.Agent) {
msg, err := serv.Router().Encoder().Unmarshal(data)
if err != nil {
log.Debug("unmarshal message error: %v", err)
return
}
err = serv.Router().Route(msg, ag)
if err != nil {
log.Debug("route message error: %v", err)
return
}
}
}