feat: add cmux
This commit is contained in:
59
templates/project/providers/cmux/config.go.tpl
Normal file
59
templates/project/providers/cmux/config.go.tpl
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package cmux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"qq/providers/grpc"
|
||||||
|
"qq/providers/http"
|
||||||
|
|
||||||
|
"git.ipao.vip/rogeecn/atom/container"
|
||||||
|
"git.ipao.vip/rogeecn/atom/utils/opt"
|
||||||
|
"github.com/soheilhy/cmux"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
const DefaultPrefix = "Cmux"
|
||||||
|
|
||||||
|
func DefaultProvider() container.ProviderContainer {
|
||||||
|
return container.ProviderContainer{
|
||||||
|
Provider: Provide,
|
||||||
|
Options: []opt.Option{
|
||||||
|
opt.Prefix(DefaultPrefix),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Host *string
|
||||||
|
Port uint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Config) Address() string {
|
||||||
|
if h.Host == nil {
|
||||||
|
return fmt.Sprintf(":%d", h.Port)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%d", *h.Host, h.Port)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CMux struct {
|
||||||
|
Http http.Service
|
||||||
|
Grpc *grpc.Grpc
|
||||||
|
Mux cmux.CMux
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CMux) Serve() error {
|
||||||
|
grpcL := c.Mux.Match(cmux.HTTP2HeaderField("content-type", "application/grpc"))
|
||||||
|
// httpL := c.Mux.Match(cmux.HTTP1Fast())
|
||||||
|
httpL := c.Mux.Match(cmux.Any())
|
||||||
|
|
||||||
|
var eg errgroup.Group
|
||||||
|
eg.Go(func() error {
|
||||||
|
return c.Grpc.ServeWithListener(grpcL)
|
||||||
|
})
|
||||||
|
|
||||||
|
eg.Go(func() error {
|
||||||
|
return c.Http.Listener(httpL)
|
||||||
|
})
|
||||||
|
|
||||||
|
return c.Mux.Serve()
|
||||||
|
}
|
||||||
32
templates/project/providers/cmux/provider.go.tpl
Normal file
32
templates/project/providers/cmux/provider.go.tpl
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package cmux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"qq/providers/grpc"
|
||||||
|
"qq/providers/http"
|
||||||
|
|
||||||
|
"git.ipao.vip/rogeecn/atom/container"
|
||||||
|
"git.ipao.vip/rogeecn/atom/utils/opt"
|
||||||
|
"github.com/soheilhy/cmux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Provide(opts ...opt.Option) error {
|
||||||
|
o := opt.New(opts...)
|
||||||
|
var config Config
|
||||||
|
if err := o.UnmarshalConfig(&config); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return container.Container.Provide(func(http http.Service, grpc *grpc.Grpc) (*CMux, error) {
|
||||||
|
l, err := net.Listen("tcp", config.Address())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CMux{
|
||||||
|
Http: http,
|
||||||
|
Grpc: grpc,
|
||||||
|
Mux: cmux.New(l),
|
||||||
|
}, nil
|
||||||
|
}, o.DiOptions()...)
|
||||||
|
}
|
||||||
@@ -46,3 +46,7 @@ func (g *Grpc) Serve() error {
|
|||||||
|
|
||||||
return g.Server.Serve(l)
|
return g.Server.Serve(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Grpc) ServeWithListener(ln net.Listener) error {
|
||||||
|
return g.Server.Serve(ln)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package http
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ type Service struct {
|
|||||||
Engine *fiber.App
|
Engine *fiber.App
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) Serve() error {
|
func (svc *Service) listenerConfig() fiber.ListenConfig {
|
||||||
listenConfig := fiber.ListenConfig{
|
listenConfig := fiber.ListenConfig{
|
||||||
EnablePrintRoutes: true,
|
EnablePrintRoutes: true,
|
||||||
OnShutdownSuccess: func() {
|
OnShutdownSuccess: func() {
|
||||||
@@ -44,7 +45,7 @@ func (svc *Service) Serve() error {
|
|||||||
|
|
||||||
if svc.conf.Tls != nil {
|
if svc.conf.Tls != nil {
|
||||||
if svc.conf.Tls.Cert == "" || svc.conf.Tls.Key == "" {
|
if svc.conf.Tls.Cert == "" || svc.conf.Tls.Key == "" {
|
||||||
return errors.New("tls cert or key is empty")
|
panic(errors.New("tls cert and key must be set"))
|
||||||
}
|
}
|
||||||
listenConfig.CertFile = svc.conf.Tls.Cert
|
listenConfig.CertFile = svc.conf.Tls.Cert
|
||||||
listenConfig.CertKeyFile = svc.conf.Tls.Key
|
listenConfig.CertKeyFile = svc.conf.Tls.Key
|
||||||
@@ -52,8 +53,15 @@ func (svc *Service) Serve() error {
|
|||||||
container.AddCloseAble(func() {
|
container.AddCloseAble(func() {
|
||||||
svc.Engine.Shutdown()
|
svc.Engine.Shutdown()
|
||||||
})
|
})
|
||||||
|
return listenConfig
|
||||||
|
}
|
||||||
|
|
||||||
return svc.Engine.Listen(svc.conf.Address(), listenConfig)
|
func (svc *Service) Listener(ln net.Listener) error {
|
||||||
|
return svc.Engine.Listener(ln, svc.listenerConfig())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *Service) Serve() error {
|
||||||
|
return svc.Engine.Listen(svc.conf.Address(), svc.listenerConfig())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Provide(opts ...opt.Option) error {
|
func Provide(opts ...opt.Option) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user