特使 GRPC 反向桥 - 已收到 RST_STREAM,代码为 0
Envoy GRPC Reverse Bridge - Received RST_STREAM with code 0
我正在尝试通过 Envoy GRPC 反向桥通过 GRPC 客户端访问 HTTP1.1 rest API。但是当我测试它时,出现以下错误。任何帮助或示例代码片段将不胜感激。谢谢!
Error: 13 INTERNAL: Received RST_STREAM with code 0
at Object.callErrorFromStatus (/Users/meiyappan/grpc-node/grpc/examples/node/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/Users/meiyappan/grpc-node/grpc/examples/node/node_modules/@grpc/grpc-js/build/src/client.js:176:52)
我的 Envoy 代理配置 XML
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: 50051
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
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: grpc
timeout: 50.00s
# per_filter_config disables the filter for this route
typed_per_filter_config:
envoy.filters.http.grpc_http1_reverse_bridge:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_reverse_bridge.v3.FilterConfigPerRoute
disabled: true
http_filters:
- name: envoy.filters.http.grpc_http1_reverse_bridge
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_reverse_bridge.v3.FilterConfig
content_type: application/grpc
withhold_grpc_frames: true
- name: envoy.filters.http.router
clusters:
- name: grpc
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: grpc
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: localhost
port_value: 80
这是原型文件
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
我的 HTTP Rest API,使用 Node-Express
app.post('/helloworld.greeter/SayHello', async (req, res) => {
console.log(req)
const root = await protobuf.load(PROTO_PATH);
const HelloReply = root.lookupType('helloworld.HelloReply');
const buf = HelloReply.encode({ message: 'Hello Bill'}).finish();
res.send(buf)
res.end();
})
节点js中的GRPC客户端代码
function main() {
var target = 'localhost:50051';
var client = new hello_proto.Greeter(target,
grpc.credentials.createInsecure());
var user = 'world';
var metadata = new grpc.Metadata();
metadata.add('Content-Type', 'application/grpc')
client.sayHello({name: user},metadata, function(err, response) {
console.log(err)
console.log('Greeting:', response);
});
}
我已经成功复现了你的问题。有两处错误:
在您的 Envoy 配置中,删除 typed_per_filter_config
,因为在这里您说不要将 grpc_http1_reverse_bridge
用于 /
,但您 应该 使用它。
在您的服务器实现中,添加:
res.header("Content-Type", "application/grpc");
就在 res.send(buf)
.
之前
然后,在你的客户端中,如果你写:
console.log('Greeting:', response.getMessage());
你应该看到:Greeting: Hello Bill
.
检索请求属性
另外,如果你想获取请求体,你应该使用服务器中的raw express中间件:
app.use(express.raw({type: "application/grpc"}));
然后:
const root = await protobuf.load(PROTO_PATH);
app.post('/helloworld.greeter/SayHello', (req, res) => {
var message = "Hello";
// if there is a body, transform it to HelloRequest and retrieve name
if (req.body !== undefined && req.body instanceof Buffer && req.body.length != 0) {
const HelloRequest = root.lookupType('helloworld.HelloRequest');
const helloReq = HelloRequest.decode(req.body);
message += " " + helloReq.name;
}
res.header("Content-Type", "application/grpc");
const HelloReply = root.lookupType('helloworld.HelloReply');
res.send(HelloReply.encode({ message: message }).finish());
});
客户端,你可以这样传递名字:
var request = new HelloRequest();
request.setName("World");
通过执行客户端,您现在应该得到:Greeting: Hello World
.
我正在尝试通过 Envoy GRPC 反向桥通过 GRPC 客户端访问 HTTP1.1 rest API。但是当我测试它时,出现以下错误。任何帮助或示例代码片段将不胜感激。谢谢!
Error: 13 INTERNAL: Received RST_STREAM with code 0
at Object.callErrorFromStatus (/Users/meiyappan/grpc-node/grpc/examples/node/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/Users/meiyappan/grpc-node/grpc/examples/node/node_modules/@grpc/grpc-js/build/src/client.js:176:52)
我的 Envoy 代理配置 XML
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: 50051
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
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: grpc
timeout: 50.00s
# per_filter_config disables the filter for this route
typed_per_filter_config:
envoy.filters.http.grpc_http1_reverse_bridge:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_reverse_bridge.v3.FilterConfigPerRoute
disabled: true
http_filters:
- name: envoy.filters.http.grpc_http1_reverse_bridge
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_reverse_bridge.v3.FilterConfig
content_type: application/grpc
withhold_grpc_frames: true
- name: envoy.filters.http.router
clusters:
- name: grpc
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: grpc
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: localhost
port_value: 80
这是原型文件
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
我的 HTTP Rest API,使用 Node-Express
app.post('/helloworld.greeter/SayHello', async (req, res) => {
console.log(req)
const root = await protobuf.load(PROTO_PATH);
const HelloReply = root.lookupType('helloworld.HelloReply');
const buf = HelloReply.encode({ message: 'Hello Bill'}).finish();
res.send(buf)
res.end();
})
节点js中的GRPC客户端代码
function main() {
var target = 'localhost:50051';
var client = new hello_proto.Greeter(target,
grpc.credentials.createInsecure());
var user = 'world';
var metadata = new grpc.Metadata();
metadata.add('Content-Type', 'application/grpc')
client.sayHello({name: user},metadata, function(err, response) {
console.log(err)
console.log('Greeting:', response);
});
}
我已经成功复现了你的问题。有两处错误:
在您的 Envoy 配置中,删除 typed_per_filter_config
,因为在这里您说不要将 grpc_http1_reverse_bridge
用于 /
,但您 应该 使用它。
在您的服务器实现中,添加:
res.header("Content-Type", "application/grpc");
就在 res.send(buf)
.
然后,在你的客户端中,如果你写:
console.log('Greeting:', response.getMessage());
你应该看到:Greeting: Hello Bill
.
检索请求属性
另外,如果你想获取请求体,你应该使用服务器中的raw express中间件:
app.use(express.raw({type: "application/grpc"}));
然后:
const root = await protobuf.load(PROTO_PATH);
app.post('/helloworld.greeter/SayHello', (req, res) => {
var message = "Hello";
// if there is a body, transform it to HelloRequest and retrieve name
if (req.body !== undefined && req.body instanceof Buffer && req.body.length != 0) {
const HelloRequest = root.lookupType('helloworld.HelloRequest');
const helloReq = HelloRequest.decode(req.body);
message += " " + helloReq.name;
}
res.header("Content-Type", "application/grpc");
const HelloReply = root.lookupType('helloworld.HelloReply');
res.send(HelloReply.encode({ message: message }).finish());
});
客户端,你可以这样传递名字:
var request = new HelloRequest();
request.setName("World");
通过执行客户端,您现在应该得到:Greeting: Hello World
.