基础教程
gRPC-web 的基础教程介绍。
基础教程
本教程提供了如何从浏览器使用 gRPC-Web 的基本介绍。
通过此示例,您将学习如何
- 在 .proto 文件中定义服务。
- 使用协议缓冲区编译器生成客户端代码。
- 使用 gRPC-Web API 为您的服务编写一个简单的客户端。
本教程假定您对 Protocol Buffers 有一定的了解。
为什么要使用 gRPC 和 gRPC-Web?
通过 gRPC,您可以在 .proto 文件中一次性定义服务,并使用 gRPC 支持的任何语言实现客户端和服务器。这些客户端和服务器可以在从大型数据中心内的服务器到您自己的平板电脑等各种环境中运行——不同语言和环境之间通信的所有复杂性都由 gRPC 为您处理。您还将获得使用 Protocol Buffers 的所有优势,包括高效的序列化、简单的 IDL 和便捷的接口更新。gRPC-Web 允许您从浏览器使用符合习惯的 API 访问以此方式构建的 gRPC 服务。
定义服务
创建 gRPC 服务的第一步是使用 Protocol Buffers 定义服务方法及其请求和响应消息类型。在本示例中,我们在名为 echo.proto
的文件中定义了我们的 EchoService
。有关 Protocol Buffers 和 proto3 语法的更多信息,请参阅 Protobuf 文档。
message EchoRequest {
string message = 1;
}
message EchoResponse {
string message = 1;
}
service EchoService {
rpc Echo(EchoRequest) returns (EchoResponse);
}
实现 gRPC 后端服务器
接下来,我们在后端 gRPC EchoServer
中使用 Node 实现 EchoService
接口。这将处理来自客户端的请求。有关详细信息,请参阅文件 node-server/server.js
。
您可以使用 gRPC 支持的任何语言实现服务器。请参阅主页了解更多详细信息。
function doEcho(call, callback) {
callback(null, {message: call.request.message});
}
配置 Envoy 代理
在此示例中,我们将使用 Envoy 代理将 gRPC 浏览器请求转发到后端服务器。您可以在 envoy.yaml 中查看完整的配置文件。
要将 gRPC 请求转发到后端服务器,我们需要一个类似这样的配置块:
admin:
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: echo_service }
http_filters:
- name: envoy.grpc_web
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: echo_service
connect_timeout: 0.25s
type: LOGICAL_DNS
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: echo_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: node-server
port_value: 9090
您可能还需要添加一些 CORS 设置,以确保浏览器可以请求跨源内容。
在这个简单的示例中,浏览器向端口 :8080
发送 gRPC 请求。Envoy 将请求转发到监听端口 :9090
的后端 gRPC 服务器。
生成 Protobuf 消息和服务客户端存根
要从我们的 echo.proto
文件生成 Protobuf 消息类,请运行以下命令:
protoc -I=$DIR echo.proto \
--js_out=import_style=commonjs:$OUT_DIR
传递给 --js_out
标志的 import_style
选项确保生成的文件将包含 CommonJS 风格的 require()
语句。
要生成 gRPC-Web 服务客户端存根,首先需要 gRPC-Web protoc 插件。要编译插件 protoc-gen-grpc-web
,您需要在仓库的根目录运行以下命令:
cd grpc-web
sudo make install-plugin
要生成服务客户端存根文件,请运行以下命令:
protoc -I=$DIR echo.proto \
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:$OUT_DIR
在上述 --grpc-web_out
参数中:
mode
可以是grpcwebtext
(默认)或grpcweb
import_style
可以是closure
(默认)或commonjs
我们的命令默认将客户端存根生成到文件 echo_grpc_web_pb.js
。
编写 JS 客户端代码
现在您可以编写一些 JS 客户端代码了。将其放入 client.js
文件中。
const {EchoRequest, EchoResponse} = require('./echo_pb.js');
const {EchoServiceClient} = require('./echo_grpc_web_pb.js');
var echoService = new EchoServiceClient('https://:8080');
var request = new EchoRequest();
request.setMessage('Hello World!');
echoService.echo(request, {}, function(err, response) {
// ...
});
您需要一个 package.json
文件
{
"name": "grpc-web-commonjs-example",
"dependencies": {
"google-protobuf": "^3.6.1",
"grpc-web": "^0.4.0"
},
"devDependencies": {
"browserify": "^16.2.2",
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0"
}
}
编译 JS 库
最后,将所有这些组合在一起,我们可以将所有相关的 JS 文件编译成一个可以在浏览器中使用的单个 JS 库。
npm install
npx webpack client.js
现在将 dist/main.js
嵌入到您的项目中,并查看它的实际运行效果!