1、rpc包

rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问。

只有满足如下标准的方法才能用于远程访问,其余方法会被忽略:

(1)方法是导出的
(2)方法有两个参数,都是导出类型或内建类型
(3)方法的第二个参数是指针
(4)方法只有一个error接口类型的返回值

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

其中T、T1和T2都能被encoding/gob包序列化。

方法的第一个参数代表调用者提供的参数;第二个参数代表返回给调用者的参数。

方法的返回值,如果非nil,将被作为字符串回传,在客户端看来就和errors.New创建的一样。

如果返回了错误,回复的参数将不会被发送给客户端。

代码示例:

package main

import (
"errors"
"fmt"
"log"
"net"
"net/http"
"net/rpc"
) // Args 参数
type Args struct {
A, B int
} // Quotient 商、余数
type Quotient struct {
Quo, Rem int
} // Arith 算术服务
type Arith int // Multiply 乘法服务
func (*Arith) Multiply(args *Args, reply *int) error {
*reply = args.A * args.B
return nil
} // Divide 除法服务
func (*Arith) Divide(args *Args, quo *Quotient) error {
if args.B == 0 {
return errors.New("除数不能为零")
}
quo.Quo = args.A / args.B
quo.Rem = args.A % args.B
return nil
} // 错误检查
func checkErr(err error) {
if err != nil {
log.Fatalln(err)
}
} func main() {
//开启服务
arith := new(Arith)
//使用默认服务对象
err := rpc.Register(arith)
checkErr(err)
//默认路径
// const (
// DefaultRPCPath = "/_goRPC_"
// DefaultDebugPath = "/debug/rpc"
// )
rpc.HandleHTTP()
//设置监听
lis, err := net.Listen("tcp", ":1234")
checkErr(err)
go http.Serve(lis, nil) //客户端请求服务
client, err := rpc.DialHTTP("tcp", ":1234")
checkErr(err)
defer client.Close()
//乘法
args := &Args{A: 17, B: 3}
var reply int
err = client.Call("Arith.Multiply", args, &reply)
checkErr(err)
fmt.Printf("Arith.Multiply:%d * %d = %d\n", args.A, args.B, reply)
//除法
quotient := new(Quotient)
call := client.Go("Arith.Divide", args, quotient, nil)
<-call.Done
fmt.Printf("Arith.Divide:%d / %d = %d .... %d\n", args.A, args.B, quotient.Quo, quotient.Rem)
} //输出
//Arith.Multiply:17 * 3 = 51
// Arith.Divide:17 / 3 = 5 .... 2

2、客户端

2.1、type Client struct{}

Client类型代表RPC客户端。

同一个客户端可能有多个未返回的调用,也可能被多个go程同时使用。

2.2、常用方法

(1)func NewClient(conn io.ReadWriteCloser) *Client

NewClient返回一个新的Client,以管理对连接另一端的服务的请求。

(2)func Dial(network, address string) (*Client, error)

Dial在指定的网络和地址与RPC服务端连接。

(3)func DialHTTP(network, address string) (*Client, error)

DialHTTP在指定的网络和地址与在默认HTTP RPC路径监听的HTTP RPC服务端连接。

(4)func DialHTTPPath(network, address, path string) (*Client, error)

DialHTTPPath在指定的网络、地址和路径与HTTP RPC服务端连接。

(5)func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error

Call调用指定的方法,等待调用返回,将结果写入reply,然后返回执行的错误状态。

(6)func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call

Go异步的调用函数。本方法Call结构体类型指针的返回值代表该次远程调用。

通道类型的参数done会在本次调用完成时发出信号(通过返回本次Go方法的返回值)。

如果done为nil,Go会申请一个新的通道(写入返回值的Done字段);如果done非nil,done必须有缓冲,否则Go方法会故意崩溃。

(7)func (client *Client) Close() error

关闭客户端。

3、服务端

3.1、type Server struct{}

rpc包提供默认的服务对象,可直接通过“rpc.”进行使用。

3.2、常用方法

(1)func NewServer() *Server

创建并返回一个*Server。

(2)func (server *Server) Register(rcvr interface{}) error

注册服务。

如果rcvr不是一个导出类型的值,或者该类型没有满足要求的方法,Register会返回错误。

Register也会使用log包将错误写入日志。

客户端可以使用格式为"Type.Method"的字符串访问这些方法,其中Type是rcvr的具体类型。

(3)func (server *Server) RegisterName(name string, rcvr interface{}) error

RegisterName类似Register,但使用提供的name代替rcvr的具体类型名作为服务名。

(4)func (server *Server) Accept(lis net.Listener)

Accept接收监听器l获取的连接,然后服务每一个连接。

Accept会阻塞,调用者应另开线程。

(5)func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP实现了回应RPC请求的http.Handler接口。

(6)func (server *Server) HandleHTTP(rpcPath, debugPath string)

