164 lines
3.5 KiB
Go
164 lines
3.5 KiB
Go
package v2
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
pb "github.com/hiddify/libcore/hiddifyrpc"
|
|
"github.com/sagernet/sing-box/experimental/libbox"
|
|
"github.com/sagernet/sing/common/observable"
|
|
)
|
|
|
|
var systemInfoObserver = observable.Observer[pb.SystemInfo]{}
|
|
var outboundsInfoObserver = observable.Observer[pb.OutboundGroupList]{}
|
|
var mainOutboundsInfoObserver = observable.Observer[pb.OutboundGroupList]{}
|
|
|
|
var (
|
|
statusClient *libbox.CommandClient
|
|
groupClient *libbox.CommandClient
|
|
groupInfoOnlyClient *libbox.CommandClient
|
|
)
|
|
|
|
func (s *server) GetSystemInfo(stream pb.Hiddify_GetSystemInfoServer) error {
|
|
if statusClient == nil {
|
|
statusClient = libbox.NewCommandClient(
|
|
&CommandClientHandler{},
|
|
&libbox.CommandClientOptions{
|
|
Command: libbox.CommandStatus,
|
|
StatusInterval: 1000000000, //1000ms debounce
|
|
},
|
|
)
|
|
|
|
defer func() {
|
|
statusClient.Disconnect()
|
|
statusClient = nil
|
|
}()
|
|
statusClient.Connect()
|
|
}
|
|
|
|
sub, _, _ := systemInfoObserver.Subscribe()
|
|
stopch := make(chan int)
|
|
go func() {
|
|
stream.Recv()
|
|
close(stopch)
|
|
}()
|
|
for {
|
|
select {
|
|
case <-stream.Context().Done():
|
|
break
|
|
case <-stopch:
|
|
break
|
|
case info := <-sub:
|
|
stream.Send(&info)
|
|
case <-time.After(1000 * time.Millisecond):
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *server) OutboundsInfo(stream pb.Hiddify_OutboundsInfoServer) error {
|
|
if groupClient == nil {
|
|
groupClient = libbox.NewCommandClient(
|
|
&CommandClientHandler{},
|
|
&libbox.CommandClientOptions{
|
|
Command: libbox.CommandGroup,
|
|
StatusInterval: 500000000, //500ms debounce
|
|
},
|
|
)
|
|
|
|
defer func() {
|
|
groupClient.Disconnect()
|
|
groupClient = nil
|
|
}()
|
|
groupClient.Connect()
|
|
}
|
|
|
|
sub, _, _ := outboundsInfoObserver.Subscribe()
|
|
stopch := make(chan int)
|
|
go func() {
|
|
stream.Recv()
|
|
close(stopch)
|
|
}()
|
|
for {
|
|
select {
|
|
case <-stream.Context().Done():
|
|
break
|
|
case <-stopch:
|
|
break
|
|
case info := <-sub:
|
|
stream.Send(&info)
|
|
case <-time.After(500 * time.Millisecond):
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *server) MainOutboundsInfo(stream pb.Hiddify_MainOutboundsInfoServer) error {
|
|
if groupInfoOnlyClient == nil {
|
|
groupInfoOnlyClient = libbox.NewCommandClient(
|
|
&CommandClientHandler{},
|
|
&libbox.CommandClientOptions{
|
|
Command: libbox.CommandGroupInfoOnly,
|
|
StatusInterval: 500000000, //500ms debounce
|
|
},
|
|
)
|
|
|
|
defer func() {
|
|
groupInfoOnlyClient.Disconnect()
|
|
groupInfoOnlyClient = nil
|
|
}()
|
|
groupInfoOnlyClient.Connect()
|
|
}
|
|
|
|
sub, _, _ := mainOutboundsInfoObserver.Subscribe()
|
|
stopch := make(chan int)
|
|
go func() {
|
|
stream.Recv()
|
|
close(stopch)
|
|
}()
|
|
for {
|
|
select {
|
|
case <-stream.Context().Done():
|
|
break
|
|
case <-stopch:
|
|
break
|
|
case info := <-sub:
|
|
stream.Send(&info)
|
|
case <-time.After(500 * time.Millisecond):
|
|
}
|
|
}
|
|
}
|
|
|
|
// Implement the SelectOutbound method
|
|
func (s *server) SelectOutbound(ctx context.Context, in *pb.SelectOutboundRequest) (*pb.Response, error) {
|
|
err := libbox.NewStandaloneCommandClient().SelectOutbound(in.GroupTag, in.OutboundTag)
|
|
|
|
if err != nil {
|
|
return &pb.Response{
|
|
ResponseCode: pb.ResponseCode_FAILED,
|
|
Message: err.Error(),
|
|
}, err
|
|
}
|
|
|
|
return &pb.Response{
|
|
ResponseCode: pb.ResponseCode_OK,
|
|
Message: "",
|
|
}, nil
|
|
}
|
|
|
|
// Implement the UrlTest method
|
|
func (s *server) UrlTest(ctx context.Context, in *pb.UrlTestRequest) (*pb.Response, error) {
|
|
err := libbox.NewStandaloneCommandClient().URLTest(in.GroupTag)
|
|
|
|
if err != nil {
|
|
return &pb.Response{
|
|
ResponseCode: pb.ResponseCode_FAILED,
|
|
Message: err.Error(),
|
|
}, err
|
|
}
|
|
|
|
return &pb.Response{
|
|
ResponseCode: pb.ResponseCode_OK,
|
|
Message: "",
|
|
}, nil
|
|
|
|
}
|