jsonrpc 是无状态、轻量级的远程过程调用协议,传递数据格式为 JSON。GO 官方提供 rpc 包和 jsonrpc 包,与 rpc 包不同的是,jsonrpc 可以实现跨平台通信。本文将介绍如何用 Go 快速搭建一个 jsonrpc Server,用 PHP 实现 jsonrpc client 进行验证,同时也记录下验证过程中出现的坑。
实现 jsonrpc_server
引入包
1import (
2 "net/rpc"
3 "net"
4 "log"
5 "net/rpc/jsonrpc"
6 "fmt"
7)
定义 server 端要伺服的 rpc method
1// rpc handler
2type Edwin int
3// 定义rpc method 第一个参数是请求对象,第二参数是返回对象,返回值是返回rpc 内部调用过程中出现的错误信息
4func (this *Edwin) Add(args map[string]float64,res *float64) error {
5 *res = args["num1"] + args["num2"]
6 return nil
7}
8func (this *Edwin) Multi(args map[string]interface{},res *float64) error {
9 *res = args["num1"].(float64) * args["num2"].(float64)
10 return nil
11}
注册 rpc handler,开启 server connection
1 rpc.Register(new(Edwin))
2
3 l,err := net.Listen("tcp",":11223")
4
5 if err!=nil{
6 log.Fatalln("listen error:",err)
7 }
8
9 for{
10 conn,err := l.Accept()
11
12 if err!= nil{
13 log.Fatalln("accept failed:",err)
14 }
15
16 fmt.Println("jsonrpc server start lisen on 11223...")
17
18
19 go func(conn net.Conn) {
20 fmt.Println("a new connection is coming...")
21 jsonrpc.ServeConn(conn)
22 }(conn)
23 }
php 实现 jsonrpc_client
1class JsonRpc {
2 private $conn;
3
4 function __construct($host, $port) {
5 $this->conn = fsockopen($host, $port, $errno, $errStr, 2);
6
7 }
8
9 public function call($method, $params) {
10
11 $err = fwrite($this->conn, json_encode([
12 'method' => $method,
13 'params' => array($params),
14 'id' => 1,
15 ]));
16
17 if (empty($err)) {
18 return false;
19 }
20
21 stream_set_timeout($this->conn, 0, 300);
22
23 $line = fgets($this->conn);
24 if ($line === false) {
25 return NULL;
26 }
27
28 fclose($this->conn);
29
30 return json_decode($line, true);
31 }
32}
33
34$client = new JsonRPC("127.0.0.1", 11223);
35$client2 = new JsonRPC("127.0.0.1", 11223);
36$ret = $client->Call("Edwin2.Multi", array("num1" => 14, "num2" => 20));
37$ret2 = $client2->Call("Edwin2.Add", array("num1" => 14, "num2" => 20));
38var_export($ret);
39var_export($ret2);
验证
1# 开启 jsonrpc server
2go run jsonrpc_server.go
3# 正常会输出监听信息
4> jsonrpc server start lisen on 11223...
5> a new connection is coming...
6# 执行 jsonrpc client
7php jsonrpc_clinent.php
8# 正常输出以下信息
9> array (
10 'id' => 1,
11 'result' => 280,
12 'error' => NULL,
13)array (
14 'id' => 1,
15 'result' => 34,
16 'error' => NULL,
17)
验证中的问题
问题代码:
1$err = fwrite($this->conn, json_encode([
2 'method' => $method,
3 'params' => array($params),
4 // 'params' => $params // 不能这么用
5 'id' => 1,
6 ]));
params 参数必须用 array 包含,如果直接传递过去,将报出以下错误信息:
1array (
2 'id' => 1,
3 'result' => NULL,
4 'error' => 'json: cannot unmarshal object into Go value of type [1]interface {}',
5)
根据 JSON-RPC 规范,参数 params 可以是 Json Array,也可以是 Json Object,可是为什么还报错呢?于是查看源码,发现:
1在 src/net/rpc/jsonrpc/server.go 第95行,go官方实现指定params必须是数组:
2 var params [1]interface{}
3 params[0] = x
4 return json.Unmarshal(*c.req.Params, ¶ms)
5 ...
通过这个坑发现,Go jsonrpc 并未严格按照 JSON-RPC 规范实现。
内部处理流程
作者介绍:
作者张大辉(企业代号名),目前负责贝壳找房 PHP、GO 方向研发工作。
本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。
原文链接:
https://mp.weixin.qq.com/s/k0cQ_kIs4FhfAz_ncctRBg
更多内容推荐
21|Web 开发(上):如何使用 Axum 框架进行 Web 后端开发?
如何使用Axum框架进行Web后端开发?
2023-12-11
鉴释加入龙蜥社区,助力开源生态建设
近日,鉴释科技(深圳)有限公司(以下简称:“鉴释”)签署了 CLA(Contribution License Agreement,贡献者许可协议),正式加入龙蜥社区(OpenAnolis)。
2022-01-26
34|WebSocket:如何在消息队列内核中支持 WebSocket?
WebSocket 是一种实时协议,它在单个 TCP 连接上提供持久的全双工通信。
2023-09-06
用会声会影制作手链的展示视频
用会声会影制作手链的展示视频
2021-10-27
晚安吻
在我的认知里,男的都是不善于情感表达的,或者压根就是感受力很钝的。而女性相对来讲更感性,更善于情感的表达。
2021-12-21
STM32+ESP8266+MQTT 协议连接 OneNet 物联网平台
通过OneNet物联网服务器实现设备数据远程上传、下发,实现数据交互。之前的OneNet服务器不支持标准MQTT协议登录的,现在官网更新之后支持标准的MQTT协议,本篇文章介绍使用STM32+ESP8266使用标准MQTT协议登录Onenet服务器,实现数据交互。
2022-07-22
康威定律如何解释微服务的合理性
微服务这个概念很早就提出了, 真正火起来是在2016年左右,而康威定律(Conway's Law)就是微服务理论基础。
2022-07-09
读《Software Systems Architecture》(22)—— The Operational Viewpoint
读《Software Systems Architecture》(22)—— The Operational Viewpoint
2022-06-15
将博客搬至 CSDN
将博客搬至CSDN将博客搬至CSDN将博客搬至CSDN将博客搬至CSDN将博客搬至CSDN将博客搬至CSDN将博客搬至CSDN将博客搬至CSDN
2022-04-24
读《Software Systems Architecture》(26)—— The Performance and Scalability Perspective
读《Software Systems Architecture》(26)—— The Performance and Scalability Perspective
2022-06-15
元宇宙大热,是风口还是虎口
说起当下科技界和投资界的热门词汇,元宇宙应当榜上有名。尽管元宇宙概念最早出现在1992年美国作家尼尔·斯蒂芬森的科幻小说《雪崩》中,但2021年元宇宙却突然火爆各界,因此,2021年也被称为“元宇宙元年”。2021年3月,元宇宙游戏公司Roblox以300亿美元市值
2022-04-10
Echo Server 实战
2022-09-08
Go 语言学习查缺补漏 ing Day6
本【Go语言查缺补漏ing】系列主要是帮助新手Gopher更好的了解Go语言的易错点、重难点。
2021-12-09
完善核心能力:Master 请求转发与 Worker 资源管理
这节课,让我们继续优化Master服务,实现Master请求转发和并发情况下的资源保护,同时实现Worker对分配资源的监听。
2023-01-31
记中山公园全马 -- 一场无准备的马
Pain is inevitable.Suffering is optional.
2022-01-16
34|服务注册与监听:Worker 节点与 etcd 交互
这节课,让我们将Worker节点变为一个支持GRPC与HTTP协议访问的服务,让它最终可以被Master服务和外部服务直接访问。
2022-12-27
读《A Philosophy of Software Design》——(8)
读《A Philosophy of Software Design》——(8)
2022-04-07
第二周作业
请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则?
2020-10-31
9.Nacos Server 处理注册流程
2023-09-29
推荐阅读
22|Web 开发(下):如何实现一个 Todo List 应用?
2023-12-13
浅谈 ChatGPT 掀起的一波浪潮 | 社区征文
2023-03-02
Go RWMutex:高并发读多写少场景下的性能优化利器
2023-04-25
LED 显示屏与 LCD 拼接屏的对比
2023-03-15
02|初出茅庐:构造一个极简的 HttpServer
2023-12-11
03|动态 Response:按照规范构造返回流
2023-12-13
第一财经《导师带回血三期必中》MBA 智库百科
2023-09-04
电子书
大厂实战PPT下载
换一换 孔罗星 | 字节跳动 Dev Infra-APM 服务端观测平台负责人
姬生利 | 腾讯安全 云鼎实验室数据安全总监
杞坚玮 | 小米 小爱高级算法工程师
评论 1 条评论