HandleHTTP注册server的RPC信息HTTP处理器对应到rpcPath,注册server的debug信息HTTP处理器对应到debugPath。

HandleHTTP会注册到http.DefaultServeMux。之后,仍需要调用http.Serve(),一般会另开线程:"go http.Serve(l, nil)"

golang——net/rpc包学习的更多相关文章

  1. golang中context包学习

    摘要 go语言中goroutine之间的关联关系,缺乏维护,在erlang中有专门的机制来保障新开仟程的生命周期, 在go语言中,只能通过channel + select来实现,但不够直观,感觉很绕. ...

  2. golang——database/sql包学习

    1.database/sql包 sql包提供了保证SQL或类SQL数据库的泛用接口. 使用sql包时必须注入(至少)一个数据库驱动. (1)获取mysql driver:go get -v githu ...

  3. golang中的rpc包用法

    RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服 ...

  4. golang——net/rpc/jsonrpc包学习

    1.jsonrpc包 该实现了JSON-RPC的ClientCodec和ServerCodec接口,可用于rpc包. 可用于跨语言使用go rpc服务. 2.常用方法 (1)func Dial(net ...

  5. github上的golang双向rpc,基于原生“net/rpc”库实现,可以注册回调

    github上的golang双向rpc,基于原生“net/rpc”库实现,可以注册回调.仅支持一个server和一个client交互. 地址:https://github.com/rocket049/ ...

  6. golang 关于golang.org/x包问题

    关于golang.org/x包问题 由于谷歌被墙,跟谷歌相关的模块无法通过go get来下载,解决方法: git clone https://github.com/golang/net.git $GO ...

  7. 关于golang的time包总结

    目录 前言 time包详解 总结 前言 各种编程语言都少不了与时间有关的操作,因为很多判断都是基于时间,因此正确和方便的使用时间库就很重要额. golang提供了import "time&q ...

  8. R语言爬虫初尝试-基于RVEST包学习

    注意:这文章是2月份写的,拉勾网早改版了,代码已经失效了,大家意思意思就好,主要看代码的使用方法吧.. 最近一直在用且有维护的另一个爬虫是KINDLE 特价书爬虫,blog地址见此: http://w ...

  9. Golang爬虫示例包系列教程(一):pedaily.com投资界爬虫

    Golang爬虫示例包 文件结构 自己用Golang原生包封装了一个爬虫库,源码见go get -u -v github.com/hunterhug/go_tool/spider ---- data ...

随机推荐

  1. Codeforces Round #655 (Div. 2) C. Omkar and Baseball (思维)

    题意:有一个数组,每次可以修改子数组,但是修改后每个元素的位置都必须变化,求最少修改多少次使得这个数组有序. 题解:假如这个数组本来就有序,我们直接输出0.否则,对于数组两端,假如它们有序,那么我们可 ...

  2. 踏上Revit二次开发之路 3 自己的工具按钮

    3 自己的工具按钮 上次的例子只能在"附加模块"→"外部工具"下运行,用作个人作品是没问题,如果打算搞个公司产品的话,估计BOSS是不会满意的.这次我来做一个直 ...

  3. 国产smartbits版本-minismb如何测试路由器III

    Minismb测试仪表是复刻smartbits的国产版本,是一款专门用于测试智能路由器,网络交换机的性能和稳定性的软硬件相结合的工具.可以通过此工具测试任何ip网络设备的端口吞吐率,带宽,并发连接数和 ...

  4. Hexo、主题、部署上线

    Hexo.主题.部署上线 安装Hexo git和nodejs安装好后,就可以安装hexo了,你可以先创建一个文件夹MyBlog,用来存放自己的博客文件,然后cd到这个文件夹下(或者在这个文件夹下直接右 ...

  5. 使用MCSManager搭建Minecraft服务器

    目录 一.准备工作 1.MCSManager Windows环境下安装 Linux安装 2.Minecraft服务端 3.Java 二.配置 1.登录面板 2.上传服务端 3.服务端的配置 三.开启服 ...

  6. Promise nested then execute order All In One

    Promise nested then execute order All In One Promise nested then nested Promise not return new Promi ...

  7. React & react-native & vue & cli & environment information & report bugs

    React & react-native & vue & cli & environment information & report bugs cli che ...

  8. js 增加数组的嵌套层数

    class A {} const proxy = new Proxy(new A(), { get(o, k) { if (!/\d+/.test(k.toString())) return o[k] ...

  9. Swift 5.1

    Swift 5.1 WebView & WKWebView https://developer.apple.com/swift-playgrounds/ https://developer.a ...

  10. NGK公链存储技术,如何开创应用落地新格局?

    尽管无人预测未来,但是资本的眼光总是那么灵敏,最近几年,国际资本市场纷纷将目光投到了公链市场上.从TPS高点备受抢占,再到DApp生态的不断涌现,再到目前Staking和Defi的新概念生态的不断发力 ...