内网穿透即是使用公网服务器作为代理,转发内网(如办公室、家里)的网络请求使其能够在外网中被访问到。
目前成都创新互联已为1000多家的企业提供了网站建设、域名、网络空间、网站托管、服务器托管、企业网站设计、伊通网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
server端监听两个端口,一个用来和接收用户的http请求,一个监听gRPC客户端,和内网服务器进行通信;
client启动时连接server端;
当User请求server http端口时,将http进行阻塞,并将User请求内容通过gRPC发给client;
client将从server收到的请求发往本地的http服务;
client将从本地程序收到的http response通过gRPC发送给server;
server结束http阻塞,将从client收到的http response发给User。
github地址:
之前写过了Grpc服务开发和接口测试初探【Java】,中间耽搁了一些时间,Go版本的gRPC测试开发实践才有时间学习使用。其中也是由于自己Go语言不够熟悉导致的。之前有段时间想暂时放弃Go语言的学习,导致了Go的生疏,原因是从Groovy到Java性能。
回归正题,Go语言版本的gRPC实践相对Java来说是比较简单的,但是总体的工具链是比较复杂的,可能是因为Go生态目前相比Java还是比较匮乏吧。下面我先简述一下大致的步骤:
以上步骤亲自操作可能会遇到一些小问题,我本人搜到的教程什么的也是乱七八糟,踩了一些坑。我没有整理出一个亲自实践之后的可行的教程,原因有二:
Go语言的gRPC的 proto 编写跟Java大致一致,只有一个报名的参数不太一样。下面是我的 Hello.proto 内容:
这里主要 go_package 网上搜到的配置方式有些不一样,我没有全都尝试,大家在搜索的资料时候,尽量先看看 syntax 这个参数的值,以及文章教程写作的时间,如果距离现在太久了,我建议直接关掉。搜索引擎有过滤功能,可以过滤掉过时的教程。
这里Go语言gRPC的一点优势,就是在一个项目中即可实现,Java需要先弄一个SDK这样。Go语言的gRPC的代码可以通过生成代码命令中的参数实现指定路径。我是放在了和 proto 文件的同级目录。
服务端代码也是比较格式化的内容,如下:
其中 pb.RegisterHelloServiceServer(s, Ser{}) 如果报错,请检查自己安装的工具 protoc-gen-go 或者 protoc-gen-gofast 版本,一般提取报错 message 搜索也能得到解决办法。
下面是客户端的代码,由于学艺不精,其中大部分参数的含义目前我也不是很清楚,特别是基于 stream 的请求响应的方式使用。后面我先把Java的学完,再回过头来看Go的,按照这个顺序学习和分享。
服务端输出:
忘记打日志了。没有输出
客户端输出:
Go语言的gRPC测试开发实践已经完事儿,大概率上我不会在工作中使用Go作为主力gRPC测试语言,后面测试实践内容还是会以Java为主。
在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端 应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。
gRPC 客户端和服务端可以在多种环境中运行和交互 - 从 google 内部的服务器到你自己的笔记本,并且可以用任何 gRPC 支持的语言来编写。所以,你可以很容易地用 Java 创建一个 gRPC 服务端,用 Go、Python、Ruby 来创建客户端。此外,Google 最新 API 将有 gRPC 版本的接口,使你很容易地将 Google 的功能集成到你的应用里。
gRPC 默认使用 protocol buffers,这是 Google 开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格式如 JSON)。名叫 proto3 的新风格的 protocol buffers,它拥有轻量简化的语法、一些有用的新功能,并且支持更多新语言。当前针对 Java 和 C++ 发布了 beta 版本,针对 JavaNano(即 Android Java)发布 alpha 版本,在protocol buffers Github 源码库里有 Ruby 支持, 在golang/protobuf Github 源码库里还有针对 Go 语言的生成器, 对更多语言的支持正在开发中。
有了 gRPC, 我们可以一次性的在一个 .proto 文件中定义服务并使用任何支持它的语言去实现客户端和服务器,反过来,它们可以在各种环境中,从Google的服务器到你自己的平板电脑—— gRPC 帮你解决了不同语言及环境间通信的复杂性.使用 protocol buffers 还能获得其他好处,包括高效的序列号,简单的 IDL 以及容易进行接口更新。
现在让我们来仔细了解一下当 gRPC 客户端调用 gRPC 服务端的方法时到底发生了什么。我们不究其实现细节,关于实现细节的部分,你可以在我们的特定语言页面里找到更为详尽的内容。
首先我们来了解一下最简单的 RPC 形式:客户端发出单个请求,获得单个响应。
服务端流式 RPC 除了在得到客户端请求信息后发送回一个应答流之外,与我们的简单例子一样。在发送完所有应答后,服务端的状态详情(状态码和可选的状态信息)和可选的跟踪元数据被发送回客户端,以此来完成服务端的工作。客户端在接收到所有服务端的应答后也完成了工作。
客户端流式 RPC 也基本与我们的简单例子一样,区别在于客户端通过发送一个请求流给服务端,取代了原先发送的单个请求。服务端通常(但并不必须)会在接收到客户端所有的请求后发送回一个应答,其中附带有它的状态详情和可选的跟踪数据。
双向流式 RPC ,调用由客户端调用方法来初始化,而服务端则接收到客户端的元数据,方法名和截止时间。服务端可以选择发送回它的初始元数据或等待客户端发送请求。 下一步怎样发展取决于应用,因为客户端和服务端能在任意顺序上读写 - 这些流的操作是完全独立的。例如服务端可以一直等直到它接收到所有客户端的消息才写应答,或者服务端和客户端可以像"乒乓球"一样:服务端后得到一个请求就回送一个应答,接着客户端根据应答来发送另一个请求,以此类推。
通过运行下面的命令克隆并安装grpc-go代码库:
下载protobuf源码包
安装golang-protobuf
第一步使用 protocol buffers去定义 gRPC service 和方法 request 以及 response 的类型。
要定义一个服务,必须在.proto 文件中指定 service:
然后在服务中定义 rpc 方法,指定请求的和响应类型,gRPC 允许定义4种类型的 service 方法。
服务.proto文件如下所示: