brpc-http:proto的使用

brpc-http:proto的使用

官方文档:
https://brpc.apache.org/zh/docs/client/access-grpc/
issues:
https://github.com/apache/brpc/issues/1647

他实际上会先解析http的头部的 Content-Type 字段
当Content-Type 中的值为,application/x-protobuf,application/proto,application/grpc 时,他将以protobuf来解析http的包体
而其他情况将会 将其以其他情况解析(默认json)
源码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
if (ct.starts_with("grpc")) {
if (ct.size() == (size_t)4 || ct[4] == ';') {
if (is_grpc_ct) {
*is_grpc_ct = true;
}
// assume that the default content type for grpc is proto.
return HTTP_CONTENT_PROTO;
} else if (ct[4] == '+') {
ct.remove_prefix(5);
if (is_grpc_ct) {
*is_grpc_ct = true;
}
}
// else don't change ct. Note that "grpcfoo" is a valid but non-grpc
// content-type in the sense of format.
}

HttpContentType type = HTTP_CONTENT_OTHERS;
if (ct.starts_with("json")) {
type = HTTP_CONTENT_JSON;
ct.remove_prefix(4);
} else if (ct.starts_with("proto-text")) {
type = HTTP_CONTENT_PROTO_TEXT;
ct.remove_prefix(10);
} else if (ct.starts_with("proto")) {
type = HTTP_CONTENT_PROTO;
ct.remove_prefix(5);
} else if (ct.starts_with("x-protobuf")) {
type = HTTP_CONTENT_PROTO;
ct.remove_prefix(10);
} else {
return HTTP_CONTENT_OTHERS;
}
return (ct.empty() || ct.front() == ';') ? type : HTTP_CONTENT_OTHERS;

http:proto代码示例

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
bool send(const std::string& url,const std::string& data){
brpc::Channel channel;
brpc::ChannelOptions options;
options.protocol = brpc::PROTOCOL_HTTP;//设置协议为http1.*
options.timeout_ms = FLAGS_timeout_ms/*milliseconds*/;
options.max_retry = 3;

if (channel.Init(url, FLAGS_load_balancer.c_str(), &options) != 0) {
LOG(ERROR) << "Fail to initialize channel";
return -1;
}

brpc::Controller cntl;
cntl.http_request().SetHeader("Content-Type","application/x-protobuf");
cntl.http_request().uri() = url;//这个操作只会读取到url后面的path
if (!data.empty()) {
cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
cntl.request_attachment().append(data);
}
channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
if (cntl.Failed()) {
std::cerr << cntl.ErrorText() << std::endl;
return -1;
}
// If -http_verbose is on, brpc already prints the response to stderr.
if (!brpc::FLAGS_http_verbose) {
std::cout << cntl.response_attachment() << std::endl;
}
return 0;
}

h2:proto代码示例

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
bool send(const std::string& url,const std::string& data){
brpc::Channel channel;
brpc::ChannelOptions options;
options.protocol = brpc::PROTOCOL_H2;//设置协议为http2.0
options.timeout_ms = FLAGS_timeout_ms/*milliseconds*/;
options.max_retry = 3;

if (channel.Init(url, FLAGS_load_balancer.c_str(), &options) != 0) {
LOG(ERROR) << "Fail to initialize channel";
return -1;
}

brpc::Controller cntl;
cntl.http_request().SetHeader("Content-Type","application/x-protobuf");
cntl.http_request().uri() = url;//这个操作只会读取到url后面的path
if (!data.empty()) {
cntl.http_request().set_method(brpc::HTTP_METHOD_POST);
cntl.request_attachment().append(data);
}
channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
if (cntl.Failed()) {
std::cerr << cntl.ErrorText() << std::endl;
return -1;
}
// If -http_verbose is on, brpc already prints the response to stderr.
if (!brpc::FLAGS_http_verbose) {
std::cout << cntl.response_attachment() << std::endl;
}
return 0;
}