JsonRPC

默认配置

toml
env
[jsonrpc]
  # 是否开启HTTP Server, 默认会根据是否有注册得有API对象来自动开启
  enable = true
  # HTTP服务Host
  host = "127.0.0.1"
  # HTTP服务端口
  port = 9090
  # API接口前缀
  path_prefix = "jsonrpc"

基本使用

Service定义

service 接口定义

package service

import "context"

const (
	APP_NAME = "HelloService"
)

type HelloService interface {
	RPCHello(context.Context, *HelloRequest) (*HelloResponse, error)
}

type HelloRequest struct {
	MyName string `json:"my_name"`
}

type HelloResponse struct {
	Message string `json:"message"`
}
return nil

service 客户端实现(安装JSON RPC协议调用服务UserService.RPCGetUser)

import (
	"context"

	"github.com/infraboard/mcube/v2/exception"
	"github.com/infraboard/mcube/v2/ioc/config/application"
	"github.com/infraboard/mcube/v2/ioc/config/jsonrpc"
	"resty.dev/v3"
)

func NewClient(address string) (HelloService, error) {
	// 建立TCP连接
	client := resty.New().
		SetDebug(application.Get().Debug).
		SetHeader("Content-Type", "application/json").
		SetHeader("Accept", "application/json").
		SetBaseURL(address).AddResponseMiddleware(func(c *resty.Client, r *resty.Response) error {
		if r.StatusCode()/100 != 2 {
			return exception.NewApiExceptionFromString(r.String())
		}
		return nil
	})
	return &HelloServiceClient{client: client}, nil
}

// 要封装原始的 不友好的rpc call
type HelloServiceClient struct {
	client *resty.Client
}

func (c *HelloServiceClient) RPCHello(ctx context.Context, in *HelloRequest) (*HelloResponse, error) {
	body := jsonrpc.NewRequest("UserService.RPCGetUser", in)
	result := jsonrpc.NewResponse[HelloResponse]()

	_, err := c.client.R().SetDebug(true).SetBody(body).SetResult(result).Post("")
	if err != nil {
		return nil, err
	}

	if result.Error != nil {
		return nil, result.Error
	}
	return result.Result, nil
}

Server实现

package main

import (
	"context"
	"fmt"

	"github.com/infraboard/mcube/v2/examples/jsonrpc/service"
	"github.com/infraboard/mcube/v2/ioc/config/jsonrpc"
	"github.com/infraboard/mcube/v2/ioc/server/cmd"
)

// 用户服务
type UserService struct{}

// RPC 方法:自动注册为 getUser
func (s *UserService) RPCGetUser(ctx context.Context, req *service.HelloRequest) (*service.HelloResponse, error) {
	// 直接使用解析好的请求对象
	return &service.HelloResponse{
		Message: fmt.Sprintf("Hello, %s", req.MyName),
	}, nil
}

func main() {
	jsonrpc.RegisterService(&UserService{})
	cmd.Start()
}

启动服务

1$ go run server/main.go start
22025/09/26 19:17:07 init app app[priority: 999] ok.
32025/09/26 19:17:07 init app trace[priority: 998] ok.
42025/09/26 19:17:07 init app log[priority: 997] ok.
52025/09/26 19:17:07 init app grpc[priority: -89] ok.
62025/09/26 19:17:07 init app http[priority: -99] ok.
72025-09-26T19:17:07+08:00 INFO   config/jsonrpc/service.go:156 > method: UserService.RPCGetUser --> UserService.RPCGetUser(*service.HelloRequest) app:mcube_app group:default hostname:oldfishmpb-9.local logger:jsonrpc
82025/09/26 19:17:07 init app jsonrpc[priority: -89] ok.
92025-09-26T19:17:07+08:00 INFO   ioc/server/server.go:79 > loaded configs: [app.v1 trace.v1 log.v1 grpc.v1 http.v1] app:mcube_app group:default hostname:oldfishmpb-9.local logger:server
102025-09-26T19:17:07+08:00 INFO   ioc/server/server.go:79 > loaded default: [] app:mcube_app group:default hostname:oldfishmpb-9.local logger:server
112025-09-26T19:17:07+08:00 INFO   ioc/server/server.go:79 > loaded controllers: [] app:mcube_app group:default hostname:oldfishmpb-9.local logger:server
122025-09-26T19:17:07+08:00 INFO   ioc/server/server.go:79 > loaded apis: [jsonrpc.v1] app:mcube_app group:default hostname:oldfishmpb-9.local logger:server
132025-09-26T19:17:07+08:00 INFO   config/jsonrpc/service.go:86 > JSON RPC服务启动成功, 监听地址: http://127.0.0.1:9090/jsonrpc/mcube_app/v1 app:mcube_app group:default hostname:oldfishmpb-9.local logger:jsonrpc

客户端使用

package main

import (
	"context"
	"fmt"

	"github.com/infraboard/mcube/v2/examples/jsonrpc/service"
)

func main() {
	// 1. 通过网络调用 服务端的函数(RPC)
	client, err := service.NewClient("http://127.0.0.1:9090/jsonrpc/mcube_app/v1")
	if err != nil {
		panic(err)
	}
	// 方法调用
	resp, err := client.RPCHello(context.Background(), &service.HelloRequest{
		MyName: "bob",
	})
	if err != nil {
		panic(err)
	}

	fmt.Println("message", resp.Message)
}