Go/Python RPC使用

Remote Procedure Call

简单RPC调用

server实现

// 注册接口

type HelloService struct{}

func (s *HelloService) HelloFunc(request string, reply *string) error {
	// 返回值是通过修改Reply的值
	*reply = "Hello, " + request
	return nil
}

func main() {
	// 实例化一个Server对象
	listener, _ := net.Listen("tcp", ":9091")

	// 注册处理逻辑
	_ = rpc.RegisterName("HelloService", &HelloService{})

	// 启动服务 处理请求
	conn, _ := listener.Accept()
	rpc.ServeConn(conn)
}

client实现

func main() {
	// 建立连接
	client, _ := rpc.Dial("tcp", "localhost:9091")

	var reply string
	_ = client.Call("HelloService.HelloFunc", "David", &reply)
	fmt.Println(reply)
}

采用JSON序列化

Go语言RPC序列化协议为Gob,将Gob替换为常见序列化协议JSON,使得能够跨语言调用

修改Server:

func main() {
	// 实例化一个Server对象
	listener, err := net.Listen("tcp", ":9091")
	if err != nil {
		panic(err)
	}

	// 注册处理逻辑
	err = rpc.RegisterName("HelloService", &HelloService{})
	if err != nil {
		panic(err)
	}
	// 启动服务 处理请求
	for {
		conn, _ := listener.Accept()
		go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))
	}
}

修改Client:

func main() {
	// 建立连接
	conn, err := net.Dial("tcp", "localhost:9091")
	if err != nil {
		panic("connect failed")
	}

	var reply string
	client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
	err = client.Call("HelloService.HelloFunc", "David", &reply)
	if err != nil {
		panic("call failed")
	}

	fmt.Println(reply)
}

这样底层就会使用json格式传输数据

基于JSON,可以使用Python进行跨语言调用:

import json
import socket

request = {
    "id": 0,
    "params": ["David"],
    "method": "HelloService.HelloFunc"
}

client = socket.create_connection(("localhost", 9091))
client.sendall(json.dumps(request).encode())

resp = client.recv(1024)
resp = json.loads(resp.decode())
print(resp["result"])

结果:

Hello, David

基于HTTP协议传输

改写server:

func main() {
	_ = rpc.RegisterName("HelloService", &HelloService{})
	http.HandleFunc("/jsonrpc", func(w http.ResponseWriter, r *http.Request) {
		var conn io.ReadWriteCloser = struct {
			io.Writer
			io.ReadCloser
		}{
			ReadCloser: r.Body,
			Writer:     w,
		}
		_ = rpc.ServeRequest(jsonrpc.NewServerCodec(conn))
	})
	_ = http.ListenAndServe(":9090", nil)
}

这时在客户端使用HTTP POST请求发送JSON数据即可:

import requests

request = {
    "id": 0,
    "params": ["David"],
    "method": "HelloService.HelloFunc"
}

resp = requests.post("http://localhost:9090/jsonrpc", json=request)
print(resp.text)
posted @ 2022-11-29 23:23  N3ptune  阅读(152)  评论(0编辑  收藏  举报