JSON-RPC

前言

RPC(Remote Procedure Call),远程过程调用,是一个分布式系统间通信的必备技术,使用protobuf、thrift、hessian、xml、json等序列化方式序列化数据,使用tcp或http等传输协议传输数据。

简介

json-rpc是基于json的跨语言远程调用协议,使用json作为序列化方式。json-rpc比xml-rpc、webservice等基于文本的协议传输数据小;相对hessian、java-rpc等二进制协议便于调试、实现、扩展,是非常优秀的一种远程调用协议。目前主流语言都已有json-rpc的实现框架,java语言中较好的json-rpc实现框架有jsonrpc4j、jpoxy、json-rpc。三者之中jsonrpc4j既可独立使用,又可与spring无缝集合,比较适合于基于spring的项目开发。

请求数据格式

{ 
  "method": "sayHello", 
  "params": ["Hello JSON-RPC"], 
  "id": 1
}

参数说明:

method:调用的方法名
params:方法传入的参数,若无参数则传入 [] id:调用标识符,用于标示一次远程调用过程

返回数据格式

{   
  "result": "Hello JSON-RPC",         
  "error": null,       
  "id": 1
}

返回值说明:

result: 方法返回值,若无返回值,则返回null。若调用错误,返回null。
error: 调用时错误,无错误返回null。
id: 调用标识符,与调用方传入的标识符一致。

示例

下面的例子使用jsonrpc4j和springboot演示对两个数求和。

定义一个Request对象,用来接收参数。
public class CalcReq implements Serializable {

    private int a;

    private int b;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }
}
定义一个Service,用来实现两个数相加的逻辑
@Service
public class CalculateService {

    public int add(CalcReq req) {
        return req.getA() + req.getB();
    }

}
定义一个controller用来接收http请求
@Controller
public class CalculateController implements InitializingBean {

    @Autowired
    private CalculateService calculateService;

    private JsonRpcServer jsonRpcServer;

    @RequestMapping("/add")
    public void add(HttpServletRequest req, HttpServletResponse res) throws IOException {
        jsonRpcServer.handle(req, res);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        jsonRpcServer = new JsonRpcServer(calculateService);
    }
}
  • 创建一个JsonRpcServer对象,将service对象作为这个JsonRpcServer对象的handler。
  • 将请求转发给JsonRpcServer处理
启动项目,使用curl发送请求:
➜  ~ curl -i -H 'content-type: application/json' -X POST -d '{"jsonrpc": "2.0", "method": "sub", "params":[{"a": 1, "b": 2}], "id": 1}' 'http://127.0.0.1:8080/add'
得到响应:
HTTP/1.1 200
Content-Type: application/json-rpc
Content-Length: 36
Date: Sat, 25 Aug 2018 06:49:09 GMT

{"jsonrpc":"2.0","id":1,"result":3}

jsonrpc4j和springboot

在上面的例子中,JsonRpcServer是在controller中创建的。实际上jsonrpc4j提供了AutoJsonRpcServiceImplExporter可以简化代码的编写。

创建JsonRpcService
@JsonRpcService("/calc")
public interface ExampleServerApi {

    int multiplier(@JsonRpcParam(value = "a") int a, @JsonRpcParam(value = "b") int b);

}
创建实现类
@Service
@AutoJsonRpcServiceImpl
public class ExampleServerApiImpl implements ExampleServerApi {
    @Override
    public int multiplier(int a, int b) {
        return a * b;
    }
}
创建ServiceExporter
@Configuration
public class ApplicationConfig {

    @Bean
    public static AutoJsonRpcServiceImplExporter autoJsonRpcServiceImplExporter() {
        AutoJsonRpcServiceImplExporter exp = new AutoJsonRpcServiceImplExporter();
        //in here you can provide custom HTTP status code providers etc. eg:
        //exp.setHttpStatusCodeProvider();
        //exp.setErrorResolver();
        return exp;
    }

}

启动项目,发送请求:

➜  ~ curl -i -H 'content-type: application/json' -X POST -d '{"jsonrpc": "2.0", "method": "multiplier", "params":{"a": 3, "b": 2}, "id": 1}' 'http://127.0.0.1:8080/calc'

返回响应:

HTTP/1.1 200
Content-Type: application/json-rpc
Content-Length: 36
Date: Sat, 25 Aug 2018 07:28:25 GMT

{"jsonrpc":"2.0","id":1,"result":6}

参考链接

results matching ""

    No results matching ""