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 } } }