RPC(二)[RPC-Golang]

在这里插入图片描述
golang对prc进行了支持,使用时只需要导入net/rpc的包即可:

import "net/rpc"

rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问。服务端注册一个对象,使它作为一个服务被暴露,服务的名字是该对象的类型名。注册之后,对象的导出方法就可以被远程访问。服务端可以注册多个不同类型的对象(服务),但注册具有相同类型的多个对象是错误的。

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

  • 方法是导出的
  • 方法有两个参数,都是导出类型或内建类型
  • 方法的第二个参数是指针
  • 方法只有一个error接口类型的返回值
    事实上,方法必须看起来像这样:
func (t *T) MethodName(argType T1, replyType *T2) error

其中T、T1和T2都能被encoding/gob包序列化。这些限制即使使用不同的编解码器也适用。(未来,对定制的编解码器可能会使用较宽松一点的限制)
方法的第一个参数代表 调用者提供的参数 ;第二个参数代表 返回给调用者的参数 。方法的返回值,如果非nil,将被作为字符串回传,在客户端看来就和errors.New创建的一样。如果返回了错误,回复的参数将不会被发送给客户端。
服务端可能会单个连接上调用ServeConn管理请求。更典型地,它会创建一个网络监听器然后调用Accept;或者,对于HTTP监听器,调用HandleHTTP和http.Serve。
想要使用服务的客户端会创建一个连接,然后用该连接调用NewClient。
更方便的函数Dial(DialHTTP)会在一个原始的连接(或HTTP连接)上依次执行这两个步骤。
生成的Client类型值有两个方法,Call和Go,它们的参数为要调用的服务和方法、一个包含参数的指针、一个用于接收接个的指针。
Call方法会等待远端调用完成,而Go方法异步的发送调用请求并使用返回的Call结构体类型的Done通道字段传递完成信号。
除非设置了显式的编解码器,本包默认使用encoding/gob包来传输数据。

执行以下前提:安装配置好golang开发环境

1.服务端

1.编辑服务端代码

mkdir -p $GOPATH/src/rpctest/ && cd $_ && go mod init rpctest && mkdir -p srv && cd $_ && vim main.go

内容如下:

package main

import (
	"log"
	"net"
	"net/http"
	"net/rpc"
)

type Rpc struct {
}

/*
- 方法是导出的
- 方法有两个参数,都是导出类型或内建类型
- 方法的第二个参数是指针
- 方法只有一个error接口类型的返回值
func (t *T) MethodName(argType T1, replyType *T2) error
*/
func (r *Rpc) GetSum(argType int, replyType *int) error {
	*replyType = argType + 100
	return nil
}
func main() {
	// 1.结构体实例化
	rp := new(Rpc)
	// 2.rpc注册
	rpc.Register(rp)
	// 3.rpc网络
	rpc.HandleHTTP()
	// 4.监听网络
	ln, err := net.Listen("tcp", "127.0.0.1:8899")
	if err != nil {
		log.Fatal(err)
	}
	// 5.等待网络连接
	http.Serve(ln, nil)
}

2.开启服务端

cd $GOPATH/src/rpctest/srv && go run main.go

在这里插入图片描述

2.客户端

1.编辑客户端代码

再开一个终端执行客户端的操作,不要关闭服务端

mkdir -p $GOPATH/src/rpctest/ && cd $_ && mkdir -p cli && cd $_ && vim main.go

内容如下:

扫描二维码关注公众号,回复: 11134838 查看本文章
package main

import (
	"log"
	"net/rpc"
)

func main() {
	// 1.连接服务器
	cli, err := rpc.DialHTTP("tcp", "127.0.0.1:8899")
	if err != nil {
		log.Fatal(err)
	}
	// 2.调用函数
	// serviceMethod :服务方法名,是一个 [ 结构体.方法名 ] 的字符串
	// args :需要传入的参数
	// reply : 接收的变量参数
	//func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error
	var reply int
	err = cli.Call("Rpc.GetSum", 99, &reply)
	if err != nil {
		log.Fatal(err)
	}
	// 3.打印结果
	log.Println(reply)
}

2.执行客户端

前提:保证服务端已经开启

cd $GOPATH/src/rpctest/cli && go run main.go

在这里插入图片描述

发布了76 篇原创文章 · 获赞 15 · 访问量 6207

猜你喜欢

转载自blog.csdn.net/weixin_42366378/article/details/105748720
RPC
今日推荐