Skip to main content

JsonRPC

默认配置

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

基本使用

Service定义

service接口定义:

const (
APP_NAME = "HelloService"
)

type HelloService interface {
Hello(request *HelloRequest, response *HelloResponse) error
}

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

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

service 客户端

package service

import (
"fmt"

"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) Hello(in *HelloRequest, out *HelloResponse) error {
body := jsonrpc.NewRequest(fmt.Sprintf("%s.Hello", APP_NAME), in)
result := jsonrpc.NewResponse(body.Id, out)
_, err := c.client.R().SetDebug(true).SetBody(body).SetResult(result).Post("")
if err != nil {
return err
}

if result.Error != nil {
return exception.NewApiExceptionFromString(*result.Error)
}
return nil
}

Server实现

package main

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

var _ service.HelloService = (*HelloServiceServer)(nil)

// 实现业务功能
// req := &HelloRequest{}
// resp := &HelloResponse{}
// err := &HelloServiceServer{}.Hello(req, resp)
// net/rpc
// 1. 写好的对象, 注册给RPC Server
// 2. 再把RPC Server 启动起来
type HelloServiceServer struct {
}

// HTTP Handler
func (h *HelloServiceServer) Hello(request *service.HelloRequest, response *service.HelloResponse) error {
response.Message = "hello:" + request.MyName
return nil
}

func main() {
// 注册服务
err := jsonrpc.GetService().Registry(service.APP_NAME, &HelloServiceServer{})
if err != nil {
panic(err)
}

cmd.Start()
}

客户端使用

package main

import (
"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")
if err != nil {
panic(err)
}
// 方法调用
// serviceMethod string, args any, reply any
req := &service.HelloRequest{
MyName: "bob",
}
resp := &service.HelloResponse{}
if err := client.Hello(req, resp); err != nil {
panic(err)
}

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