Skip to content
129 changes: 126 additions & 3 deletions .doc/Protocol.v0.(en).md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ This field defines the type of the data packet and is an enumerated value. The s
- Information Packet (`info`) - `0x00`
- Error Packet (`error`) - `0x01`
- Command Packet (`cmd`) - `0x02`
- Synchronous Response Packet (`resp`) - `0x03`
- Asynchronous Response Packet (`async-resp`) - `0x04`
- Subscription Status Packet (`status`) - `0x05`
- Command Response Packet (`cmd-resp`) - `0x03`
- Synchronous Response Packet (`resp`) - `0x04`
- Asynchronous Response Packet (`async-resp`) - `0x05`
- Subscription Normal Broadcast Packet (`status`) - `0x06`
- Subscription Interrupt Broadcast Packet (`interrupt`) - `0x07`

### FLAG1 (1 Byte)

Expand All @@ -42,6 +44,22 @@ Similar to FLAG1, this field is reserved for future use to describe additional a

The content of an information packet is plain text containing informational data.

The server sends an `info` packet to the client in two specific situations:

- **On Connection**: When a client successfully connects to the server, the server sends a welcome `info` packet:

```
Welcome to the CSM TCP Router Server
API: "list", "list api", "list states", "help"
type "bye" to close connection from Server side.
```

- **On Disconnection**: When the connection is closed from the server side, the server sends a goodbye `info` packet:

```
Good bye.
```

### Error Packet (`error`)

The content of an error packet is plain text describing an error, formatted as per the CSM Error format.
Expand Down Expand Up @@ -89,6 +107,20 @@ The content of a command packet is a command in the CSM local command format. It
>
> When module `A` sends a `Status`, the client will automatically receive a `status` packet.

### Command Response Packet (`cmd-resp`)

Except for synchronous messages (`-@`), all other command packets (`cmd`) receive a handshake response after being received and processed by the server:

- **Normal case**: A `cmd-resp` packet is returned, indicating the command has been accepted and triggered for execution.
- **Error case**: An `error` packet is returned, indicating the command was not accepted or an error occurred during execution (e.g., the target module does not exist, execution failed, etc.).

> [!NOTE]
> `cmd-resp` is a handshake acknowledgment of the command, indicating that the command has been accepted and execution has started. It does not contain business response data.
> Business response data is returned via `resp` or `async-resp` packets.
>
> Synchronous messages (`-@`) do not have a `cmd-resp` handshake; upon completion, they directly return `resp` or `error`.
>

### Synchronous Response Packet (`resp`)

After executing a synchronous command, the TCP router sends a response packet back to the client.
Expand All @@ -102,3 +134,94 @@ After executing an asynchronous command, the TCP router sends a response packet
When a client subscribes to the status of a CSM module, it will automatically receive this packet whenever the status changes.

The packet format is: `Status Name >> Status Data <- Sending Module`.

## Communication Flow

### Synchronous Message Flow (`-@`)

After the client sends a synchronous command, it **must wait** for the server to return a response: either a `resp` (synchronous response data) or an `error` (error message). Synchronous messages do not have a `cmd-resp` handshake packet.

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server

C->>S: cmd (synchronous message -@)
alt Command executed successfully
S-->>C: resp (synchronous response data)
else Command execution failed
S-->>C: error (error message)
end
```

### Asynchronous Message Flow (`->`)

After the client sends an asynchronous command, the server first returns a confirmation packet: either `cmd-resp` (command accepted) or `error` (command not accepted or execution error). Upon receiving `cmd-resp`, the client **does not need to wait** for the business response and can continue sending other commands; after asynchronous processing is complete, the server returns an `async-resp` packet.

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server

C->>S: cmd (asynchronous message ->)
alt Command accepted
S-->>C: cmd-resp (command accepted)
Note over S: Processing asynchronously...
S-->>C: async-resp (asynchronous response data)
else Not accepted or execution error
S-->>C: error (error message)
end
```

### Asynchronous Without Return Flow (`->|`)

After the client sends an asynchronous without return command, the server first returns a confirmation packet: either `cmd-resp` (command accepted) or `error` (command not accepted or execution error). Once the command is accepted, **no** business response packet will be returned after processing is complete.

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server

