Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/qbk/01_intro/_intro_zh_Hans.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Beast 授权用户基于 HTTP/1 和 WebSocket 构建自己的库、客户端及
[section 要求]

[important
该库面向熟悉 Asio 的程序员。用户
该库面向熟悉 __Asio__的程序员。用户
wish to use asynchronous interfaces should already know how to
create concurrent network programs using callbacks or coroutines.
Comment on lines +39 to 41

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Complete this zh_Hans translation block.

Line 40-Line 41 are still in English inside the localized [important] note, so this section reads as a partial translation.

Suggested fix
 [important
-    该库面向熟悉 __Asio__的程序员。用户
-    wish to use asynchronous interfaces should already know how to
-    create concurrent network programs using callbacks or coroutines.
+    该库面向熟悉 __Asio__ 的程序员。希望使用异步接口的用户,
+    应当已经了解如何使用回调或协程来编写并发网络程序。
 ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
该库面向熟悉 __Asio__的程序员。用户
wish to use asynchronous interfaces should already know how to
create concurrent network programs using callbacks or coroutines.
[important
该库面向熟悉 __Asio__ 的程序员。希望使用异步接口的用户,
应当已经了解如何使用回调或协程来编写并发网络程序。
]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@doc/qbk/01_intro/_intro_zh_Hans.qbk` around lines 39 - 41, The zh_Hans
translation block is incomplete because the localized [important] note still
contains English text. Update the mixed-language sentence in this intro section
so the entire paragraph is fully translated into Simplified Chinese, keeping the
meaning aligned with the existing Asio-focused wording and the guidance about
asynchronous interfaces, callbacks, and coroutines.

]
Expand Down
85 changes: 15 additions & 70 deletions doc/qbk/03_core/1_refresher_zh_Hans.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -130,108 +130,53 @@ __AsyncReadStream__ 与 __AsyncWriteStream__ 概念用于定义 [异步流] 的

[heading 通用模型]

Because completion handlers cause an inversion of the flow of control,
sometimes other methods of attaching a continuation are desired. Networking
provides the
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf ['Universal Model for Asynchronous Operations]],
providing a customizable means for transforming the signature of the initiating
function to use other types of objects and methods in place of a completion
handler callback. For example to call to write a string to a socket
asynchronously, using a `std::future` to receive the number of bytes transferred
thus looks like this:
由于完成处理器会导致控制流反转,有时需要其他方式来附加延续。网络库提供 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf [异步操作通用模型]],该模型提供一种可定制的方法,用于改变发起函数的签名,以便使用其他类型的对象和方法来替代完成处理器回调。例如,使用 `std::future` 接收传输字节数来异步向套接字写入字符串的调用方式如下:

[code_core_1_refresher_4s]

This functionality is enabled by passing the variable
[@boost:/doc/html/boost_asio/reference/use_future.html `net::use_future`]
(of type
[@boost:/doc/html/boost_asio/reference/use_future_t.html `net::use_future_t<>`])
in place of the completion handler. The same `async_write` function overload
can work with a
[@https://en.wikipedia.org/wiki/Fiber_(computer_science) ['fiber]]
launched with
[@boost:/doc/html/boost_asio/reference/spawn/overload1.html `asio::spawn`]:
此功能通过将变量 [@boost:/doc/html/boost_asio/reference/use_future.html `net::use_future`](类型为 [@boost:/doc/html/boost_asio/reference/use_future_t.html `net::use_future_t<>`])传递给完成处理器位置来实现。同一个 `async_write` 函数重载还可以与通过 [@boost:/doc/html/boost_asio/reference/spawn/overload1.html `asio::spawn`] 启动的 [@https://en.wikipedia.org/wiki/Fiber_(computer_science) [纤程]] 配合使用:

[code_core_1_refresher_5s]

In both of these cases, an object with a specific type is used in place of
the completion handler, and the return value of the initiating function
is transformed from `void` to `std::future<std::size_t>` or `std::size_t`.
The handler is sometimes called a
__CompletionToken__
when used in this context. The return type transformation is supported by
customization points in the initiating function signature. Here is the
signature for
[@boost:/doc/html/boost_asio/reference/async_write/overload1.html `net::async_write`]:
在这两种情况下,都使用具有特定类型的对象来替代完成处理器,且发起函数的返回值也从 `void` 转变为 `std::future<std::size_t>` 或 `std::size_t`。在这种上下文中,该处理器有时被称为 __CompletionToken__。发起函数签名中的定制点支持这种返回值类型的转换。以下是 [@boost:/doc/html/boost_asio/reference/async_write/overload1.html `net::async_write`] 的签名:

Note that a `spawn` function itself has a completion signature,
but we're ignoring it's result in the example by using `asio::detached`.
需要注意的是,`spawn` 函数本身也带有完成签名,但示例中通过使用 `asio::detached` 忽略了它的结果。

[code_core_1_refresher_9]

The type of the function's return value is determined by the
[@boost:/doc/html/boost_asio/reference/async_result.html `net::async_result`]
customization point, which comes with specializations for common library
types such as `std::future` and may also be specialized for user-defined
types. The body of the initiating function calls the
[@boost:/doc/html/boost_asio/reference/async_initiate.html `net::async_initiate`]
helper to capture the arguments and forward them to the specialization of
`async_result`. An additional "initiation function" object is provided which
`async_result` may use to immediately launch the operation, or defer the launch
of the operation until some point in the future (this is called "lazy
execution"). The initiation function object receives the internal completion
handler which matches the signature expected by the initiating function:
函数返回值类型由 [@boost:/doc/html/boost_asio/reference/async_result.html `net::async_result`] 定制点决定。该定制点为 `std::future` 等常用库类型提供特化版本,同时也支持用户自定义类型的特化。发起函数的函数体通过调用 [@boost:/doc/html/boost_asio/reference/async_initiate.html `net::async_initiate`] 辅助函数来捕获参数并将其转发给 `async_result` 的特化版本。此外,还提供一个额外的“发起函数”对象,`async_result` 可利用该对象立即启动操作,或将操作启动延迟到未来某个时刻(即“延迟执行”)。该发起函数对象接收一个内部完成处理器,其签名与发起函数所期望的签名相匹配。

[code_core_1_refresher_10]

This transformed, internal handler is responsible for the finalizing step that
delivers the result of the operation to the caller. For example, when using
`net::use_future` the internal handler will deliver the result by calling
[@https://en.cppreference.com/w/cpp/thread/promise/set_value `std::promise::set_value`]
on the promise object returned by the initiating function.
这个经过转换的内部处理器负责执行最终步骤,将操作结果传递给调用方。例如,当使用 `net::use_future` 时,内部处理器会通过调用发起函数返回的 promise 对象上的 [@https://en.cppreference.com/w/cpp/thread/promise/set_value `std::promise::set_value`] 来传递结果。
Comment thread
coderabbitai[bot] marked this conversation as resolved.

[/-----------------------------------------------------------------------------]

[heading Using Networking]
[heading 使用网络库]

Most library stream algorithms require a __socket__, __ssl_stream__, or
other __Stream__ object that has already established communication with
a remote peer. This example is provided as a reminder of how to work with
sockets:
大多数库中的流算法都需要一个已与远程对等端建立通信的 __socket__、__ssl_stream__ 或其他 __Stream__ 对象。以下示例用于回顾如何使用套接字:

[snippet_core_2]

Throughout this documentation identifiers with the following names have
special meaning:
在本文档中,以下名称的标识符具有特殊含义:

[table Global Variables
[[Name][Description]]
[table 全局变量
[[名称][描述]]
[[
[@boost:/doc/html/boost_asio/reference/io_context.html [*`ioc`]]
][
A variable of type __io_context__ which is running on one separate thread,
and upon which an __executor_work_guard__ object has been constructed.
][一个类型为 __io_context__ 的变量,该变量在单独线程上运行,且已为其构造一个 __executor_work_guard__ 对象。
]]
[[
[@boost:/doc/html/boost_asio/reference/ip__tcp/socket.html [*`sock`]]
][
A variable of type
[@boost:/doc/html/boost_asio/reference/ip__tcp/socket.html `tcp::socket`]
which has already been connected to a remote host.
][一个类型为 [@boost:/doc/html/boost_asio/reference/ip__tcp/socket.html `tcp::socket`] 的变量,该变量已连接到远程主机。
]]
[[
[@boost:/doc/html/boost_asio/reference/ssl__stream.html [*`ssl_sock`]]
][
A variable of type
[@boost:/doc/html/boost_asio/reference/ssl__stream.html `net::ssl::stream<tcp::socket>`]
which is already connected and has handshaked with a remote host.
][一个类型为 [@boost:/doc/html/boost_asio/reference/ssl__stream.html `net::ssl::stream<tcp::socket>`] 的变量,该变量已与远程主机建立连接并完成握手。
]]
[[
[link beast.ref.boost__beast__websocket__stream [*`ws`]]
][
A variable of type
[link beast.ref.boost__beast__websocket__stream `websocket::stream<tcp::socket>`]
which is already connected with a remote host.
][一个类型为 [link beast.ref.boost__beast__websocket__stream `websocket::stream<tcp::socket>`] 的变量,该变量已与远程主机建立连接。
]]
]

Expand Down
86 changes: 28 additions & 58 deletions doc/qbk/06_websocket/04_messages_zh_Hans.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -9,93 +9,65 @@

[/-----------------------------------------------------------------------------]

[section:messages Messages]

Once a websocket session is established, messages can be sent unsolicited by
either peer at any time. A message is made up of one or more ['messages frames].
Each frame is prefixed with the size of the payload in bytes, followed by the
data. A frame also contains a flag (called 'fin') indicating whether or not it
is the last frame of the message. When a message is made up from only one frame,
it is possible to know immediately what the size of the message will be.
Otherwise, the total size of the message can only be determined once
the last frame is received.

The boundaries between frames of a multi-frame message are not not considered
part of the message. Intermediaries such as proxies which forward the websocket
traffic are free to "reframe" (split frames and combine them) the message in
arbitrary ways. These intermediaries include Beast, which can reframe messages
automatically in some cases depending on the options set on the stream.
[section:messages 消息]

WebSocket 会话建立后,任何一端都可以随时主动发送消息。每条消息由一个或多个消息帧组成。每个帧的前部是有效载荷的字节长度,随后是数据内容。帧还包含一个名为 fin 的标志,用于标识该帧是否为消息的最后一帧。如果消息只由一个帧构成,则可以立即获知消息大小。否则,消息的总大小只能在接收到最后一帧时才能确定。

多帧消息中,各帧的边界不属于消息内容的一部分。像代理这类转发 WebSocket 流量的中间节点,可以自由地对消息进行“重帧处理”(即拆分或合并帧)。Beast 也属于这类中间节点,它会根据流上配置的选项,在某些场景下自动重帧消息。

[caution
An algorithm should never depend on the way that incoming or outgoing
算法不应依赖入站或出站消息的帧结构方式。
messages are split up into frames.
]
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Messages can be either text or binary. A message sent as text must contain
consist of valid utf8, while a message sent as binary may contain arbitrary
data. In addition to message frames, websocket provides ['control frames]
in the form of ping, pong, and close messages which have a small upper limit
on their payload size. Depending on how a message is framed, control frames
may have more opportunities to be sent in-between.
消息可以是文本类型或二进制类型。以文本形式发送的消息必须包含有效的 UTF-8 编码,而以二进制形式发送的消息则可以包含任意数据。除了消息帧之外,WebSocket 还提供控制帧,包括 ping、pong 和 close 消息,这些控制帧的有效载荷大小有较小的上限限制。根据消息的帧结构方式,控制帧可能有更多的机会在传输间隙发送。

[heading Sending]
[heading 发送]

These stream members are used to write websocket messages:
以下流成员函数用于写入 WebSocket 消息:

[table WebSocket Stream Write Operations
[[Function][Description]]
[table WebSocket 流写入操作
[[函数][描述]]
[
[
[link beast.ref.boost__beast__websocket__stream.write.overload2 `write`],
[link beast.ref.boost__beast__websocket__stream.async_write `async_write`]
][
Send a buffer sequence as a complete message.
]
][将缓冲区序列作为完整消息发送。]
][
[
[link beast.ref.boost__beast__websocket__stream.write_some.overload2 `write_some`],
[link beast.ref.boost__beast__websocket__stream.async_write_some `async_write_some`]
][
Send a buffer sequence as part of a message.
]
][将缓冲区序列作为消息的一部分发送。]
]]

This example shows how to send a buffer sequence as a complete message.
本示例展示如何将缓冲区序列作为完整消息发送。

[code_websocket_4_1]

The same message could be sent in two or more frames thusly.
同一消息也可以通过两个或多个帧来发送,如下所示:

[heading Receiving]
[heading 接受]

[table WebSocket Stream Read Operations
[[Function][Description]]
[table WebSocket 流读取操作
[[函数][描述]]
[
[
[link beast.ref.boost__beast__websocket__stream.read.overload2 `read`],
[link beast.ref.boost__beast__websocket__stream.async_read `async_read`]
][
Read a complete message into a __DynamicBuffer__.
]
][将完整消息读入 __DynamicBuffer__。]
][
[
[link beast.ref.boost__beast__websocket__stream.read_some.overload2 `read_some`],
[link beast.ref.boost__beast__websocket__stream.async_read_some.overload1 `async_read_some`]
][
Read part of a message into a __DynamicBuffer__.
]
][将消息的部分内容读入 __DynamicBuffer__。]
][
[
[link beast.ref.boost__beast__websocket__stream.read_some.overload4 `read_some`],
[link beast.ref.boost__beast__websocket__stream.async_read_some.overload2 `async_read_some`]
][
Read part of a message into a __MutableBufferSequence__.
]
][将消息的部分内容读入 MutableBufferSequence。]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore QuickBook macro syntax for MutableBufferSequence.

Line 67 uses bare MutableBufferSequence without the required __ delimiters. The English original uses __MutableBufferSequence__, which QuickBook expands to a link/type reference. Removing the underscores breaks macro expansion and may render incorrect output.

-    ][将消息的部分内容读入 MutableBufferSequence。]
+    ][将消息的部分内容读入 __MutableBufferSequence__。]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
][将消息的部分内容读入 MutableBufferSequence。]
][将消息的部分内容读入 __MutableBufferSequence__。]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@doc/qbk/06_websocket/04_messages_zh_Hans.qbk` at line 67, Restore the
QuickBook macro syntax for MutableBufferSequence in the translated message text
by using the same __...__ delimiters as the English source. Update the content
in the messages document so the reference to MutableBufferSequence is written as
a QuickBook type/link macro rather than plain text, ensuring the markup is
consistent with other symbols in this section.

]]

After the WebSocket handshake is accomplished, callers may send and receive
messages using the message oriented interface. This interface requires that
all of the buffers representing the message are known ahead of time:
完成 WebSocket 握手后,调用方可以使用面向消息的接口收发消息。该接口要求表示消息的所有缓冲区必须事先已知:

[code_websocket_4_2]

Expand All @@ -105,17 +77,15 @@ all of the buffers representing the message are known ahead of time:
all be made from the same implicit or explicit strand.
]

[heading Frames]
[heading 消息帧]

Some use-cases make it impractical or impossible to buffer the entire
message ahead of time:
某些场景下,提前将整个消息缓冲起来并不现实或不可行:

* Streaming multimedia to an endpoint.
* Sending a message that does not fit in memory at once.
* Providing incremental results as they become available.
* 将流式多媒体数据发送到终端。
* 发送无法一次性装入内存的消息。
* 在结果可用时逐步提供。

For these cases, the partial data oriented interface may be used. This
example reads and echoes a complete message using this interface:
在这些情况下,可以使用面向部分数据的接口。以下示例使用该接口读取并回显完整消息:

[code_websocket_4_3]

Expand Down
Loading