概述
- Golang 提供
net/rpc/jsonrpc
库来实现rpc方法 - 采用 json 方式进行数据编解码,支持跨语言调用
这里实现跨语言示例
1 )go 服务端
go
package main
import (
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
// 定义服务接口
type Arith int
// 定义接口方法,参数和返回值都应该是指针类型
func (t *Arith) Multiply(args *Args, reply *int) error {
*reply = args.A * args.B
log.Print("参数", args)
return nil
}
// Args 是传递给服务的参数结构
type Args struct {
A, B int
}
func main() {
arith := new(Arith)
rpc.Register(arith)
l, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("listen error:", err)
}
defer l.Close()
for {
conn, err := l.Accept()
if err != nil {
log.Print("accept error:", err)
continue
}
// 使用 jsonrpc 包处理连接
go func() {
jsonrpc.ServeConn(conn)
conn.Close()
}()
}
}
2 )nodejs 客户端1
js
const net = require('net');
const readline = require('readline');
// 创建一个 TCP 客户端
const client = new net.Socket();
// 连接到服务器
client.connect(1234, 'localhost', () => {
console.log('Connected to server!');
// 发送请求到服务器
const request = JSON.stringify({
jsonrpc: "2.0",
method: "Arith.Multiply",
params: [{ A: 7, B: 8 }],
id: 1
});
client.write(request + '\n');
});
// 处理从服务器返回的数据
const rl = readline.createInterface({
input: client,
output: process.stdout,
terminal: false
});
rl.on('line', (line) => {
const response = JSON.parse(line);
console.log('Server response:', response.result);
client.end();
});
client.on('error', (err) => {
console.error('Socket error:', err);
});
client.on('close', () => {
console.log('Connection closed');
});
3 )nodejs 客户端2
js
const jayson = require('jayson');
const client = jayson.client.tcp({
port: 1234,
host: 'localhost'
});
// 定义要调用的方法以及参数
const request = {
jsonrpc: "2.0",
method: "Arith.Multiply",
params: [{ A: 7, B: 8 }],
id: 1
};
// 发送请求并处理响应
client.request(request, function(err, response) {
if (err) {
console.error('请求出错:', err);
return;
}
console.log('服务器响应:', response.result); // 输出乘法的结果
});
4 )go 客户端3
js
package main
import (
"fmt"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
type Args struct {
A int `json:"A"`
B int `json:"B"`
}
func main() {
// 1. 用 net.Dial和rpc微服务端建立连接
conn, err1 := net.Dial("tcp", "127.0.0.1:1234")
if err1 != nil {
fmt.Println(err1)
}
// 2. 当客户端退出的时候关闭连接
defer conn.Close()
// 3、建立基于json编解码的rpc服务
client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
// 4. 调用远程函数
var reply int
err2 := client.Call("Arith.Multiply", Args{A: 7, B: 8}, &reply)
if err2 != nil {
fmt.Println(err2)
}
// 5. 获取微服务返回的数据
fmt.Println(reply)
}
总结
- 这里演示了,基于go语言为服务端,nodejs 和 golang 为客户端的3种示范
- 注意,上面 nodejs版本中的 params 的格式与 golang 中的区别
- 标准库的RPC默认采用Go语言特有的gob编码,没法实现跨语言调用
- golang官方还提供了 net/rpc/jsonrpc 库实现RPC方法
- JSON RPC采用JSON进行数据编解码,因而支持跨语言调用
- 但目前的jsonrpc库是基于tcp协议实现的,暂时不支持使用http进行数据传输
- 另外,Mac环境,在没有服务端服务时,可用 nc 工具调试客户端
- $
nc -l 127.0.0.1 1234
- $
- linux下需要安装, $
yum install -y nc
- nc是netcat的简写,是一个功能强大的网络工具,有着网络界的瑞士军刀美誉
- nc命令的主要作用如下:
- 实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口
- 端口的扫描,nc可以作为client发起TCP或UDP连接
- 机器之间传输文件
- 机器之间网络测速