C->>S: cmd (asynchronous without return ->|)
alt Command accepted
S-->>C: cmd-resp (command accepted)
else Not accepted or execution error
S-->>C: error (error message)
end
```

### Subscribe/Unsubscribe Flow (`<register>` / `<unregister>`)

After the client sends a subscribe or unsubscribe command, the server returns a `cmd-resp` handshake confirmation. Once subscribed, whenever the subscribed module emits a status, the client continuously receives `status` packets (normal broadcast) or `interrupt` packets (interrupt broadcast), until unsubscribed.

> [!NOTE]
> Both `status` and `interrupt` subscription broadcast types are supported:
> - `status` (`0x06`): Normal broadcast, subscribes to regular status changes of the module
> - `interrupt` (`0x07`): Interrupt broadcast, subscribes to interrupt events triggered by the module
>

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server
participant M as CSM Module

C->>S: cmd (<register> subscribe)
alt Subscription successful
S-->>C: cmd-resp (subscription accepted)
Note over M,S: When module status changes...
M->>S: Normal status broadcast
S-->>C: status (status data)
M->>S: Interrupt broadcast
S-->>C: interrupt (interrupt data)
else Subscription failed
S-->>C: error (error message)
end

C->>S: cmd (<unregister> unsubscribe)
alt Unsubscription successful
S-->>C: cmd-resp (unsubscription accepted)
else Unsubscription failed
S-->>C: error (error message)
end
```
131 changes: 126 additions & 5 deletions .doc/Protocol.v0.(zh-cn).md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ CSM-TCP-Router 中 TCP 数据包格式定义如下:
- 错误数据包(error) - `0x01`
- 指令数据包(cmd) - `0x02`
- 指令响应数据包(cmd-resp) - `0x03`
- 同步响应数据包(resp) - `0x03`
- 异步响应数据包(async-resp) - `0x04`
- 订阅普通广播返回数据包(status) - `0x05`
- 订阅中断广播返回数据包(interrupt) - `0x06`
- 同步响应数据包(resp) - `0x04`
- 异步响应数据包(async-resp) - `0x05`
- 订阅普通广播返回数据包(status) - `0x06`
- 订阅中断广播返回数据包(interrupt) - `0x07`

### FLAG1类型(1字节)

Expand All @@ -44,6 +44,22 @@ FLAG2用于描述数据包的属性, 保留字段。

info 数据包的数据内容为提示信息内容,纯文本格式。

服务端会在以下两种情况下向客户端发送 `info` 数据包:

- **连接时**:客户端成功连接到服务器后,服务端发送欢迎 `info` 数据包:

```
Welcome to the CSM TCP Router Server
API: "list", "list api", "list states", "help"
type "bye" to close connection from Server side.
```

- **断开连接时**:当连接从服务端侧关闭时,服务端发送告别 `info` 数据包:

```
Good bye.
```

### 错误数据包(error)

error 数据包的数据内容为错误信息内容,为纯文本格式,文本格式定为 CSM Error 格式。
Expand Down Expand Up @@ -95,16 +111,121 @@ error 数据包的数据内容为错误信息内容,为纯文本格式,文
> 当 A 模块发出 Status 后,client 将自动收到 `status` 数据包
>

### 指令响应数据包(cmd-resp)

除同步消息(-@)外,其他指令数据包(cmd)在被服务端接收并处理后,都会有一个握手返回:

- **正常情况**:返回 `cmd-resp` 数据包,表示指令已被接受并触发执行。
- **错误情况**:返回 `error` 数据包,表示指令未被接受或执行出现错误(如目标模块不存在、执行失败等)。

> [!NOTE]
> `cmd-resp` 是对指令的握手确认,表示指令已被接受并开始执行,不包含业务响应数据。
> 业务响应数据由 `resp` 或 `async-resp` 数据包返回。
>
> 同步消息(-@)没有 `cmd-resp` 握手,执行完成后直接返回 `resp` 或 `error`。
>

### 同步响应数据包(resp)

当执行完毕同步消息指令后,tcp-router 将 response 返回给 client.

### 异步响应数据包(async-resp)

当执行完毕同步消息指令后,tcp-router 将 response 返回给 client. 格式为:"`Response数据` <- `异步消息原文`"
当执行完毕异步消息指令后,tcp-router 将 response 返回给 client. 格式为:"`Response数据` <- `异步消息原文`"

### 订阅返回数据包(status)

Client 订阅了CSM模块的状态,当状态发生时,client 会自动收到此数据包。

数据包格式为 "状态名 >> `状态数据` <- 发送模块"

## 通信流程

### 同步消息流程 (`-@`)

客户端发送同步指令后,**必须等待**服务端返回响应:要么收到 `resp`(同步业务响应数据),要么收到 `error`(错误信息)。同步消息没有 `cmd-resp` 握手包。

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server

