印度包网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
6.8 KiB

1 year ago
package gate
import (
"fmt"
"reflect"
"time"
"github.com/liangdas/mqant/conf"
"github.com/liangdas/mqant/gate"
basegate "github.com/liangdas/mqant/gate/base"
"github.com/liangdas/mqant/log"
"github.com/liangdas/mqant/module"
basemodule "github.com/liangdas/mqant/module/base"
"github.com/liangdas/mqant/network"
)
var RPCParamSessionType = gate.RPCParamSessionType
var RPCParamProtocolMarshalType = gate.RPCParamProtocolMarshalType
type BaseGate struct {
//module.RPCSerialize
basemodule.BaseModule
opts gate.Options
judgeGuest func(session gate.Session) bool
createAgent func() gate.Agent
}
func (gt *BaseGate) SetJudgeGuest(judgeGuest func(session gate.Session) bool) error {
gt.judgeGuest = judgeGuest
return nil
}
/*
设置Session信息持久化接口
*/
func (gt *BaseGate) SetRouteHandler(router gate.RouteHandler) error {
gt.opts.RouteHandler = router
return nil
}
/*
设置Session信息持久化接口
*/
func (gt *BaseGate) SetStorageHandler(storage gate.StorageHandler) error {
gt.opts.StorageHandler = storage
return nil
}
/*
设置客户端连接和断开的监听器
*/
func (gt *BaseGate) SetSessionLearner(sessionLearner gate.SessionLearner) error {
gt.opts.SessionLearner = sessionLearner
return nil
}
/*
设置创建客户端Agent的函数
*/
func (gt *BaseGate) SetCreateAgent(cfunc func() gate.Agent) error {
gt.createAgent = cfunc
return nil
}
func (gt *BaseGate) Options() gate.Options {
return gt.opts
}
func (gt *BaseGate) GetStorageHandler() (storage gate.StorageHandler) {
return gt.opts.StorageHandler
}
func (gt *BaseGate) GetGateHandler() gate.GateHandler {
return gt.opts.GateHandler
}
func (gt *BaseGate) GetAgentLearner() gate.AgentLearner {
return gt.opts.AgentLearner
}
func (gt *BaseGate) GetSessionLearner() gate.SessionLearner {
return gt.opts.SessionLearner
}
func (gt *BaseGate) GetRouteHandler() gate.RouteHandler {
return gt.opts.RouteHandler
}
func (gt *BaseGate) GetJudgeGuest() func(session gate.Session) bool {
return gt.judgeGuest
}
func (gt *BaseGate) GetModule() module.RPCModule {
return gt.GetSubclass()
}
func (gt *BaseGate) NewSession(data []byte) (gate.Session, error) {
return basegate.NewSession(gt.App, data)
}
func (gt *BaseGate) NewSessionByMap(data map[string]interface{}) (gate.Session, error) {
return basegate.NewSessionByMap(gt.App, data)
}
func (gt *BaseGate) OnConfChanged(settings *conf.ModuleSettings) {
}
/*
自定义rpc参数序列化反序列化 Session
*/
func (gt *BaseGate) Serialize(param interface{}) (ptype string, p []byte, err error) {
rv := reflect.ValueOf(param)
if rv.Kind() != reflect.Ptr || rv.IsNil() {
//不是指针
return "", nil, fmt.Errorf("Serialize [%v ] or not pointer type", rv.Type())
}
switch v2 := param.(type) {
case gate.Session:
bytes, err := v2.Serializable()
if err != nil {
return RPCParamSessionType, nil, err
}
return RPCParamSessionType, bytes, nil
case module.ProtocolMarshal:
bytes := v2.GetData()
return RPCParamProtocolMarshalType, bytes, nil
default:
return "", nil, fmt.Errorf("args [%s] Types not allowed", reflect.TypeOf(param))
}
}
func (gt *BaseGate) Deserialize(ptype string, b []byte) (param interface{}, err error) {
switch ptype {
case RPCParamSessionType:
mps, errs := basegate.NewSession(gt.App, b)
if errs != nil {
return nil, errs
}
return mps.Clone(), nil
case RPCParamProtocolMarshalType:
return gt.App.NewProtocolMarshal(b), nil
default:
return nil, fmt.Errorf("args [%s] Types not allowed", ptype)
}
}
func (gt *BaseGate) GetTypes() []string {
return []string{RPCParamSessionType}
}
func (gt *BaseGate) OnAppConfigurationLoaded(app module.App) {
//添加Session结构体的序列化操作类
gt.BaseModule.OnAppConfigurationLoaded(app) //这是必须的
err := app.AddRPCSerialize("gate", gt)
if err != nil {
log.Warning("Adding session structures failed to serialize interfaces %s", err.Error())
}
}
func (gt *BaseGate) OnInit(subclass module.RPCModule, app module.App, settings *conf.ModuleSettings, opts ...gate.Option) {
gt.opts = gate.NewOptions(opts...)
gt.BaseModule.OnInit(subclass, app, settings, gt.opts.Opts...) //这是必须的
if gt.opts.WsAddr == "" {
if WSAddr, ok := settings.Settings["WSAddr"]; ok {
gt.opts.WsAddr = WSAddr.(string)
}
}
if gt.opts.TCPAddr == "" {
if TCPAddr, ok := settings.Settings["TCPAddr"]; ok {
gt.opts.TCPAddr = TCPAddr.(string)
}
}
if gt.opts.TLS == false {
if tls, ok := settings.Settings["TLS"]; ok {
gt.opts.TLS = tls.(bool)
} else {
gt.opts.TLS = false
}
}
if gt.opts.CertFile == "" {
if CertFile, ok := settings.Settings["CertFile"]; ok {
gt.opts.CertFile = CertFile.(string)
} else {
gt.opts.CertFile = ""
}
}
if gt.opts.KeyFile == "" {
if KeyFile, ok := settings.Settings["KeyFile"]; ok {
gt.opts.KeyFile = KeyFile.(string)
} else {
gt.opts.KeyFile = ""
}
}
handler := basegate.NewGateHandler(gt)
gt.opts.AgentLearner = handler
gt.opts.GateHandler = handler
gt.GetServer().RegisterGO("Update", gt.opts.GateHandler.Update)
gt.GetServer().RegisterGO("Bind", gt.opts.GateHandler.Bind)
gt.GetServer().RegisterGO("UnBind", gt.opts.GateHandler.UnBind)
gt.GetServer().RegisterGO("Push", gt.opts.GateHandler.Push)
gt.GetServer().RegisterGO("Set", gt.opts.GateHandler.Set)
gt.GetServer().RegisterGO("Remove", gt.opts.GateHandler.Remove)
gt.GetServer().Register("Send", gt.opts.GateHandler.Send)
gt.GetServer().RegisterGO("SendBatch", gt.opts.GateHandler.SendBatch)
gt.GetServer().RegisterGO("BroadCast", gt.opts.GateHandler.BroadCast)
gt.GetServer().RegisterGO("IsConnect", gt.opts.GateHandler.IsConnect)
gt.GetServer().RegisterGO("Close", gt.opts.GateHandler.Close)
}
func (gt *BaseGate) Run(closeSig chan bool) {
var wsServer *network.WSServer
if gt.opts.WsAddr != "" {
wsServer = new(network.WSServer)
wsServer.Addr = gt.opts.WsAddr
wsServer.HTTPTimeout = 30 * time.Second
wsServer.TLS = gt.opts.TLS
wsServer.CertFile = gt.opts.CertFile
wsServer.KeyFile = gt.opts.KeyFile
wsServer.NewAgent = func(conn *network.WSConn) network.Agent {
agent := gt.createAgent()
agent.OnInit(gt, conn)
return agent
}
}
var tcpServer *network.TCPServer
if gt.opts.TCPAddr != "" {
tcpServer = new(network.TCPServer)
tcpServer.Addr = gt.opts.TCPAddr
tcpServer.TLS = gt.opts.TLS
tcpServer.CertFile = gt.opts.CertFile
tcpServer.KeyFile = gt.opts.KeyFile
tcpServer.NewAgent = func(conn *network.TCPConn) network.Agent {
agent := gt.createAgent()
agent.OnInit(gt, conn)
return agent
}
}
if wsServer != nil {
wsServer.Start()
}
if tcpServer != nil {
tcpServer.Start()
}
<-closeSig
if gt.opts.GateHandler != nil {
gt.opts.GateHandler.OnDestroy()
}
if wsServer != nil {
wsServer.Close()
}
if tcpServer != nil {
tcpServer.Close()
}
}
func (gt *BaseGate) OnDestroy() {
gt.BaseModule.OnDestroy() //这是必须的
}