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 有了初步的认识。





目录
相关文章
|
6月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
1519 2
|
10月前
|
Go 开发者
Go语言包的组织与导入 -《Go语言实战指南》
本章详细介绍了Go语言中的包(Package)概念及其使用方法。包是实现代码模块化、复用性和可维护性的核心单位,内容涵盖包的基本定义、命名规则、组织结构以及导入方式。通过示例说明了如何创建和调用包,并深入讲解了`go.mod`文件对包路径的管理。此外,还提供了多种导入技巧,如别名导入、匿名导入等,帮助开发者优化代码结构与可读性。最后以表格形式总结了关键点,便于快速回顾和应用。
417 61
|
6月前
|
Java 编译器 Go
【Golang】(1)Go的运行流程步骤与包的概念
初次上手Go语言!先来了解它的运行流程吧! 在Go中对包的概念又有怎样不同的见解呢?
339 4
|
9月前
|
JSON 中间件 Go
Go语言实战指南 —— Go中的反射机制:reflect 包使用
Go语言中的反射机制通过`reflect`包实现,允许程序在运行时动态检查变量类型、获取或设置值、调用方法等。它适用于初中级开发者深入理解Go的动态能力,帮助构建通用工具、中间件和ORM系统等。
489 63
|
11月前
|
缓存 开发框架 .NET
一个功能丰富的 .NET 工具库 XiHan.Framework.Utils
XiHan.Framework.Utils 是一个功能全面的 .NET 工具库,包含字符串处理、集合扩展、加密解密、分布式 ID、文件操作、缓存、线程、国际化等模块。设计上注重高内聚、低耦合,适用于各类 .NET 应用开发。支持 AES 加密、树形结构转换、分页过滤、日志输出等功能,提供简单易用的 API。可通过 NuGet 快速安装,源码开放,采用 MIT 协议。
399 56
|
10月前
|
JSON 编解码 API
Go语言网络编程:使用 net/http 构建 RESTful API
本章介绍如何使用 Go 语言的 `net/http` 标准库构建 RESTful API。内容涵盖 RESTful API 的基本概念及规范,包括 GET、POST、PUT 和 DELETE 方法的实现。通过定义用户数据结构和模拟数据库,逐步实现获取用户列表、创建用户、更新用户、删除用户的 HTTP 路由处理函数。同时提供辅助函数用于路径参数解析,并展示如何设置路由器启动服务。最后通过 curl 或 Postman 测试接口功能。章节总结了路由分发、JSON 编解码、方法区分、并发安全管理和路径参数解析等关键点,为更复杂需求推荐第三方框架如 Gin、Echo 和 Chi。
|
8月前
|
缓存 监控 安全
告别缓存击穿!Go 语言中的防并发神器:singleflight 包深度解析
在高并发场景中,多个请求同时访问同一资源易导致缓存击穿、数据库压力过大。Go 语言提供的 `singleflight` 包可将相同 key 的请求合并,仅执行一次实际操作,其余请求共享结果,有效降低系统负载。本文详解其原理、实现及典型应用场景,并附示例代码,助你掌握高并发优化技巧。
581 0
|
11月前
|
Go
在golang中发起http请求以获取访问域名的ip地址实例(使用net, httptrace库)
这只是追踪我们的行程的简单方法,不过希望你跟着探险家的脚步,即使是在互联网的隧道中,也可以找到你想去的地方。接下来就是你的探险之旅了,祝你好运!
593 26
|
11月前
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
257 10
|
11月前
|
Go 持续交付 开发者
Go语言包与模块(module)的基本使用-《Go语言实战指南》
本章深入讲解Go语言中的包(Package)和模块(Module)概念。包是代码组织的最小单位,每个`.go`文件属于一个包,通过`import`实现复用;主程序包需命名为`main`。模块是Go 1.11引入的依赖管理机制,支持自动版本管理和私有/远程仓库,无需依赖GOPATH。通过实际示例,如自定义包`mathutil`和第三方模块`gin`的引入,展示其使用方法。常用命令包括`go mod init`、`go mod tidy`等,帮助开发者高效管理项目依赖。最后总结,包负责功能划分,模块实现现代化依赖管理,提升团队协作效率。
441 15
下一篇
开通oss服务