feat: add JSON-RPC control adapter

This commit is contained in:
2026-09-06 10:22:40 +00:00
parent 8df56263fb
commit 8155e5f81f
4 changed files with 379 additions and 1 deletions
+29 -1
View File
@@ -80,6 +80,19 @@ func run(configPath string) error {
}
grpcServer := grpc.NewServer(grpc.MaxRecvMsgSize(int(configured.Protocol.MaxControlRequestBytes)), grpc.MaxSendMsgSize(int(configured.Protocol.MaxControlRequestBytes)))
rvboxv1.RegisterControlServer(grpcServer, controlService)
var rpcListener net.Listener
var rpcServer *http.Server
if configured.JSONRPC.Enabled {
rpcListener, err = net.Listen("tcp", configured.JSONRPC.Listen)
if err != nil {
return fmt.Errorf("listen for JSON-RPC: %w", err)
}
defer rpcListener.Close()
if configured.JSONRPC.NonLoopbackBind {
log.Printf("rvbox-server: WARNING JSON-RPC is unauthenticated and bound to non-loopback address %s", configured.JSONRPC.Listen)
}
rpcServer = &http.Server{Handler: control.NewJSONRPCHandler(controlService, int64(configured.Protocol.MaxJSONRPCBodyBytes)), ReadHeaderTimeout: configured.Flow.WriteDeadline}
}
agent := &session.AgentServer{
Store: persistence, Registry: registry, Path: configured.Server.AgentPath,
Limits: agentproto.Limits{
@@ -93,9 +106,12 @@ func run(configPath string) error {
HeartbeatIdle: configured.Protocol.HeartbeatIdle, LivenessTimeout: configured.Protocol.LivenessTimeout,
}
httpServer := &http.Server{Handler: agent, ReadHeaderTimeout: configured.Flow.WriteDeadline}
serveError := make(chan error, 2)
serveError := make(chan error, 3)
go func() { serveError <- httpServer.Serve(listener) }()
go func() { serveError <- grpcServer.Serve(controlListener) }()
if rpcServer != nil {
go func() { serveError <- rpcServer.Serve(rpcListener) }()
}
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt, syscall.SIGTERM)
@@ -103,15 +119,27 @@ func run(configPath string) error {
select {
case err := <-serveError:
if errors.Is(err, http.ErrServerClosed) {
if rpcServer != nil {
_ = rpcServer.Close()
}
grpcServer.Stop()
return nil
}
_ = httpServer.Close()
if rpcServer != nil {
_ = rpcServer.Close()
}
grpcServer.Stop()
return err
case <-signals:
shutdownContext, cancel := context.WithTimeout(context.Background(), configured.Server.ShutdownGrace)
defer cancel()
httpErr := httpServer.Shutdown(shutdownContext)
if rpcServer != nil {
if err := rpcServer.Shutdown(shutdownContext); httpErr == nil {
httpErr = err
}
}
grpcDone := make(chan struct{})
go func() { grpcServer.GracefulStop(); close(grpcDone) }()
select {