Go从入门到精通—示例:模拟远程过程调用(RPC)
示例:模拟远程过程调用(RPC)
服务器开发中会使用 RPC(Remote Procedure Call,远程过程调用)简化进程间通信的过程。RPC 能有效低封装通信过程,让远程的数据收发通信过程看起来就像本地的函数调用一样。
本例中,使用通道替代 Socket 实现 RPC 的过程。客户端与服务器运行在同一个进程,服务器和客户端在两个 goroutine 中运行。
1、客户端请求和接收封装
下面的代码封装了向服务器请求数据,等待服务器返回数据,如果请求方超时,该函数还会处理超时逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //模拟 RPC 客户端的请求和接收消息封装 func RPCClient(ch chan string, req string)(string ,error){ //模拟 socket 向服务器发送一个字符串信息。服务器接收后,结束阻塞执行下一行。 ch <- req //等待服务器返回 select { //使用 select 做多路复用 case ack := <- ch: //接收到服务器返回数据 return ack,nil //使用了time包提供的函数After(),从字面意思看就是多少时间之后,其参数是time包的一个常量,time.Second 表示1秒。 //time.After()返回一个通道,这个通道在指定时间后,通过通道返回当前时间。 case <-time.After(time.Second): return "" ,errors.New( "Time out" ) //超时时,返回超时错误 } } |
2、服务器接收和反馈数据
服务器接收到客户端的任意数据后,先打印再通过通道返回给客户端一个固定字符串,表示服务器已经收到请求。
1 2 3 4 5 6 7 8 9 10 11 12 | //模拟 RPC 服务器端接受客户端请求和回应 func RPCServer(ch chan string) (string, error) { for { //接收客户端请求 data := <-ch //打印接收到的数据 fmt.Println( "Server received:" , data) //向客户端反馈已收到 ch <- "roger" } |
3、完整代码+模拟超时
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | package main import ( "errors" "fmt" "time" ) //模拟 RPC 客户端的请求和接收消息封装 func RPCClient(ch chan string, req string) (string, error) { //模拟 socket 向服务器发送一个字符串信息。服务器接收后,结束阻塞执行下一行。 ch <- req //等待服务器返回 select { //使用 select 做多路复用 case ack := <-ch: //接收到服务器返回数据 return ack, nil //使用了time包提供的函数After(),从字面意思看就是多少时间之后,其参数是time包的一个常量,time.Second 表示1秒。 //time.After()返回一个通道,这个通道在指定时间后,通过通道返回当前时间。 case <-time.After(time.Second): return "" , errors.New( "time out" ) //超时时,返回超时错误 } } //模拟 RPC 服务器端接受客户端请求和回应 func RPCServer(ch chan string) { for { //接收客户端请求 data := <-ch //打印接收到的数据 fmt.Println( "Server received:" , data) //通过睡眠函数让程序执行阻塞 2秒 的任务 time.Sleep(time.Second * 2) //向客户端反馈已收到 ch <- "roger" } } func main() { //创建一个无缓存字符串通道 ch := make( chan string) go RPCServer(ch) recv, err := RPCClient(ch, "hi" ) if err != nil { //发生错误 fmt.Println(err) } else { //正常接收到数据 fmt.Println( "client received" , recv) } } |
代码执行结果:
1 2 3 4 5 6 7 8 | Starting: D:\ go -testfiles\bin\dlv.exe dap --check- go -version=false --listen=127.0.0.1:50443 from d:\ go -testfiles DAP server listening at: 127.0.0.1:50443 Type 'dlv help' for list of commands. Server received: hi time out Process 7812 has exited with status 0 Detaching dlv dap (9404) exited with code: 0 |
分类:
Go专题精讲
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南