go语言之rpc支持json
标准库的RPC默认采用Go语言特有的gob编码,因此从其它语言调用Go语言实现的RPC服务将比较困难。在互联网的微服务时代,每个RPC以及服务的使用者都可能采用不同的编程语言,因此跨语言是互联网时代RPC的一个首要条件。得益于RPC的框架设计,Go语言的RPC其实也是很容易实现跨语言支持的。
Go语言的RPC框架有两个比较有特色的设计:一个是RPC数据打包时可以通过插件实现自定义的编码和解码;另一个是RPC建立在抽象的io.ReadWriteCloser接口之上的,我们可以将RPC架设在不同的通讯协议之上。这里我们将尝试通过官方自带的net/rpc/jsonrpc扩展实现一个跨语言的PPC。
1、服务端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package main import ( "net" "net/rpc" "net/rpc/jsonrpc" ) type HelloService struct {} func (s *HelloService) Hello(request string, reply *string) error { *reply = "hello " + request return nil } func main(){ rpc.RegisterName( "HelloService" , new(HelloService)) listener, err := net.Listen( "tcp" , ":1234" ) if err != nil { panic( "启动错误" ) } for { conn, err := listener.Accept() if err != nil { panic( "接收" ) } go rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) } } |
代码中最大的变化是用rpc.ServeCodec函数替代了rpc.ServeConn函数,传入的参数是针对服务端的json编解码器。
2、客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package main import ( "fmt" "net" "net/rpc" "net/rpc/jsonrpc" ) func main(){ conn, err := net.Dial( "tcp" , "localhost:1234" ) if err != nil { panic( "连接错误" ) } client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn)) var reply string err = client.Call( "HelloService.Hello" , "imooc" , &reply) if err != nil { panic( "调用错误" ) } fmt.Println(reply) } |
3、python代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import json import socket import itertools import time class JSONClient(object): def __init__(self, addr): self.socket = socket.create_connection(addr) self.id_counter = itertools.count() def __del__(self): self.socket.close() def call(self, name, *params): request = dict(id=next(self.id_counter), params=list(params), method=name) self.socket.sendall(json.dumps(request).encode()) # This must loop if resp is bigger than 4K response = self.socket.recv(4096) response = json.loads(response.decode()) if response.get( 'id' ) != request.get( 'id' ): raise Exception( "expected id=%s, received id=%s: %s" %(request.get( 'id' ), response.get( 'id' ), response.get( 'error' ))) if response.get( 'error' ) is not None: raise Exception(response.get( 'error' )) return response.get( 'result' ) def close(self): self._socket.close() if __name__ == '__main__' : rpc = JSONClient(( "localhost" , 1234)) args = "hello" print(rpc.call( "HelloService.Hello" , args)) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码