From 90c28fcb3bda3964ee5d8f55227c09ba843408a4 Mon Sep 17 00:00:00 2001 From: lioncfliu Date: Wed, 18 Oct 2023 16:23:51 +0800 Subject: [PATCH] docs: update content of http/grpc's development guide --- docs/en/grpc_protocol_client.md | 9 +++----- docs/en/http_protocol_client.md | 16 +++++++------- docs/en/http_protocol_service.md | 7 +++--- .../http_protocol_upload_download_client.md | 22 +++++++++---------- .../http_protocol_upload_download_service.md | 2 -- docs/zh/grpc_protocol_client.md | 7 ++---- docs/zh/http_protocol_client.md | 6 ++--- docs/zh/http_protocol_service.md | 8 +++---- .../http_protocol_upload_download_client.md | 15 ++++++------- .../http_protocol_upload_download_service.md | 8 +++---- 10 files changed, 44 insertions(+), 56 deletions(-) diff --git a/docs/en/grpc_protocol_client.md b/docs/en/grpc_protocol_client.md index 21b348ec..77303d2d 100644 --- a/docs/en/grpc_protocol_client.md +++ b/docs/en/grpc_protocol_client.md @@ -27,7 +27,7 @@ accessing a tRPC service: ## Call process -* Get the `XxServiceProxyPtr` object `proxy`: use the `GetClient()->GetProxy(...)`. +* Get the `XxServiceProxyPtr` object `proxy`: use the `GetTrpcClient()->GetProxy(...)`. ```cpp auto proxy = ::trpc::GetTrpcClient()->GetProxy<::trpc::test::helloworld::GreeterServiceProxy>("xx_service_name") @@ -84,9 +84,8 @@ Use the synchronous or asynchronous interface corresponding to the selected runt ::trpc::test::helloworld::HelloRequest req; req.set_msg("future"); bool succ = true; - ::trpc::Latch latch(1); - proxy->AsyncSayHello(client_ctx, req) - .Then([&latch, &succ](::trpc::Future<::trpc::test::helloworld::HelloReply>&& fut) { + auto fut = proxy->AsyncSayHello(client_ctx, req) + .Then([&succ](::trpc::Future<::trpc::test::helloworld::HelloReply>&& fut) { if (fut.IsReady()) { auto rsp = fut.GetValue0(); std::cout << "get rsp msg: " << rsp.msg() << std::endl; @@ -95,10 +94,8 @@ Use the synchronous or asynchronous interface corresponding to the selected runt succ = false; std::cerr << "get rpc error: " << exception.what() << std::endl; } - latch.count_down(); return ::trpc::MakeReadyFuture<>(); }); - latch.wait(); return succ ? 0 : -1; } ``` diff --git a/docs/en/http_protocol_client.md b/docs/en/http_protocol_client.md index 62b08376..220bab72 100644 --- a/docs/en/http_protocol_client.md +++ b/docs/en/http_protocol_client.md @@ -62,7 +62,7 @@ Next, let's take a look at the steps to access an HTTP service. ### Basic steps to access an HTTP service -1. Get the `HttpServiceProxyPtr` object `proxy`: use `GetClient()->GetProxy(...)`. +1. Get the `HttpServiceProxyPtr` object `proxy`: use `GetTrpcClient()->GetProxy(...)`. 2. Create the `ClientContextPtr` object `context`: use `MakeClientContext(proxy)`. 3. Call the expected API to access and check the return code, such as `GetString` or `PostString` (we can choose to use synchronous or asynchronous interfaces based on your business scenario). @@ -84,7 +84,7 @@ Example: [http_client.cc](../../examples/features/http/client/client.cc) auto proxy = ::trpc::GetTrpcClient()->GetProxy<::trpc::http::HttpServiceProxy>(servie_name, option); ``` - > There are two ways to create an `HttpServiceProxyPtr`: + > There are three ways to create an `HttpServiceProxyPtr`: > > -1- Set the `ServiceProxyOption` object. > @@ -142,11 +142,11 @@ Note: The Get2 below is just an interface name and does not use the HTTP2 protoc | Class/Object | Interface Name | Functionality | Parameters | Return Value | Remarks | |------------------|----------------------------------------------------------------------------------------------------------|------------------------------------------------------------|------------------------------------------------------------------------------------------|--------------------------------|------------------------| -| HttpServiceProxy | Status Get(const ClientContextPtr& context, const std::string& url, rapidjson::Document* json) | Obtains a JSON response message using GET | client context
url resource location
json stores the response message | Status | Synchronous interface | -| HttpServiceProxy | Status GetString(const ClientContextPtr& context, const std::string& url, std::string* rspStr) | Obtains a string response message using GET | client context
url resource location
rspStr stores the response message | Status | Synchronous interface | -| HttpServiceProxy | Status Get2(const ClientContextPtr& context, const std::string& url, HttpResponse* rsp) | Obtains an HTTP response using GET | client context
url resource location
rsp stores the HTTP response | Status | Synchronous interface | -| HttpServiceProxy | Future<rapidjson::Document> AsyncGet(const ClientContextPtr& context, const std::string& url) | Obtains a JSON response message using GET asynchronously | client context
url resource location | Future<rapidjson::Document> | Asynchronous interface | -| HttpServiceProxy | Future<std::string> AsyncGetString(const ClientContextPtr& context, const std::string& url) | Obtains a string response message using GET asynchronously | client context
url resource location | Future<std::string> | Asynchronous interface | +| HttpServiceProxy | Status Get(const ClientContextPtr& context, const std::string& url, rapidjson::Document* json) | Obtains a JSON response message using GET | context client context
url resource location
json stores the response message | Status | Synchronous interface | +| HttpServiceProxy | Status GetString(const ClientContextPtr& context, const std::string& url, std::string* rspStr) | Obtains a string response message using GET | context client context
url resource location
rspStr stores the response message | Status | Synchronous interface | +| HttpServiceProxy | Status Get2(const ClientContextPtr& context, const std::string& url, HttpResponse* rsp) | Obtains an HTTP response using GET | context client context
url resource location
rsp stores the HTTP response | Status | Synchronous interface | +| HttpServiceProxy | Future<rapidjson::Document> AsyncGet(const ClientContextPtr& context, const std::string& url) | Obtains a JSON response message using GET asynchronously | context client context
url resource location | Future<rapidjson::Document> | Asynchronous interface | +| HttpServiceProxy | Future<std::string> AsyncGetString(const ClientContextPtr& context, const std::string& url) | Obtains a string response message using GET asynchronously | context client context
url resource location | Future<std::string> | Asynchronous interface | | HttpServiceProxy | Future<HttpResponse> AsyncGet2(const ClientContextPtr& context, const std::string& url) | Obtains an HTTP response using GET asynchronously | context client context
url resource location | Future<HttpResponse> | Asynchronous interface | Translation: @@ -507,7 +507,7 @@ be transmitted correctly. If you only need to get the status code of 2xx, you can use the interface that returns `HttpResponse*`. If you need to get the status code of non-2xx, please override the `CheckHttpResponse(...)` method. -## Does the `target` configuration item in the configuration file support the `domain:Port` format? +## Does the `target` configuration item in the configuration file support the `domain:port` format? Yes, it is supported. You need to: diff --git a/docs/en/http_protocol_service.md b/docs/en/http_protocol_service.md index 1335cf7c..81ca8b3d 100644 --- a/docs/en/http_protocol_service.md +++ b/docs/en/http_protocol_service.md @@ -3,8 +3,7 @@ # Overview Currently, tRPC-Cpp supports two types of HTTP services: HTTP Standard Service and HTTP RPC Service (these names are -used to -differentiate between the two services). +used to differentiate between the two services). > HTTP standard service: It is a regular HTTP service that does not use proto files to define the service interface. > Users need to write their own code to define the service interface and register URL routes. @@ -160,7 +159,7 @@ Basic steps: After the application is started, we can access it through the following URLs. ```bash - # GET /foo HTTP1.1 + # GET /foo HTTP/1.1 # e.g: curl http://$ip:$port/foo $ hello world! ``` @@ -474,7 +473,7 @@ class ApiUserHandler : public ::trpc::http::HttpHandler { #### Register `HttpController` -Using the `HTTP_HANDLER` macro, users can easily register `Controller`-like interfaces to the route: +Using the `TPRC_HTTP_HANDLER` macro, users can easily register `Controller`-like interfaces to the route: Note: `Controller` does not inherit the `HttpHandler` class, but only has the same interface signature. diff --git a/docs/en/http_protocol_upload_download_client.md b/docs/en/http_protocol_upload_download_client.md index e5bee88a..5c390944 100644 --- a/docs/en/http_protocol_upload_download_client.md +++ b/docs/en/http_protocol_upload_download_client.md @@ -22,7 +22,7 @@ transfer `Transfer-Encoding: chunked`. *Note: The synchronous streaming interface needs to run in the `fiber` coroutine environment.* -## Programming interfaces synchronous streaming +## Programming interfaces about synchronous streaming ### Client stream reader writer by synchronous @@ -91,7 +91,7 @@ Taking the Read interface as an example, tRPC provides two types of specific int Example: [upload_client.cc](../../examples/features/http_upload_download/client/upload_client.cc) The basic data uploading process involves the following steps: setting the length form/chunked form, sending the request -header, reading the response header, writing data, and completing the write. +header, writing data, completing the write, and reading the response header. * **Setting the length form/chunked form** @@ -101,10 +101,6 @@ header, reading the response header, writing data, and completing the write. The client does not need to send the request header. tRPC does not provide this method. When the stream is obtained, tRPC-Cpp has already sent the request header. -* **Reading the response header** - - If the ReadHeaders interface is executed successfully, it means that the response header from the server has been received. The HTTP status code (200, 404, etc.) can be obtained from the http_code parameter. These constants are also defined in tRPC, such as ResponseStatus::kOk. The response header can be obtained from the http_header parameter. - * **Writing data** The user can continuously send data fragments to the server through the Write interface. If the user is using chunked form, there is no need to encode the transmitted data with chunked. tRPC will handle it automatically. If the user is using length form, the Write interface will report the kStreamStatusClientWriteContentLengthError error if the data sent by the user exceeds the set length. @@ -112,6 +108,10 @@ header, reading the response header, writing data, and completing the write. * **Completing the write** The user informs the reader/writer that all data has been sent through the WriteDone interface. If the user is using chunked form, the framework will send the chunked end flag to the server. If the user is using length form, the framework will check whether the length of the data sent by the user is consistent with the set length. If they are inconsistent, the kStreamStatusClientWriteContentLengthError error will be reported. Once the WriteDone interface is called, the user should not try to use the Write interface again. + +* **Reading the response header** + + If the ReadHeaders interface is executed successfully, it means that the response header from the server has been received. The HTTP status code (200, 404, etc.) can be obtained from the http_code parameter. These constants are also defined in tRPC, such as ResponseStatus::kOk. The response header can be obtained from the http_header parameter. * Example code @@ -293,10 +293,10 @@ Call `GetAsyncStreamReaderWriter` of `HttpStreamProxy` to obtain the stream read | Future<NoncontiguousBuffer> ReadAtMost(uint64_t len, int timeout = max) | Can be called in both length mode and chunk mode, and gets up to len length of data.
If the size of the data received from the network is smaller than len, return data of size.
If the size of the data received from the network is larger than len, return data of length len.
If the buffer is empty, it means EOF.
Scenario 1: Used in memory-limited situations, limiting the maximum read length each time.
Scenario 2: In relay mode, it can obtain data in a timely manner and send it downstream. | len in bytes, timeout (ms) | | Future<NoncontiguousBuffer> ReadExactly(uint64_t len, int timeout = max) | Can be called in both length mode and chunk mode, and gets fixed length data of len. If EOF is read, it returns as much data as there is in the network.
If the size of the buffer read is smaller than len, it means EOF.
Special scenario 1: The requested data is compressed in fixed size and needs to be read in fixed size for decompression. | len in bytes, timeout (ms) | - * Client-side interfaces for writing complete requests and reading complete responses: +* Client-side interfaces for writing complete requests and reading complete responses: - | Interface Signature | Function | Parameters | - |---------------------------------------------------------------------------------------------------------|---------------------------------------------|----------------------------------------------------| - | Future<> WriteFullRequest(HttpClientAsyncStreamWriterPtr rw, HttpRequest&& req) | Writes the complete request to the stream | rw: Client-side stream reader/writer, timeout (ms) | - | Future<HttpResponsePtr> ReadFullResponse(HttpClientAsyncStreamReaderWriterPtr rw, int timeout = max) | Reads the complete response from the stream | rw: Client-side stream reader/writer, timeout (ms) | + | Interface Signature | Function | Parameters | + |---------------------------------------------------------------------------------------------------------|---------------------------------------------|----------------------------------------------------| + | Future<> WriteFullRequest(HttpClientAsyncStreamWriterPtr rw, HttpRequest&& req) | Writes the complete request to the stream | rw: Client-side stream reader/writer, timeout (ms) | + | Future<HttpResponsePtr> ReadFullResponse(HttpClientAsyncStreamReaderWriterPtr rw, int timeout = max) | Reads the complete response from the stream | rw: Client-side stream reader/writer, timeout (ms) | \ No newline at end of file diff --git a/docs/en/http_protocol_upload_download_service.md b/docs/en/http_protocol_upload_download_service.md index 5a477320..aa789826 100644 --- a/docs/en/http_protocol_upload_download_service.md +++ b/docs/en/http_protocol_upload_download_service.md @@ -2,8 +2,6 @@ # Overview -Topic: How to develop an HTTP file upload-download service based on tRPC-Cpp. - In HTTP services, there are scenarios where large files need to be read or sent. Reading the entire file into memory is inefficient and puts a lot of pressure on the memory, making it difficult to upload large files. tRPC-Cpp provides a set of HTTP streaming read and write data chunking interfaces, which can receive and send large files in chunks. diff --git a/docs/zh/grpc_protocol_client.md b/docs/zh/grpc_protocol_client.md index f179bed4..f2b4dac9 100644 --- a/docs/zh/grpc_protocol_client.md +++ b/docs/zh/grpc_protocol_client.md @@ -83,9 +83,8 @@ Unary Service:可以理解为一问一答服务,是为了区别流式服务 ::trpc::test::helloworld::HelloRequest req; req.set_msg("future"); bool succ = true; - ::trpc::Latch latch(1); - proxy->AsyncSayHello(client_ctx, req) - .Then([&latch, &succ](::trpc::Future<::trpc::test::helloworld::HelloReply>&& fut) { + auto fut = proxy->AsyncSayHello(client_ctx, req) + .Then([&succ](::trpc::Future<::trpc::test::helloworld::HelloReply>&& fut) { if (fut.IsReady()) { auto rsp = fut.GetValue0(); std::cout << "get rsp msg: " << rsp.msg() << std::endl; @@ -94,10 +93,8 @@ Unary Service:可以理解为一问一答服务,是为了区别流式服务 succ = false; std::cerr << "get rpc error: " << exception.what() << std::endl; } - latch.count_down(); return ::trpc::MakeReadyFuture<>(); }); - latch.wait(); return succ ? 0 : -1; } ``` diff --git a/docs/zh/http_protocol_client.md b/docs/zh/http_protocol_client.md index 8d1b3e12..ee0f9f80 100644 --- a/docs/zh/http_protocol_client.md +++ b/docs/zh/http_protocol_client.md @@ -7,7 +7,7 @@ tRPC-Cpp 默认支持 tRPC 协议,同时也支持 HTTP 协议。 RPC 服务。 这可以使一个 RPC 服务同时支持 tRPC 和 HTTP 协议,当前支持通过 HTTP 客户端访问 tRPC 服务。 -本文介绍如何基于 tRPC-Cpp (下面简称 tRPC)访问 HTTP 服务,开发可以了解到如下内容: +本文介绍如何基于 tRPC-Cpp (下面简称 tRPC)访问 HTTP 服务,开发者可以了解到如下内容: * 访问 HTTP 标准服务 * 快速上手:使用一个 HTTP Client 访问 HTTP 服务。 @@ -228,7 +228,7 @@ tRPC-Cpp 侧暂未实现 HTTP CONNECT 相关逻辑。 tRPC 当前支持 `HTTP/1.1` 和 `HTTP 1.0`, 默认使用 `HTTP/1.1`。暂未支持 `HTTP/2.0`,在准备中。 -如果使用使用 1.0 ,可以使用如下方法设置。 +如果使用 1.0 ,可以使用如下方法设置。 ```cpp request.SetVersion("1.0"); @@ -481,7 +481,7 @@ curl -H 'trpc-trans-info: {"k1": "v1", "k2": "v2" }' -T xx.seriealized.pb $url 如果只需要获取 2xx 的状态码,可直接使用返回为 `HttpResponse*` 的接口。 如果需要获取非 2xx 的状态码,请 override `CheckHttpResponse(...)` 方法。 -## 配置文件中的 `target` 配置项是否支持 `域名:Port` 格式? +## 配置文件中的 `target` 配置项是否支持 `domain:port` 格式? 支持的,需要: diff --git a/docs/zh/http_protocol_service.md b/docs/zh/http_protocol_service.md index a466fab0..187a8373 100644 --- a/docs/zh/http_protocol_service.md +++ b/docs/zh/http_protocol_service.md @@ -10,7 +10,7 @@ 本文介绍如何基于 tRPC-Cpp (下面简称 tRPC)开发 [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) 服务,开发者可以了解到如下内容: -* 如何开发 HTTP 标准服务。 +* 如何开发 HTTP 标准服务 * 快速上手:快速搭建一个 HTTP 服务。 * 功能特性一览:RESTful;HTTPS。 * 基础用法:获取请求、响应常用接口;配置请求路由规则。 @@ -110,7 +110,7 @@ class FooHandler : public ::trpc::http::HttpHandler { 接口签名大致如下: ```cpp -class trpc::http::HttpHandler { +class HttpHandler { public: virtual ::trpc::Status Head(const ::trpc::ServerContextPtr& ctx, const ::trpc::http::RequestPtr& req, ::trpc::http::Response* rsp); virtual ::trpc::Status Get(const ::trpc::ServerContextPtr& ctx, const ::trpc::http::RequestPtr& req, ::trpc::http::Response* rsp); @@ -155,7 +155,7 @@ class HttpdServer : public ::trpc::TrpcApp { 应用程序启动后,可以通过如下如下 URL 访问。 ```bash -# GET /foo HTTP1.1 +# GET /foo HTTP/1.1 # e.g: curl http://$ip:$port/foo $ hello world! ``` @@ -523,7 +523,7 @@ HTTPS 是 HTTP over SSL 的简称,可以通过如下方式开启 SSL。 | ciphers | 加密套件 | 不限 | null | `required` | 在启用 SSL 时,如果不正确设置,服务会启动失败 | | enable | 是否启用SSL | {true, false} | false | optional | 建议在配置项明确指定,明确意图 | | mutual_auth | 是否启用双向认证 | {true, false} | false | optional | - | - | ca_cert_path | CA证书路径 | 不限,xx/path/to/ca.pem | null | optional | 双向认证是开启有效 | + | ca_cert_path | CA证书路径 | 不限,xx/path/to/ca.pem | null | optional | 双向认证时开启有效 | | protocols | SSL协议版本 | {SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2} | TLSv1.1 + TLSv1.2 | optional | - | 举个例子: diff --git a/docs/zh/http_protocol_upload_download_client.md b/docs/zh/http_protocol_upload_download_client.md index 4bbff774..69359a0d 100644 --- a/docs/zh/http_protocol_upload_download_client.md +++ b/docs/zh/http_protocol_upload_download_client.md @@ -5,13 +5,13 @@ tRPC-Cpp 提供一套 HTTP 流式读取、写入数据分片的接口,可以分片接收、发送大文件。 本文介绍如何基于 tRPC-Cpp (下面简称 tRPC)访问 HTTP 文件上传-下载服务,开发者可以了解到如下内容: -* 如何使用同步流式接口访问文件上传-下载服务。 +* 如何使用同步流式接口访问文件上传-下载服务 * 编程接口。 * 访问上传-下载服务。 -* 如何使用异步流式接口访问文件上传-下载服务。 +* 如何使用异步流式接口访问文件上传-下载服务 * 编程接口。 * 代码示例。 -* FAQ。 +* FAQ # 如何使用同步流式接口访问文件上传-下载服务 @@ -81,7 +81,7 @@ tRPC-Cpp 提供一套 HTTP 流式读取、写入数据分片的接口,可以 示例: [upload_client.cc](../../examples/features/http_upload_download/client/upload_client.cc) -基本的数据上传过程需要经过如下几个步骤:设置长度形式/chunked 形式,发送请求头,读取响应头,写数据,完成写。 +基本的数据上传过程需要经过如下几个步骤:设置长度形式/chunked 形式,发送请求头,写数据,完成写,读取响应头。 * **设置长度形式/chunked 形式** @@ -91,10 +91,6 @@ tRPC-Cpp 提供一套 HTTP 流式读取、写入数据分片的接口,可以 客户端不需要用户进行发送请求头的动作,tRPC 也没有提供该方法。用户在获得 stream 时 tRPC 已经将请求头发送出去。 -* **读取响应头** - - 如果 ReadHeaders 接口执行成功,说明正常接收到服务端的响应头,从 http_code 参数能拿到 HTTP 状态码(200,404等),这些常量在 tRPC-Cpp 中也有定义,比如下面例子中的 ResponseStatus::kOk。从 http_header 参数能获取响应头。 - * **写数据** 通过 Write 接口,用户可以不断地向服务端发送数据分片。如果用户使用的是 chunked 形式,用户也不需要对传输数据做 chunked 编码,tRPC 会自动处理。如果用户使用的是长度形式,一旦用户发送的数据超过了设置的长度,Write 接口会报 kStreamStatusClientWriteContentLengthError 错误。 @@ -102,6 +98,9 @@ tRPC-Cpp 提供一套 HTTP 流式读取、写入数据分片的接口,可以 * **完成写** 通过 WriteDone 接口,用户告知读写器数据全部发送完毕。如果用户使用的是 chunked 形式,框架会向服务端发送chunked结束标志;如果用户使用的是长度形式,框架会检查用户已发送的数据长度和设置的长度是否一致,不一致会报 kStreamStatusClientWriteContentLengthError 错误。一旦调用 WriteDone 接口后,用户不应该再尝试使用 Write 接口。 +* **读取响应头** + + 如果 ReadHeaders 接口执行成功,说明正常接收到服务端的响应头,从 http_code 参数能拿到 HTTP 状态码(200,404等),这些常量在 tRPC-Cpp 中也有定义,比如下面例子中的 ResponseStatus::kOk。从 http_header 参数能获取响应头。 * 简单的示例代码: diff --git a/docs/zh/http_protocol_upload_download_service.md b/docs/zh/http_protocol_upload_download_service.md index 06a28699..1b56d8a3 100644 --- a/docs/zh/http_protocol_upload_download_service.md +++ b/docs/zh/http_protocol_upload_download_service.md @@ -2,8 +2,6 @@ # 前言 -主题:如何基于 tRPC-Cpp 开发 HTTP 文件上传、下载服务。 - 在 HTTP 服务中,部分场景需要读取或者发送大文件的场景,将文件完整读入内存压力较大且效率较低,对于大文件的上传可行性不高。 tRPC-Cpp 提供一套 HTTP 流式读取、写入数据分片的接口,可以分片接收、发送大文件。 @@ -15,15 +13,15 @@ tRPC-Cpp 提供一套 HTTP 流式读取、写入数据分片的接口,可以 本文介绍如何基于 tRPC-Cpp (下面简称 tRPC)发 HTTP 文件上传-下载服务,开发者可以了解到如下内容: -* 如何使用同步流式接口实现文件上传-下载。 +* 如何使用同步流式接口实现文件上传-下载 * 运行流程。 * 编程接口。 * 实现上传-下载服务。 -* 如何使用异步流式接口实现文件上传-下载。 +* 如何使用异步流式接口实现文件上传-下载 * 运行流程。 * 编程接口。 * 代码示例。 -* FAQ。 +* FAQ # 如何使用同步流式接口实现文件上传-下载