| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 | 
							- package commander
 
- //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg commander -path App,Commander
 
- import (
 
- 	"context"
 
- 	"net"
 
- 	"sync"
 
- 	"google.golang.org/grpc"
 
- 	"v2ray.com/core"
 
- 	"v2ray.com/core/common"
 
- 	"v2ray.com/core/common/signal"
 
- )
 
- // Commander is a V2Ray feature that provides gRPC methods to external clients.
 
- type Commander struct {
 
- 	sync.Mutex
 
- 	server *grpc.Server
 
- 	config Config
 
- 	v      *core.Instance
 
- 	ohm    core.OutboundHandlerManager
 
- }
 
- // NewCommander creates a new Commander based on the given config.
 
- func NewCommander(ctx context.Context, config *Config) (*Commander, error) {
 
- 	v := core.MustFromContext(ctx)
 
- 	c := &Commander{
 
- 		config: *config,
 
- 		ohm:    v.OutboundHandlerManager(),
 
- 		v:      v,
 
- 	}
 
- 	if err := v.RegisterFeature((*Commander)(nil), c); err != nil {
 
- 		return nil, err
 
- 	}
 
- 	return c, nil
 
- }
 
- // Type implements common.HasType.
 
- func (c *Commander) Type() interface{} {
 
- 	return (*Commander)(nil)
 
- }
 
- // Start implements common.Runnable.
 
- func (c *Commander) Start() error {
 
- 	c.Lock()
 
- 	c.server = grpc.NewServer()
 
- 	for _, rawConfig := range c.config.Service {
 
- 		config, err := rawConfig.GetInstance()
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		rawService, err := c.v.CreateObject(config)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		service, ok := rawService.(Service)
 
- 		if !ok {
 
- 			return newError("not a Service.")
 
- 		}
 
- 		service.Register(c.server)
 
- 	}
 
- 	c.Unlock()
 
- 	listener := &OutboundListener{
 
- 		buffer: make(chan net.Conn, 4),
 
- 		done:   signal.NewDone(),
 
- 	}
 
- 	go func() {
 
- 		if err := c.server.Serve(listener); err != nil {
 
- 			newError("failed to start grpc server").Base(err).AtError().WriteToLog()
 
- 		}
 
- 	}()
 
- 	c.ohm.RemoveHandler(context.Background(), c.config.Tag)
 
- 	c.ohm.AddHandler(context.Background(), &Outbound{
 
- 		tag:      c.config.Tag,
 
- 		listener: listener,
 
- 	})
 
- 	return nil
 
- }
 
- // Close implements common.Closable.
 
- func (c *Commander) Close() error {
 
- 	c.Lock()
 
- 	defer c.Unlock()
 
- 	if c.server != nil {
 
- 		c.server.Stop()
 
- 		c.server = nil
 
- 	}
 
- 	return nil
 
- }
 
- func init() {
 
- 	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
 
- 		return NewCommander(ctx, cfg.(*Config))
 
- 	}))
 
- }
 
 
  |