104 lines
1.6 KiB
Go
104 lines
1.6 KiB
Go
package rpcsup
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
"net/rpc"
|
|
"net/rpc/jsonrpc"
|
|
"strings"
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
type RpcServicer interface {
|
|
Name() string
|
|
}
|
|
|
|
type RpcService struct {
|
|
rpc *rpc.Server
|
|
listen net.Listener
|
|
handler func(net.Conn)
|
|
}
|
|
|
|
type RpcConfig struct {
|
|
Typec string
|
|
Network string
|
|
Address string
|
|
}
|
|
|
|
func NewRpcService(conf *RpcConfig) (res *RpcService, err error) {
|
|
res = new(RpcService)
|
|
|
|
res.rpc = rpc.NewServer()
|
|
res.listen, err = net.Listen(conf.Network, conf.Address)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if strings.Contains(conf.Typec, "json") {
|
|
res.handler = func(c net.Conn) {
|
|
res.rpc.ServeCodec(jsonrpc.NewServerCodec(c))
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
if strings.Contains(conf.Typec, "grpc") {
|
|
return nil, errors.New("currently not supported")
|
|
}
|
|
|
|
res.handler = func(c net.Conn) {
|
|
res.rpc.ServeConn(c)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (r *RpcService) Register(service ...interface{}) error {
|
|
for _, ser := range service {
|
|
if nser, ok := ser.(RpcServicer); ok {
|
|
if err := r.rpc.RegisterName(nser.Name(), nser); err != nil {
|
|
return err
|
|
}
|
|
continue
|
|
}
|
|
|
|
if err := r.rpc.Register(ser); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *RpcService) Run(ctx context.Context) error {
|
|
wg, ctxx := errgroup.WithContext(ctx)
|
|
|
|
wg.Go(func() error {
|
|
for {
|
|
accept, err := r.listen.Accept()
|
|
if err != nil {
|
|
if errors.Is(err, net.ErrClosed) {
|
|
return err
|
|
}
|
|
continue
|
|
}
|
|
|
|
go r.handler(accept)
|
|
}
|
|
})
|
|
|
|
wg.Go(func() error {
|
|
<-ctxx.Done()
|
|
r.listen.Close()
|
|
return ctxx.Err()
|
|
})
|
|
|
|
if err := wg.Wait(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|