1 Star 1 Fork 0

Allen / go-scaffold

Create your Gitee Account
Explore and code with more than 5 million developers,Free private repositories !:)
Sign up
Clone or download
server.go 5.41 KB
Copy Edit Raw Blame History
Allen authored 2020-08-24 16:17 . update to h2c
package server
import (
"context"
"crypto/tls"
"fmt"
"gitee.com/zakums06/go-scaffold/grpc/plugin"
"net"
"net/http"
"google.golang.org/grpc/grpclog"
"github.com/gorilla/handlers"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
)
// BaseServer for gRPC
type BaseServer struct {
Name string
Host string
Port int
listenAddr string
SSLName string
SSLCrtFile string
SSLKeyFile string
// start http server
EnableHTTPServer bool
// gRPC and http service
Services []Register
// ignore log gRPC method
IgnoreZapLogMethod []string
// StreamServerInterceptor for gRPC
StreamServerInterceptors []grpc.StreamServerInterceptor
// UnaryServerInterceptors for gRPC
UnaryServerInterceptors []grpc.UnaryServerInterceptor
// disableAutoRecovery for gRPC StreamServerInterceptor and UnaryServerInterceptor
DisableAutoRecovery bool
DisableAutoZap bool
OnShutdown []func()
options Options
// credentials config
tlsConfig *tls.Config
}
func (s *BaseServer) newGRPCServer() *grpc.Server {
if !s.DisableAutoRecovery {
s.StreamServerInterceptors = append(s.StreamServerInterceptors, StreamServerInterceptor())
s.UnaryServerInterceptors = append(s.UnaryServerInterceptors, UnaryServerInterceptor())
}
if !s.DisableAutoZap {
gRPCIgnoreLogMethod := make(map[string]bool, 0)
for _, v := range s.IgnoreZapLogMethod {
gRPCIgnoreLogMethod[v] = true
}
// overwrite system field
grpc_zap.SystemField = zap.String("span.system", "grpc")
zapOpts := []grpc_zap.Option{
grpc_zap.WithDecider(func(fullMethodName string, err error) bool {
// will not log gRPC calls if it was a call to ignore method and no error was raised
if err == nil && gRPCIgnoreLogMethod[fullMethodName] {
return false
}
// by default everything will be logged
return true
}),
}
s.StreamServerInterceptors = append(s.StreamServerInterceptors, grpc_zap.StreamServerInterceptor(zap.L(), zapOpts...))
s.UnaryServerInterceptors = append(s.UnaryServerInterceptors, grpc_zap.UnaryServerInterceptor(zap.L(), zapOpts...))
}
// enable zap logger
streamServerInterceptors := []grpc.StreamServerInterceptor{
grpc_ctxtags.StreamServerInterceptor(),
}
unaryServerInterceptors := []grpc.UnaryServerInterceptor{
grpc_ctxtags.UnaryServerInterceptor(),
}
// combine interceptors
streamServerInterceptors = append(streamServerInterceptors, s.StreamServerInterceptors...)
unaryServerInterceptors = append(unaryServerInterceptors, s.UnaryServerInterceptors...)
var opts []grpc.ServerOption
opts = append(
opts,
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
streamServerInterceptors...,
)),
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
unaryServerInterceptors...,
)),
)
if s.SSLCrtFile != "" && s.SSLKeyFile != "" {
cred, err := credentials.NewServerTLSFromFile(s.SSLCrtFile, s.SSLKeyFile)
if err != nil {
panic(err)
}
opts = append(opts, grpc.Creds(cred))
}
return grpc.NewServer(opts...)
}
// buildServer for gRPC and HTTPS
func (s *BaseServer) buildServer(services []Register) *http.Server {
g := s.newGRPCServer()
// grpc connection option
var opts []grpc.DialOption
if s.SSLCrtFile != "" && s.SSLKeyFile != "" {
cred, err := credentials.NewClientTLSFromFile(s.SSLCrtFile, s.SSLName)
if err != nil {
panic(err)
}
zap.L().Info("WithTransportCredentials")
opts = append(opts, grpc.WithTransportCredentials(cred))
} else {
zap.L().Info("WithInsecure")
opts = append(opts, grpc.WithInsecure())
}
gwmux := runtime.NewServeMux()
// register service to gRPC and http
for _, service := range services {
service.RegisterGRPC(g)
// register grpc-gateway http
if err := service.RegisterHTTP(context.Background(), gwmux, s.listenAddr, opts); err != nil {
panic(err)
}
}
// http server
var h http.Handler
if s.EnableHTTPServer {
mux := http.NewServeMux()
mux.Handle("/", gwmux)
// add cors from gorilla handlers
h = handlers.CORS(
handlers.AllowedMethods(s.options.CORSAllowedMethods),
handlers.AllowedOrigins(s.options.CORSAllowedOrigins),
handlers.AllowedHeaders(s.options.CORSAllowedHeaders),
)(mux)
}
return &http.Server{
Addr: s.listenAddr,
Handler: GRPCHandlerFunc(g, h),
}
}
// Start gRPC server
func (s *BaseServer) Start(opts ...Option) {
// with options
options := defaultServerOptions
for _, fn := range opts {
fn(&options)
}
s.options = options
// set grpc log
grpclog.SetLoggerV2(plugin.NewZapLogger(zap.L()))
// init listen address
s.listenAddr = fmt.Sprintf("%s:%d", s.Host, s.Port)
conn, err := net.Listen("tcp", s.listenAddr)
if err != nil {
panic(err)
}
// build server with register services
h := s.buildServer(s.Services)
var listener net.Listener
// init tls config
if s.SSLCrtFile != "" && s.SSLKeyFile != "" {
s.tlsConfig = GetTLSConfig(s.SSLCrtFile, s.SSLKeyFile)
h.TLSConfig = s.tlsConfig
listener = tls.NewListener(conn, s.tlsConfig)
} else {
listener = conn
}
h.RegisterOnShutdown(func() {
for _, f := range s.OnShutdown {
go f()
}
})
zap.L().Info("grpc and https start", zap.String("addr", s.listenAddr), zap.String("name", s.Name))
if err = h.Serve(listener); err != nil {
panic(err)
}
}

Comment ( 0 )

Sign in for post a comment

Go
1
https://gitee.com/zakums06/go-scaffold.git
git@gitee.com:zakums06/go-scaffold.git
zakums06
go-scaffold
go-scaffold
v0.1.11

Search