server.go 1.6 KB

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