Go 使用标准库 net/rpc 包

简介: Go 使用标准库 net/rpc 包

01

RPC 是什么?


RPC 是远程过程调用(Remote Procedure Call),用于调用方和被调用方两个进程间的交互,并且提供类似本地方法调用的形式。RPC 广泛用于在分布式系统中不同节点间的通信。


02

Go 语言 RPC 标准库


在 Go 语言的标准库中,也提供了一个简单的 RPC 实现(net/rpc)。rpc 包提供对对象在网络或其他 I/O 连接中导出方法的访问。服务器端注册对象,使其作为可见服务,服务的名称是对象类型名称。注册后,对象的导出方法将可远程访问。服务器可以注册不同类型的多个对象(服务),但注册同一类型的多个对象是错误的。


对象的导出方法有以下几点要求:

  • 方法的类型是可导出的。
  • 方法是可导出的。
  • 方法有两个参数,都是可导出类型或内置类型。
  • 方法的第二个参数是指针。
  • 方法返回一个错误类型。


实际上,方法看起来像这样:


func (t *T) MethodName(argType T1, replyType *T2) error


其中 T1 和 T2 可以通过 encoding/gob 编码进行序列化。即使使用不同的编码解码器,这些限制也适用。将来,对自定义的编码解码器的限制可能会宽松一些。


该方法的第一个参数表示调用方提供的参数;第二个参数表示要返回给调用方的结果参数。方法的返回值(如果不是 nil)作为字符串传递回来,客户端认为该字符串就像由 errors.New 创建的错误一样。如果返回错误,则不会将回复参数发送回客户端。


服务器端可以调用 ServeConn 处理单个连接上的请求。更典型的是,它将创建一个网络监听器并调用 Accept,或者,对于 HTTP 监听器,调用 HandleHTTP 和 http.Serve。


想要使用该服务的客户端会建立连接,然后在连接上调用 NewClient。

更方便的函数是 Dial (DialHTTP) ,会在原始网络连接(HTTP 连接)依次执行这两个步骤。生成的 Client 对象有两个方法,即 Call 和 Go,它们的参数是要调用的服务和方法,一个包含参数的指针,一个用于接收结果的指针。


Call 方法等待远程调用完成。Go 方法异步发送调用请求,并使用返回的 Call结构体类型的 "Done 通道" 传递完成的信号。


除非显式设置了编码解码器,否则 net/rpc 包默认采用 encoding/gob 包编码解码数据。


03

RPC 怎么使用?


通过一个简单的示例,我们演示 Go 语言标准库 net/rpc 的使用方法。


RPC 方法:

服务器端定义一个可导出的 User 类型和一个符合 RPC 方法定义要求的 GetUser 方法:


type User struct {
  ID   int
  Name string
}
// rpc 方法
func (u *User) GetUser(id int, user *User) error {
  userMap := map[int]User{
    1: {ID: 1, Name: "frank"},
    2: {ID: 2, Name: "lucy"},
  }
  if userInfo, ok := userMap[id]; ok {
    *user = userInfo
  }
  return nil
}


服务器端:

服务器端被调用(用于 HTTP 服务):


func main() {
  _ = rpc.Register(new(message.User))
  rpc.HandleHTTP()
  listener, _ := net.Listen("tcp", ":8081")
  _ = http.Serve(listener, nil)
}


客户端:

此时,客户端可以看到具有 "User.GetUser" 方法的服务 "User"。要调用方法,客户端首先呼叫服务器端:


client, _ := rpc.DialHTTP("tcp", ":8081")


然后客户端可以进行远程调用:

Call 方法,同步调用:


id := 1
var user message.User
_ = client.Call("User.GetUser", id, &user)
fmt.Println(user)


Go 方法,异步调用:


userCall := client.Go("User.GetUser", id, &user, nil)
if replyCall := <-userCall.Done; replyCall != nil {
  fmt.Println(user)
}


服务器端的实现通常为客户端提供简单、类型安全的包装。


net/rpc 包已冻结,不接受新功能。


04

总结


本文简要描述 Go 语言标准库 net/rpc 包的使用方法,通过阅读本文,读者应该已经对Go 语言标准库 net/rpc 有了初步的认识。





目录
相关文章
|
8天前
|
C#
一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
|
8天前
|
人工智能 自然语言处理 API
适用于 .NET 稳定的官方OpenAI库
适用于 .NET 稳定的官方OpenAI库
|
30天前
|
开发框架 .NET 测试技术
了解 .NET 9 中的新 Microsoft.AspNetCore.OpenApi 包,并将其与 NSwag 和 Swashbuckle.AspNetCore 进行比较。
本文介绍了 `.NET 9` 中新推出的 `Microsoft.AspNetCore.OpenApi` 包,该包旨在为 `ASP.NET Core` 应用程序生成 `OpenAPI` 文档。文章对比了 `NSwag` 和 `Swashbuckle.AspNetCore` 两大现有库,探讨了新包的优势和不足,特别是在性能和功能方面。尽管新包在某些方面尚不及成熟库完善,但其对原生 `AoT` 编译的支持和未来的扩展潜力使其成为一个值得考虑的选择。文章还提供了详细的性能测试数据和优化建议,适合对 `OpenAPI` 文档生成感兴趣的开发者阅读。
72 3
了解 .NET 9 中的新 Microsoft.AspNetCore.OpenApi 包,并将其与 NSwag 和 Swashbuckle.AspNetCore 进行比较。
|
14天前
|
编译器 Go 开发者
go语言中导入相关包
【11月更文挑战第1天】
27 3
|
17天前
|
存储 Cloud Native Shell
go库介绍:Golang中的Viper库
Viper 是 Golang 中的一个强大配置管理库,支持环境变量、命令行参数、远程配置等多种配置来源。本文详细介绍了 Viper 的核心特点、应用场景及使用方法,并通过示例展示了其强大功能。无论是简单的 CLI 工具还是复杂的分布式系统,Viper 都能提供优雅的配置管理方案。
|
20天前
|
JSON 安全 网络协议
go语言使用内置函数和标准库
【10月更文挑战第18天】
14 3
|
22天前
|
JSON 监控 安全
go语言选择合适的工具和库
【10月更文挑战第17天】
12 2
|
29天前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
23 1
|
8天前
|
开发框架 安全 .NET
.NET使用Moq开源模拟库简化单元测试
.NET使用Moq开源模拟库简化单元测试~
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
42 7