You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nnet/core/server.go

192 lines
4.3 KiB
Go

package core
import (
"git.noahlan.cn/northlan/nnet/internal/env"
"git.noahlan.cn/northlan/nnet/internal/log"
"git.noahlan.cn/northlan/nnet/internal/packet"
"git.noahlan.cn/northlan/nnet/serialize"
"net/http"
"time"
)
type (
// RunOption defines the method to customize a Server.
RunOption func(*Server)
Server struct {
ngin *engine
router Router
}
)
// NewServer returns a server with given config of c and options defined in opts.
// Be aware that later RunOption might overwrite previous one that write the same option.
func NewServer(c EngineConf, opts ...RunOption) *Server {
s := &Server{
ngin: newEngine(c),
router: NewRouter(),
}
opts = append([]RunOption{WithNotFoundHandler(nil)}, opts...)
for _, opt := range opts {
opt(s)
}
return s
}
// AddRoutes add given routes into the Server.
func (s *Server) AddRoutes(rs []Route) {
s.ngin.addRoutes(rs...)
}
// AddRoute adds given route into the Server.
func (s *Server) AddRoute(r Route) {
s.AddRoutes([]Route{r})
}
// Start starts the Server.
// Graceful shutdown is enabled by default.
func (s *Server) Start() {
if err := s.ngin.serve(s.router); err != nil {
log.Error(err)
panic(err)
}
}
// Stop stops the Server.
func (s *Server) Stop() {
s.ngin.close()
}
// Use adds the given middleware in the Server.
func (s *Server) Use(middleware Middleware) {
s.ngin.use(middleware)
}
// ToMiddleware converts the given handler to a Middleware.
func ToMiddleware(handler func(next Handler) Handler) Middleware {
return func(next HandlerFunc) HandlerFunc {
return handler(next).Handle
}
}
// WithMiddlewares adds given middlewares to given routes.
func WithMiddlewares(ms []Middleware, rs ...Route) []Route {
for i := len(ms) - 1; i >= 0; i-- {
rs = WithMiddleware(ms[i], rs...)
}
return rs
}
// WithMiddleware adds given middleware to given route.
func WithMiddleware(middleware Middleware, rs ...Route) []Route {
routes := make([]Route, len(rs))
for i := range rs {
route := rs[i]
routes[i] = Route{
Matches: route.Matches,
Handler: middleware(route.Handler),
}
}
return routes
}
// WithNotFoundHandler returns a RunOption with not found handler set to given handler.
func WithNotFoundHandler(handler Handler) RunOption {
return func(server *Server) {
notFoundHandler := server.ngin.notFoundHandler(handler)
server.router.SetNotFoundHandler(notFoundHandler)
}
}
func WithRouter(router Router) RunOption {
return func(server *Server) {
server.router = router
}
}
func WithPacker(packer packet.Packer) RunOption {
return func(server *Server) {
server.ngin.packer = packer
}
}
func WithProcessor(p Processor) RunOption {
return func(server *Server) {
server.ngin.processor = p
}
}
func WithSerializer(s serialize.Serializer) RunOption {
return func(server *Server) {
server.ngin.serializer = s
}
}
func WithLogger(logger log.Logger) RunOption {
return func(_ *Server) {
log.SetLogger(logger)
}
}
// WithTimerPrecision 设置Timer精度
// 注精度需大于1ms, 并且不能在运行时更改
// 默认精度是 time.Second
func WithTimerPrecision(precision time.Duration) RunOption {
if precision < time.Millisecond {
panic("time precision can not less than a Millisecond")
}
return func(_ *Server) {
env.TimerPrecision = precision
}
}
func WithPipeline(pipeline Pipeline) RunOption {
return func(server *Server) {
server.ngin.pipeline = pipeline
}
}
func WithHeartbeatInterval(d time.Duration) RunOption {
return func(server *Server) {
server.ngin.heartbeatInterval = d
}
}
type WSOption func(opts *wsOptions)
// WithWebsocket 开启Websocket, 参数是websocket的相关参数 nnet.WSOption
func WithWebsocket(wsOpts ...WSOption) RunOption {
return func(server *Server) {
for _, opt := range wsOpts {
opt(&server.ngin.wsOpt)
}
server.ngin.wsOpt.IsWebsocket = true
}
}
// WithWSPath 设置websocket的path
func WithWSPath(path string) WSOption {
return func(opts *wsOptions) {
opts.WebsocketPath = path
}
}
// WithWSTLSConfig 设置websocket的证书和密钥
func WithWSTLSConfig(certificate, key string) WSOption {
return func(opts *wsOptions) {
opts.TLSCertificate = certificate
opts.TLSKey = key
}
}
func WithWSCheckOriginFunc(fn func(*http.Request) bool) WSOption {
return func(opts *wsOptions) {
if fn != nil {
opts.CheckOrigin = fn
}
}
}