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

186 lines
4.2 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package core
import (
"git.noahlan.cn/noahlan/nnet/internal/env"
"git.noahlan.cn/noahlan/nnet/packet"
"git.noahlan.cn/noahlan/nnet/serialize"
"git.noahlan.cn/noahlan/ntools-go/core/nlog"
"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 {
nlog.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(fn packet.NewPackerFunc) RunOption {
return func(server *Server) {
server.ngin.packerFn = fn
}
}
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
}
}
// 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
}
}
}