golang——net/rpc包学习

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)"

原文地址:https://www.cnblogs.com/dzhy/p/11086905.html

时间: 2024-11-06 07:50:14

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

golang中context包学习

摘要 go语言中goroutine之间的关联关系,缺乏维护,在erlang中有专门的机制来保障新开仟程的生命周期, 在go语言中,只能通过channel + select来实现,但不够直观,感觉很绕. Context 通常被译作 上下文 ,它是一个比较抽象的概念.在公司技术讨论时也经常会提到 上下文 .一般理解为程序单元的一个运行状态.现场.快照,而翻译中 上下 又很好地诠释了其本质,上下上下则是存在上下层的传递, 上 会把内容传递给 下 .在Go语言中,程序单元也就指的是Goroutine.

golang中的rpc包用法

RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服务之间的沟通越来越频繁,就希望可以做成用rpc来做内部的通讯,对外依然用Restful.于是就想到了golang标准库的rpc包和google的grpc. 这篇文章重点了解一下golang的rpc包. 介绍 golang的rpc支持三个级别的RPC:TCP.HTTP.JSONRPC.但Go的RPC包

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

R语言爬虫初尝试-基于RVEST包学习 Thursday, February 26, 2015 在学完coursera的getting and Cleaning data后,继续学习用R弄爬虫网络爬虫.主要用的还是Hadley Wickham开发的rvest包.再次给这位矜矜业业开发各种好用的R包的大神奉上膝盖 查阅资料如下: rvest的github rvest自身的帮助文档 rvest + CSS Selector 网页数据抓取的最佳选择-戴申: 里面有提及如何快速获得html的位置.看完这

golang的sync包例子

package main import ( "fmt" "sync" ) var wg sync.WaitGroup func asyncTestFunc() { for i := 0; i < 100; i++ { fmt.Println(i) } wg.Done() } func main() { wg.Add(1) go asyncTestFunc() wg.Wait() } golang的sync包例子

golang的io包

package io import "io" io包提供了对I/O原语的基本接口.本包的基本任务是包装这些原语已有的实现(如os包里的原语),使之成为共享的公共接口,这些公共接口抽象出了泛用的函数并附加了一些相关的原语的操作. 因为这些接口和原语是对底层实现完全不同的低水平操作的包装,除非得到其它方面的通知,客户端不应假设它们是并发执行安全的. Index Variables type Reader type Writer type Closer type Seeker type Re

使用golang的pprof包对程序进行性能分析

程序经常出现OOM错误,然后关键字"go pprof"搜到文章<Go程序性能分析pprof>,该文章第二步说运行程序后会生成profile文件,但是编译运行后发现生成的profile文件大小一直为0,然后关键字"go pprof profile is empty"搜到文章<Golang pprof heap profile is empty>,该文章说在运行程序前添加环境变量GODEBUG="memprofilerate=1&quo

golang 中io包用法(一)

本文转自Golove博客:http://www.cnblogs.com/golove/p/3276678.html io 包为I/O原语提供了基础的接口.它主要包装了这些原语的已有实现,如 os 包中的那些,抽象成函数性的共享公共接口,加上一些其它相关的原语. 由于这些接口和原语以不同的实现包装了低级操作,因此除非另行通知,否则客户不应假定它们对于并行执行是安全的. 在io包中最重要的是两个接口:Reader和Writer接口,首先来介绍这两个接口. type Reader interface

Golang Gin 项目包依赖管理 godep 使用

Golang Gin 项目包依赖管理 godep 使用 标签(空格分隔): Go 在按照github.com/tools/godep文档go get完包以后,调整项目结构为$GOPATH/src/$PROJECT_NAME/,同时使项目编译没有问题.执行godep save命令,出现了一系列包缺失的问题: github.com/campoy/embedmd github.com/client9/misspell/cmd/misspell github.com/dustin/go-broadcas

Golang官方log包详解

Golang官方log包详解 以下全是代码, 详解在注释中, 请从头到尾看 // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package log implements a simple logging package. I