在gRPC-Web中使用gRPC流需要一些特定的配置和代码实现。以下是一个基本的指南,展示如何在gRPC-Web中使用服务器流(Server Streaming)和客户端流(Client Streaming)。
首先,你需要定义你的gRPC服务和消息。假设你有一个简单的服务,支持服务器流和客户端流。
syntax = "proto3";
package stream;
service StreamService {
rpc ServerStreaming (ServerStreamingRequest) returns (stream ServerStreamingResponse);
rpc ClientStreaming (stream ClientStreamingRequest) returns (ClientStreamingResponse);
}
message ServerStreamingRequest {
string message = 1;
}
message ServerStreamingResponse {
string response = 1;
}
message ClientStreamingRequest {
string message = 1;
}
message ClientStreamingResponse {
string response = 1;
}
使用protoc
和protoc-gen-grpc-web
插件生成gRPC-Web客户端代码。
protoc -I=. --grpc-web_out=import_style=commonjs:./src stream.proto
由于浏览器的安全限制,gRPC-Web不能直接与gRPC服务器通信。你需要一个代理服务器来转发请求。常用的代理服务器有Envoy和grpcwebproxy。
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.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: grpc_service
http_filters:
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.router
clusters:
- name: grpc_service
connect_timeout: 0.25s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: grpc_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: your-grpc-server, port_value: 50051 }
envoy -c envoy.yaml
import { StreamServiceClient } from './stream_grpc_web_pb';
import { ServerStreamingRequest } from './stream_pb';
const client = new StreamServiceClient('http://localhost:8080');
const request = new ServerStreamingRequest();
request.setMessage('Hello');
const call = client.serverStreaming(request, {}, (err, response) => {
if (err) {
console.error(err);
}
});
call.on('data', (response) => {
console.log(response.getResponse());
});
call.on('end', () => {
console.log('Server streaming ended');
});
import { StreamServiceClient } from './stream_grp_web_pb';
import { ClientStreamingRequest, ClientStreamingResponse } from './stream_pb';
const client = new StreamServiceClient('http://localhost:8080');
const call = client.clientStreaming({}, (err, response) => {
if (err) {
console.error(err);
} else {
console.log(response.getResponse());
}
});
call.on('end', () => {
console.log('Client streaming ended');
});
// 发送多个请求
for (let i = 0; i < 5; i++) {
const request = new ClientStreamingRequest();
request.setMessage(`Message ${i}`);
call.write(request);
}
call.end();
领取专属 10元无门槛券
手把手带您无忧上云