C->>S: cmd (同步消息 -@)
alt 指令执行成功
S-->>C: resp (同步响应数据)
else 指令执行失败
S-->>C: error (错误信息)
end
```

### 异步消息流程 (`->`)

客户端发送异步指令后,服务端首先返回确认包:要么是 `cmd-resp`(指令已接受),要么是 `error`(指令未被接受或执行出现错误)。若收到 `cmd-resp`,客户端**无需等待**业务响应,可继续发送其他指令;服务端异步处理完毕后,返回 `async-resp` 数据包。

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server

C->>S: cmd (异步消息 ->)
alt 指令已接受
S-->>C: cmd-resp (指令已接受)
Note over S: 异步处理中...
S-->>C: async-resp (异步响应数据)
else 未被接受或执行出错
S-->>C: error (错误信息)
end
```

### 异步无返回消息流程 (`->|`)

客户端发送异步无返回指令后,服务端首先返回确认包:要么是 `cmd-resp`(指令已接受),要么是 `error`(指令未被接受或执行出现错误)。指令被接受后,业务处理完成后**不会**返回业务响应数据包。

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server

C->>S: cmd (异步无返回消息 ->|)
alt 指令已接受
S-->>C: cmd-resp (指令已接受)
else 未被接受或执行出错
S-->>C: error (错误信息)
end
```

### 订阅/注销流程 (`<register>` / `<unregister>`)

客户端发送订阅或注销指令后,服务端返回 `cmd-resp` 握手确认。订阅成功后,每当被订阅模块发出状态,客户端会持续收到 `status` 数据包(普通广播)或 `interrupt` 数据包(中断广播),直到取消订阅。

> [!NOTE]
> `status` 和 `interrupt` 两种订阅广播类型均受支持:
> - `status`(`0x06`):普通广播,订阅模块的常规状态变化
> - `interrupt`(`0x07`):中断广播,订阅模块触发的中断事件
>

```mermaid
sequenceDiagram
participant C as Client
participant S as TCP-Router Server
participant M as CSM 模块

C->>S: cmd (<register> 订阅)
alt 订阅成功
S-->>C: cmd-resp (订阅已接受)
Note over M,S: 模块状态变化时...
M->>S: 普通状态广播
S-->>C: status (状态数据)
M->>S: 中断广播
S-->>C: interrupt (中断数据)
else 订阅失败
S-->>C: error (错误信息)
end

C->>S: cmd (<unregister> 取消订阅)
alt 取消成功
S-->>C: cmd-resp (取消订阅已接受)
else 取消失败
S-->>C: error (错误信息)
end
```
12 changes: 7 additions & 5 deletions README(zh-cn).md
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@
CSM-TCP-Router 中 TCP 数据包格式定义如下:

```
| 数据长度(4B) | 版本(1B) | FLAG1(1B) | FLAG2(1B) | TYPE(1B) | 文本数据 |
| 数据长度(4B) | 版本(1B) | TYPE(1B) | FLAG1(1B) | FLAG2(1B) | 文本数据 |
╰─────────────────────────── 包头 ──────────────────────────╯╰──── 数据长度字范围 ────╯
```

数据包类型用于描述数据包的内容,为枚举类型,目前支持的数据包类型有:

- 信息数据包(info) - `0x00`
- 信息数据包(info) - `0x00`:服务端在客户端连接时(欢迎消息)和连接关闭时(告别消息)发送
- 错误数据包(error) - `0x01`
- 指令数据包(cmd) - `0x02`
- 同步响应数据包(resp) - `0x03`
- 异步响应数据包(async-resp) - `0x04`
- 订阅返回数据包(status) - `0x05`
- 指令响应数据包(cmd-resp) - `0x03`
- 同步响应数据包(resp) - `0x04`
- 异步响应数据包(async-resp) - `0x05`
- 订阅普通广播返回数据包(status) - `0x06`
- 订阅中断广播返回数据包(interrupt) - `0x07`

详细的通讯协议定义, 见 [协议设计](.doc/Protocol.v0.(zh-cn).md)

Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ The TCP packet format used in the CSM-TCP-Router is defined as follows:

This field defines the type of the data packet and is an enumerated value. The supported packet types are:

- Information Packet (`info`) - `0x00`
- Information Packet (`info`) - `0x00`: Sent by the server when a client connects (welcome message) and when the connection is closed (goodbye message)
- Error Packet (`error`) - `0x01`
- Command Packet (`cmd`) - `0x02`
- Synchronous Response Packet (`resp`) - `0x03`
- Asynchronous Response Packet (`async-resp`) - `0x04`
- Subscription Status Packet (`status`) - `0x05`
- Command Response Packet (`cmd-resp`) - `0x03`
- Synchronous Response Packet (`resp`) - `0x04`
- Asynchronous Response Packet (`async-resp`) - `0x05`
- Subscription Normal Broadcast Packet (`status`) - `0x06`
- Subscription Interrupt Broadcast Packet (`interrupt`) - `0x07`

For detailed communication protocol definitions, see [Protocol Design](.doc/Protocol.v0.(en).md).

Expand Down