feat: server 包新增 service 模式的加载函数 server.BindService

This commit is contained in:
kercylan98 2023-12-25 12:11:04 +08:00
parent 6bf9c5ef9a
commit bdf4a237df
3 changed files with 75 additions and 6 deletions

View File

@ -97,18 +97,19 @@ type Server struct {
cancel context.CancelFunc // 停止上下文
online *concurrent.BalanceMap[string, *Conn] // 在线连接
systemDispatcher *dispatcher // 系统消息分发器
network Network // 网络类型
addr string // 侦听地址
systemSignal chan os.Signal // 系统信号
closeChannel chan struct{} // 关闭信号
multipleRuntimeErrorChan chan error // 多服务器模式下的运行时错误
dispatcherLock sync.RWMutex // 消息分发器锁
isShutdown atomic.Bool // 是否已关闭
messageCounter atomic.Int64 // 消息计数器
isRunning bool // 是否正在运行
dispatchers map[string]*dispatcher // 消息分发器集合
dispatcherMember map[string]map[string]*Conn // 消息分发器包含的连接
currDispatcher map[string]*dispatcher // 当前连接所处消息分发器
dispatcherLock sync.RWMutex // 消息分发器锁
isShutdown atomic.Bool // 是否已关闭
messageCounter atomic.Int64 // 消息计数器
addr string // 侦听地址
network Network // 网络类型
isRunning bool // 是否正在运行
services []func() // 服务
}
// Run 使用特定地址运行服务器
@ -130,6 +131,7 @@ func (slf *Server) Run(addr string) error {
if slf.event == nil {
return ErrConstructed
}
onServicesInit(slf)
slf.event.check()
slf.addr = addr
slf.startMessageStatistics()

37
server/service.go Normal file
View File

@ -0,0 +1,37 @@
package server
import (
"github.com/kercylan98/minotaur/utils/log"
"reflect"
)
// Service 兼容传统 service 设计模式的接口
type Service interface {
// OnInit 初始化服务,该方法将会在 Server 初始化时执行
// - 通常来说,该阶段发生任何错误都应该 panic 以阻止 Server 启动
OnInit(srv *Server)
}
// BindService 绑定服务到特定 Server被绑定的服务将会在 Server 初始化时执行 Service.OnInit 方法
func BindService(srv *Server, services ...Service) {
for _, service := range services {
srv.services = append(srv.services, func() {
name := reflect.TypeOf(service).String()
defer func(name string) {
if err := recover(); err != nil {
log.Error("Server", log.String("service", name), log.String("status", "initialization"), log.Any("err", err))
panic(err)
}
}(name)
service.OnInit(srv)
log.Info("Server", log.String("service", name), log.String("status", "initialized"))
})
}
}
// onServicesInit 服务初始化
func onServicesInit(srv *Server) {
for _, service := range srv.services {
service()
}
}

30
server/service_test.go Normal file
View File

@ -0,0 +1,30 @@
package server_test
import (
"github.com/kercylan98/minotaur/server"
"testing"
"time"
)
type TestService struct {
}
func (ts *TestService) OnInit(srv *server.Server) {
srv.RegStartFinishEvent(func(srv *server.Server) {
println("Server started")
})
srv.RegStopEvent(func(srv *server.Server) {
println("Server stopped")
})
}
func TestBindService(t *testing.T) {
srv := server.New(server.NetworkNone, server.WithLimitLife(time.Second))
server.BindService(srv, new(TestService))
if err := srv.RunNone(); err != nil {
panic(err)
}
}