package service import ( "fmt" "git.hlsq.asia/mmorpg/service-common/discover" "git.hlsq.asia/mmorpg/service-common/log" "git.hlsq.asia/mmorpg/service-common/utils" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "google.golang.org/grpc" "google.golang.org/grpc/keepalive" "net" "sync" "time" ) type IService interface { Init(addr string, port int32) Close() } type Base struct { Target string ServiceName string SID string Serve *grpc.Server EtcdTTL int64 OnCustomGrpcServerOption func() []grpc.ServerOption OnInit func(serve *grpc.Server) OnClose func() wg *sync.WaitGroup } func (s *Base) Init(addr string, port int32) { s.wg = &sync.WaitGroup{} s.wg.Add(1) s.SID = utils.SnowflakeInstance().Generate().String() go func() { defer s.wg.Done() defer s.OnClose() defer discover.UnRegisterGrpcServer(s.SID) // 监听端口 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { log.Errorf("%v ListenPort err: %v", s.Target, err) return } options := []grpc.ServerOption{ grpc.ChainUnaryInterceptor( s.RecoveryInterceptor, s.LoggingInterceptor, ), grpc.StatsHandler(otelgrpc.NewServerHandler()), grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ MinTime: 20 * time.Second, PermitWithoutStream: true, }), } options = append(options, s.OnCustomGrpcServerOption()...) s.Serve = grpc.NewServer(options...) s.OnInit(s.Serve) // 服务注册 if err = discover.RegisterGrpcServer(s.Target, s.SID, fmt.Sprintf("%v:%d", addr, port), s.EtcdTTL); err != nil { log.Errorf("%v RegisterGrpcServer err: %v", s.Target, err) return } if err = s.Serve.Serve(lis); err != nil { log.Errorf("%v Serve err: %v", s.Target, err) return } log.Infof("%v server stop.", s.Target) }() } func (s *Base) Close() { if s.Serve != nil { s.Serve.Stop() s.wg.Wait() } }