Skip to content

Commit 207ca7b

Browse files
authored
Dev202503 (#9)
* init Dev202503 * [update] #8 Remove GlobalStop Library, multiple clients instances could work simultaneously * update dependency * 同时支持 -> & -> 调用 #4 * #4 * [add] #4 support async-message/register/unregister. * polish all VIs * Recommendation: Debug Tools You can use CSM Tools to debugging your application. You can find the entry from labview project toolbar, CSM palette, quick drop and Right-Click menu of CSM loops. * update with deps * 更新 README(zh-cn).md * 备份设计 * update protocol * update Connection Handler Worker.vi * update readme * update Protocol.v0.(en).md * 备份修改 * 备份下测试代码 * update client UI * backupcode * update vipb --------- Co-authored-by: NEVSTOP <nevstop>
1 parent 84c89d8 commit 207ca7b

30 files changed

+668
-162
lines changed

.doc/CSM-TCP-Router 1.svg

Lines changed: 1 addition & 1 deletion
Loading

.doc/CSM-TCP-Router Sever BD.png

510 KB
Loading

.doc/CSM-TCP-Router.drawio

Lines changed: 86 additions & 86 deletions
Large diffs are not rendered by default.

.doc/Protocol.v0.(en).md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Protocol Definition
2+
3+
The TCP packet format used in the CSM-TCP-Router is defined as follows:
4+
5+
``` txt
6+
| Data Length (4B) | Version (1B) | TYPE (1B) | FLAG1 (1B) | FLAG2 (1B) | Text Data |
7+
╰─────────────────────── Header (8B) ──────────────────────────────╯╰─── Data Length Range ──╯
8+
```
9+
10+
## Header Fields
11+
12+
### Data Length (4 Bytes)
13+
14+
This field specifies the length of the data section and is represented using 4 bytes.
15+
16+
### Version (1 Byte)
17+
18+
This field indicates the version of the data packet. The current version is `0x01`. Different versions can be handled appropriately to ensure forward compatibility.
19+
20+
### Packet Type (1 Byte)
21+
22+
This field defines the type of the data packet and is an enumerated value. The supported packet types are:
23+
24+
- Information Packet (`info`) - `0x00`
25+
- Error Packet (`error`) - `0x01`
26+
- Command Packet (`cmd`) - `0x02`
27+
- Synchronous Response Packet (`resp`) - `0x03`
28+
- Asynchronous Response Packet (`async-resp`) - `0x04`
29+
- Subscription Status Packet (`status`) - `0x05`
30+
31+
### FLAG1 (1 Byte)
32+
33+
This field is reserved for future use to describe additional attributes of the data packet.
34+
35+
### FLAG2 (1 Byte)
36+
37+
Similar to FLAG1, this field is reserved for future use to describe additional attributes of the data packet.
38+
39+
## Data Content
40+
41+
### Information Packet (`info`)
42+
43+
The content of an information packet is plain text containing informational data.
44+
45+
### Error Packet (`error`)
46+
47+
The content of an error packet is plain text describing an error, formatted as per the CSM Error format.
48+
49+
> [!NOTE]
50+
> The CSM Error format is: `[Error: Error Code] Error Message`.
51+
52+
### Command Packet (`cmd`)
53+
54+
The content of a command packet is a command in the CSM local command format. It supports the following types of messages:
55+
56+
- Synchronous (`-@`)
57+
- Asynchronous (`->`)
58+
- Asynchronous without return (`->|`)
59+
- Register (`register`)
60+
- Unregister (`unregister`)
61+
62+
> [!NOTE]
63+
> Example: Suppose there is a CSM module named `DAQmx` in the local program with an interface `API: Start Sampling`. You can send the following messages to control data acquisition:
64+
>
65+
> ``` c++
66+
> API: Start Sampling -@ DAQmx // Synchronous message
67+
> API: Start Sampling -> DAQmx // Asynchronous message
68+
> API: Start Sampling ->| DAQmx // Asynchronous message without return
69+
> ```
70+
>
71+
> These messages can also be sent over a TCP connection to achieve remote control.
72+
73+
> [!NOTE]
74+
> Example: Suppose there is a CSM module `A` that continuously sends a monitoring status called `Status`. Another module `B` can subscribe to this status:
75+
>
76+
> ``` c++
77+
> status@a >> api@b -><register> // Subscribe to status
78+
> status@a >> api@b -><unregister> // Unsubscribe from status
79+
> ```
80+
>
81+
> Similarly, these messages can be sent over a TCP connection to manage subscriptions remotely.
82+
>
83+
> If the subscriber (`api@b`) is omitted, it indicates that the client connected to the TCP router is subscribing to the status:
84+
>
85+
> ``` c++
86+
> status@a -><register> // Client subscribes to module A's status
87+
> status@a >> api@b -><unregister> // Client unsubscribes from module A's status
88+
> ```
89+
>
90+
> When module `A` sends a `Status`, the client will automatically receive a `status` packet.
91+
92+
### Synchronous Response Packet (`resp`)
93+
94+
After executing a synchronous command, the TCP router sends a response packet back to the client.
95+
96+
### Asynchronous Response Packet (`async-resp`)
97+
98+
After executing an asynchronous command, the TCP router sends a response packet back to the client. The format is: `Response Data <- Original Asynchronous Message`.
99+
100+
### Subscription Status Packet (`status`)
101+
102+
When a client subscribes to the status of a CSM module, it will automatically receive this packet whenever the status changes.
103+
104+
The packet format is: `Status Name >> Status Data <- Sending Module`.

.doc/Protocol.v0.(zh-cn).md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# 传输协议
2+
3+
CSM-TCP-Router 中 TCP 数据包格式定义如下:
4+
5+
``` txt
6+
| 数据长度(4B) | 版本(1B) | TYPE(1B) | FLAG1(1B) | FLAG2(1B) | 文本数据 |
7+
╰─────────────────────────── 包头 ──────────────────────────╯╰──── 数据长度字范围 ────╯
8+
```
9+
10+
## 包头字段
11+
12+
### 数据长度(4字节)
13+
14+
数据长度为4字节,表示数据字段的长度。
15+
16+
### 版本信息(1字节)
17+
18+
版本信息为1字节,表示数据包的版本信息。当前的版本信息为 `0x01`。可以根据版本信息进行不同的处理,实现向前兼容。
19+
20+
### 数据包类型(1字节)
21+
22+
数据包类型用于描述数据包的内容,为枚举类型,目前支持的数据包类型有:
23+
24+
- 信息数据包(info) - `0x00`
25+
- 错误数据包(error) - `0x01`
26+
- 指令数据包(cmd) - `0x02`
27+
- 同步响应数据包(resp) - `0x03`
28+
- 异步响应数据包(async-resp) - `0x04`
29+
- 订阅返回数据包(status) - `0x05`
30+
31+
### FLAG1类型(1字节)
32+
33+
FLAG1用于描述数据包的属性, 保留字段。
34+
35+
### FLAG2类型(1字节)
36+
37+
FLAG2用于描述数据包的属性, 保留字段。
38+
39+
## 数据内容
40+
41+
### 信息数据包(info)
42+
43+
info 数据包的数据内容为提示信息内容,纯文本格式。
44+
45+
### 错误数据包(error)
46+
47+
error 数据包的数据内容为错误信息内容,为纯文本格式,文本格式定为 CSM Error 格式。
48+
49+
> [!NOTE]
50+
> CSM Error 格式为:"[Error: `错误代码`]`错误字符串`"。
51+
>
52+
53+
### 指令数据包(cmd)
54+
55+
指令数据包的数据内容为指令内容,格式为 CSM 本地指令格式,支持:
56+
57+
- 同步(-@)
58+
- 异步(->)
59+
- 无返回异步(->|)消息,
60+
- 注册(register)
61+
- 注销(unregister)。
62+
63+
> [!NOTE]
64+
> 举例:假设本地程序存在名为DAQmx的CSM模块,具有一个接口为 "API: Start Sampling".
65+
> 本地我们可以发送消息给这个模块,控制采集的启停:
66+
>
67+
> ``` c++
68+
> API: Start Sampling -@ DAQmx // 同步消息
69+
> API: Start Sampling -> DAQmx // 异步消息
70+
> API: Start Sampling ->| DAQmx // 异步无返回消息
71+
> ```
72+
>
73+
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程消息。
74+
>
75+
76+
> [!NOTE]
77+
> 举例:假设本地程序存在名为A的CSM模块,不停的发送一个监控状态为 "Status", 另外一个模块B可以订阅这个状态。
78+
>
79+
> ``` c++
80+
> status@a >> api@b -><register> // 订阅状态
81+
> status@a >> api@b -><unregister> // 取消订阅
82+
> ```
83+
>
84+
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程控制底层 csm 模块的订阅
85+
>
86+
> 但是如果发送中缺省了订阅方(api@b), 则表示连接到 tcp-router 的 client订阅状态
87+
>
88+
> ``` c++
89+
> status@a -><register> // client 订阅 A 模块status
90+
> status@a >> api@b -><unregister> // 取消 client 订阅 A 模块status
91+
> ```
92+
>
93+
> 当 A 模块发出 Status 后,client 将自动收到 `status` 数据包
94+
>
95+
96+
### 同步响应数据包(resp)
97+
98+
当执行完毕同步消息指令后,tcp-router 将 response 返回给 client.
99+
100+
### 异步响应数据包(async-resp)
101+
102+
当执行完毕同步消息指令后,tcp-router 将 response 返回给 client. 格式为:"`Response数据` <- `异步消息原文`"
103+
104+
### 订阅返回数据包(status)
105+
106+
Client 订阅了CSM模块的状态,当状态发生时,client 会自动收到此数据包。
107+
108+
数据包格式为 "状态名 >> `状态数据` <- 发送模块"

.doc/Protocol.v1.(zh-cn).md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# 传输协议
2+
3+
CSM-TCP-Router 中 TCP 数据包格式定义如下:
4+
5+
``` txt
6+
╭────────────────── CRC校验范围 ────────────────────╮
7+
| 数据长度(4B) | 版本(1B) | FLAG1(1B) | FLAG2(1B) | TYPE(1B) | 文本长度(4B) | 文本数据 | 二进制长度(4B) | 二进制数据 | CRC(2B) |
8+
╰─────────────────────────── 包头 ──────────────────────────╯╰──────────────────── 数据长度字范围 ──────────────────────────╯
9+
```
10+
11+
## 包头字段
12+
13+
### 数据长度(4字节)
14+
15+
数据长度为4字节,表示数据字段的长度。
16+
17+
### 版本信息(1字节)
18+
19+
版本信息为1字节,表示数据包的版本信息。当前的版本信息为 `0x01`。可以根据版本信息进行不同的处理,实现向前兼容。
20+
21+
### FLAG1类型(1字节)
22+
23+
FLAG1用于描述数据包的属性
24+
25+
``` ini
26+
FLAG_TEXT = 0b00000001 # 存在文本数据(置1时需解析文本长度+内容)
27+
FLAG_BIN = 0b00000010 # 存在二进制数据(置1时需解析二进制长度+内容)
28+
FLAG_CRC = 0B00010000 # 存在CRC校验(置1时需解析CRC校验)
29+
```
30+
31+
### FLAG2类型(1字节)
32+
33+
FLAG2用于描述数据包的属性, 保留字段。
34+
35+
### 数据包类型(1字节)
36+
37+
数据包类型用于描述数据包的内容,为枚举类型,目前支持的数据包类型有:
38+
39+
- 信息数据包(info) - `0x00`
40+
- 错误数据包(error) - `0x01`
41+
- 指令数据包(cmd) - `0x02`
42+
- 同步响应数据包(resp) - `0x03`
43+
- 异步响应数据包(async-resp) - `0x04`
44+
- 订阅返回数据包(status) - `0x05`
45+
46+
## 数据内容
47+
48+
当 FLAG1 的 `FLAG_TEXT` 为1时,数据包中存在文本数据。文本数据的格式为:`文本数据长度(4字节)` | `文本数据内容`
49+
当 FLAG1 的 `FLAG_BIN` 为1时,数据包中存在二进制数据。二进制数据的格式为:`二进制数据长度(4字节)` | `二进制数据内容`
50+
51+
> [!NOTE]
52+
> `数据包类型`决定了数据内容的格式, 主要规定了文本数据的内容。
53+
>
54+
55+
> [!NOTE]
56+
>
57+
> 目前当文本数据格式中存在`MassData`类型的参数或返回数据时,才会有二进制数据。
58+
>
59+
60+
### 文本数据
61+
62+
#### 信息数据包(info)
63+
64+
info 数据包的数据内容为提示信息内容,纯文本格式。
65+
66+
#### 错误数据包(error)
67+
68+
error 数据包的数据内容为错误信息内容,为纯文本格式,文本格式定为 CSM Error 格式。
69+
70+
> [!NOTE]
71+
> CSM Error 格式为:"[Error: `错误代码`]`错误字符串`"。
72+
>
73+
74+
#### 指令数据包(cmd)
75+
76+
指令数据包的数据内容为指令内容,格式为 CSM 本地指令格式,支持:
77+
78+
- 同步(-@)
79+
- 异步(->)
80+
- 无返回异步(->|)消息,
81+
- 注册(register)
82+
- 注销(unregister)。
83+
84+
> [!NOTE]
85+
> 举例:假设本地程序存在名为DAQmx的CSM模块,具有一个接口为 "API: Start Sampling".
86+
> 本地我们可以发送消息给这个模块,控制采集的启停:
87+
>
88+
> - API: Start Sampling -@ DAQmx // 同步消息
89+
> - API: Start Sampling -> DAQmx // 异步消息
90+
> - API: Start Sampling ->| DAQmx // 异步无返回消息
91+
>
92+
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程消息。
93+
>
94+
95+
> [!NOTE]
96+
> 举例:假设本地程序存在名为A的CSM模块,不停的发送一个监控状态为 "Status", 另外一个模块B可以订阅这个状态。
97+
>
98+
> - status@a >> api@b -><register> // 订阅状态
99+
> - status@a >> api@b -><unregister> // 取消订阅
100+
>
101+
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程控制底层 csm 模块的订阅
102+
>
103+
> 但是如果发送中缺省了订阅方(api@b), 则表示连接到 tcp-router 的 client订阅状态
104+
>
105+
> - status@a -><register> // client 订阅 A 模块status
106+
> - status@a >> api@b -><unregister> // 取消 client 订阅 A 模块status
107+
>
108+
> 当 A 模块发出 Status 后,client 将自动收到 `status` 数据包
109+
>
110+
111+
#### 同步响应数据包(resp)
112+
113+
当执行完毕同步消息指令后,tcp-router 将 response 返回给 client.
114+
115+
#### 异步响应数据包(async-resp)
116+
117+
当执行完毕同步消息指令后,tcp-router 将 response 返回给 client. 格式为:"`Response数据` <- `异步消息原文`"
118+
119+
#### 订阅返回数据包(status)
120+
121+
Client 订阅了CSM模块的状态,当状态发生时,client 会自动收到此数据包。
122+
123+
数据包格式为 "状态名 >> `状态数据` <- 发送模块"
124+
125+
### 二进制数据
126+
127+
当大量数据需要进行传递时,使用二进制格式传输会在不损失精度的前提下节省带宽。目前支持 CSM MassData 数据格式,当文本描述中的参数、返回为 CSM MassData 数据时,MassData 指向的数据区域,将被放置在`二进制数据段` 传输。
128+
129+
> [!NOTE]
130+
> 举例,假设本地程序存在名为DAQmx的CSM模块,具有一个接口为 "API: Read Data", 返回的 Response 为 MassData 格式
131+
>
132+
> 通常返回的纯文本描述为 <MassData>Start:100;Length:1000
133+
>
134+
> 此时,MassData 指向的数据区域,将被放置在`二进制数据段` 传输。
135+
136+
## CRC校验
137+
138+
当 FLAG1 的 `FLAG_CRC` 为1时,数据包中存在CRC校验。CRC校验为2字节,校验范围为数据内容段,不包括包头。

CSM-TCP-Router.vipb

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
<VI_Package_Builder_Settings Version="2020.1" Created_Date="2023-09-27 14:21:53" Modified_Date="2025-02-28 15:22:55" Creator="liyao" Comments="" ID="87a1501566075aebed5513952fe62c41">
1+
<VI_Package_Builder_Settings Version="2020.1" Created_Date="2023-09-27 14:21:53" Modified_Date="2025-03-26 22:57:17" Creator="liyao" Comments="" ID="d445ff5669eab75606fa3bc7f2771d1e">
22
<Library_General_Settings>
33
<Package_File_Name>NEVSTOP_lib_CSM_TCP_Router_Example</Package_File_Name>
4-
<Library_Version>2025.2.0.2</Library_Version>
4+
<Library_Version>2025.3.0.2</Library_Version>
55
<Auto_Increment_Version>false</Auto_Increment_Version>
66
<Library_Source_Folder>src</Library_Source_Folder>
77
<Library_Output_Folder>vip</Library_Output_Folder>
@@ -18,11 +18,10 @@
1818
<Advanced_Settings>
1919
<Package_Dependencies>
2020
<Additional_External_Dependencies>jki_lib_tcp_server &gt;=5.0.0.8</Additional_External_Dependencies>
21-
<Additional_External_Dependencies>nevstop_lib_communicable_state_machine &gt;=2025.2.28.95859</Additional_External_Dependencies>
22-
<Additional_External_Dependencies>nevstop_lib_csm_api_string_arguments_support &gt;=2025.1.27.145038</Additional_External_Dependencies>
23-
<Additional_External_Dependencies>nevstop_lib_csm_ini_static_variable_support &gt;=2025.2.28.100053</Additional_External_Dependencies>
21+
<Additional_External_Dependencies>nevstop_lib_communicable_state_machine &gt;=2025.3.24.114002</Additional_External_Dependencies>
22+
<Additional_External_Dependencies>nevstop_lib_csm_api_string_arguments_support &gt;=2025.3.14.155345</Additional_External_Dependencies>
23+
<Additional_External_Dependencies>nevstop_lib_csm_ini_static_variable_support &gt;=2025.3.23.221959</Additional_External_Dependencies>
2424
<Additional_External_Dependencies>nevstop_lib_csm_massdata_parameter_support &gt;=2024.12.31.84154</Additional_External_Dependencies>
25-
<Additional_External_Dependencies>nevstop_lib_globalstop &gt;=2022.12.12.102654</Additional_External_Dependencies>
2625
<Additional_External_Dependencies>oglib_error &gt;=4.2.0.23</Additional_External_Dependencies>
2726
<Additional_External_Dependencies>oglib_time &gt;=4.0.1.3</Additional_External_Dependencies>
2827
</Package_Dependencies>
@@ -75,11 +74,8 @@
7574
<Copyright/>
7675
<Packager>NEVSTOP</Packager>
7776
<URL>https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App</URL>
78-
<Release_Notes>[add] add IP address/Port input dialog for client.
79-
[update] update connection information
80-
[update] update server/client VI icon
81-
[fix] type "bye", client will exit, as the connection will be closed from server side.
82-
[fix] minor fix. #5</Release_Notes>
77+
<Release_Notes>[add] #4 support async message/register/unregister.
78+
[update] #8 Remove GlobalStop Library, multiple clients instances could work simultaneously</Release_Notes>
8379
</Description>
8480
<Destinations>
8581
<Toolkit_VIs>

0 commit comments

Comments
 (0)