github.com/sagernet/sing-box@v1.9.0-rc.20/experimental/v2rayapi/server.go (about)

     1  package v2rayapi
     2  
     3  import (
     4  	"errors"
     5  	"net"
     6  	"net/http"
     7  
     8  	"github.com/sagernet/sing-box/adapter"
     9  	"github.com/sagernet/sing-box/experimental"
    10  	"github.com/sagernet/sing-box/log"
    11  	"github.com/sagernet/sing-box/option"
    12  	"github.com/sagernet/sing/common"
    13  
    14  	"google.golang.org/grpc"
    15  	"google.golang.org/grpc/credentials/insecure"
    16  )
    17  
    18  func init() {
    19  	experimental.RegisterV2RayServerConstructor(NewServer)
    20  }
    21  
    22  var _ adapter.V2RayServer = (*Server)(nil)
    23  
    24  type Server struct {
    25  	logger       log.Logger
    26  	listen       string
    27  	tcpListener  net.Listener
    28  	grpcServer   *grpc.Server
    29  	statsService *StatsService
    30  }
    31  
    32  func NewServer(logger log.Logger, options option.V2RayAPIOptions) (adapter.V2RayServer, error) {
    33  	grpcServer := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
    34  	statsService := NewStatsService(common.PtrValueOrDefault(options.Stats))
    35  	if statsService != nil {
    36  		RegisterStatsServiceServer(grpcServer, statsService)
    37  	}
    38  	server := &Server{
    39  		logger:       logger,
    40  		listen:       options.Listen,
    41  		grpcServer:   grpcServer,
    42  		statsService: statsService,
    43  	}
    44  	return server, nil
    45  }
    46  
    47  func (s *Server) Start() error {
    48  	listener, err := net.Listen("tcp", s.listen)
    49  	if err != nil {
    50  		return err
    51  	}
    52  	s.logger.Info("grpc server started at ", listener.Addr())
    53  	s.tcpListener = listener
    54  	go func() {
    55  		err = s.grpcServer.Serve(listener)
    56  		if err != nil && !errors.Is(err, http.ErrServerClosed) {
    57  			s.logger.Error(err)
    58  		}
    59  	}()
    60  	return nil
    61  }
    62  
    63  func (s *Server) Close() error {
    64  	if s.grpcServer != nil {
    65  		s.grpcServer.Stop()
    66  	}
    67  	return common.Close(
    68  		common.PtrOrNil(s.grpcServer),
    69  		s.tcpListener,
    70  	)
    71  }
    72  
    73  func (s *Server) StatsService() adapter.V2RayStatsService {
    74  	return s.statsService
    75  }