Bittly TCP Mock 服务用于模拟 TCP 服务, 用于测试 TCP 服务的调用。 MOCK 服务支持通过配置匹配规则自动 响应请求, 支持自定义分帧方式方便匹配数据处理, 支持通过脚本扩展功能。 当无法匹配规则时, 支持转发到其他 通讯连接,并将收到的数据转发到目标连接。
主机
: 主机地址端口
: 监听端口模式
: 内容模式, 支持文本和HEX两种模式字符集
: 当内容模式为文本模式时,可指定数据内容字符集,当字符集为 默认
时, 则使用当前项目指定的字符集。启用多客户端
: 是否启用多客户端自动切换至新客户端
: 在启用多客户端时, 是否自动切换至新客户端在服务运行时, 对于需要临时存储的数据, 可以通过变量来进行存储。 变量的值可以在服务运行时进行修改, 但在服务启动时,将会使用默认值进行初始化。
变量可以在脚本或者模板中使用,
例如在模板中使用变量:
{{ $var("变量名") }}
在脚本中使用变量:
// 获取变量
let value = $this.variableGet("变量名");
// 设置变量
$this.variableSet("变量名", "变量值");
当收到数据后,可能收到的数据不是一个完整的数据包,或者存在多余的数据,这时需要对数据进行分帧处理。
收到数据后直接提交给后续步骤处理,不做任何处理。
配置项
时间
: 超时时间,单位毫秒。当收到数据后,如果在超时时间内没有收到更多数据,则标识该数据为一个完整的数据包,提交给后续步骤处理。 如果在超时时间内收到更多数据,则继续等待。
配置项
换行符
: 换行符。支持\r
, \n
和 \r\n
。当收到数据后,如果收到换行符,则标识该数据为一个完整的数据包,提交给后续步骤处理。 如果没有收到换行符,则继续等待。
假设换行符为 \n
, 收到数据如下:
hello\nworld\n123
则收到的数据帧为:
hello\n
和
world\n
数据末尾的 123
会被保留,等待下一次数据到来。
配置项
长度
: 固定长度,单位字节。当收到数据后,如果收到的数据长度等于固定长度,则标识该数据为一个完整的数据包,提交给后续步骤处理。 如果收到的数据长度小于固定长度,则继续等待。
假设收到数据长度为 13,固定长度为 5,收到的数据如下:
hello12345!!!
则收到的数据帧为:
hello
和
12345
数据末尾的 !!!
会被保留,等待下一次数据到来。
配置项
帧头
: 帧头标识,可选。帧尾
: 帧尾标识,可选。超时
: 超时时间,单位毫秒。当配置了帧头和帧尾时,则当收到数据后,如果收到的数据包含帧头和帧尾,则标识该数据为一个完整的数据包,提交给后续步骤处理。 如果在帧头之前存在数据,则会被忽略, 即仅仅被帧头帧尾包括的内容会被提交给后续步骤处理。
假设帧头为 hello
,帧尾为 world
,收到的数据如下:
hello12345world
则收到的数据帧为:
12345
如果配置了帧头而未配置帧尾,接收到的数据将按以下规则处理:若能识别出下一帧的帧头,则将当前帧头至下一帧帧头之前的数据视为完整数据包, 并提交给后续处理。如果未检测到下一帧帧头,则系统将根据设置的超时时间等待,超时后将已接收的数据作为完整数据包处理。
若仅配置了帧尾而未配置帧头,当接收的数据包含帧尾时,将帧尾之前的所有数据视为一个完整的数据包,并提交给后续处理步骤。
当内容模式为文本时, 帧头和帧尾可以配置为文本,例如 hello
和 world
。
如果内容模式为HEX时,帧头和帧尾可以配置为十六进制,例如 AA BB
和 EE FF
。
配置项
表达式
: 正则表达式。忽略大小写
: 是否忽略大小写。当配置分帧模式为正则表达式时,收到数据后则会进行正则表达式匹配,并将匹配的数据内容作为一个完整的数据包提交给后续步骤处理。
例如,配置正则表达式为 hello.*world
,收到的数据如下:
hello12345world
则收到的数据帧为:
12345
当收到数据后,检查数据是否为一个完整的JSON数据包,如果是则提交给后续步骤处理。
例如,收到的数据如下:
{
"name": "hello",
"age": 18
}
{
"name": "world",
则收到的数据帧为:
{
"name": "hello",
"age": 18
}
当收到数据后,检查数据是否为一个完整的XML数据包,如果是则提交给后续步骤处理。
例如,收到的数据如下:
<name>hello</name>
<age>18
则收到的数据帧为:
<name>hello</name>
在默认情况下,MOCK服务在没有匹配到响应规则时, 不会进行任何数据响应操作。
但是,如果我们希望将部分数据转发到其他服务, 则可以通过 转发
功能来实现。
例如,起初我们设备没有实现任何功能, 则我们可以通过配置响应规则来响应所有请求数据。 当设备实现了部分功能时, 我们可以通过将原规则禁用掉, 从而将部分请求数据转发到真实设备, 其余数据继续由MOCK服务响应。
在配置了转发规则后, 当请求数据未匹配任何规则时, MOCK 服务则会将请求数据转发到指定的服务地址, 转发配置可配置不同类型的通讯方式, 例如可以将串口MOCK服务转发到TCP服务, 也可以将TCP服务转发到串口服务。 但是, 转发的要求是两种服务之间支持同一种数据类型,例如串口和TCP服务都支持文本以及二进制数据,所以可以进行转发。
转发目标通过通讯模块进行配置, 配置完成后可通过刷新按钮刷新转发目标列表, 选择需要转发的目标即可。 对于TCP获取UDP等支持多客户端的服务,仅有在未开启多客户端模式下才能进行转发。
当服务接收到数据后, 会依次匹配每个规则, 当规则匹配成功时, 会执行对应的响应操作,并且停止匹配。
当规则为任意
时, 会匹配任意数据。 所以可以将任意
规则放在最后, 以确保能够匹配到所有未匹配的数据。
当规则为文本
时, 会以文本方式进行匹配, 如果收到的数据与规则内容相同, 则执行对应的响应操作。
当规则为 通配符
时, 会以通配符方式进行匹配, 如果收到的数据与规则匹配成功, 则执行对应的响应操作。
在通配符中,使用 *
表示任意字符,使用 ?
表示任意单个字符。 如果需要匹配 *
或 ?
字符, 需要使用 \
进行转义。
例如, 规则 01*03
匹配 010203
, 01?03
匹配 0103
。
当规则为HEX
时, 会以HEX方式进行匹配, 如果收到的数据与规则内容相同, 则执行对应的响应操作。
当规则为正则表达式
时, 会以正则表达式进行匹配, 如果接收到的数据与规则匹配成功, 则执行对应的响应操作。
如果正则表达式中存在分组, 则分组数据将会被作为上下文数据用于响应操作。
例如, 正则表达式(?<temp>\d+),(?<level>\d+)
匹配123,456
时,
temp
的值为123
, level
的值为456
。
则在响应规则模板中可以使用 {{temp}}
和 {{level}}
来引用上下文数据。
当规则为HEX匹配
时, 会以HEX方式进行匹配, 如果接收到的数据与规则匹配成功, 则执行对应的响应操作。
如果表达式中存在变量解析, 则变量将会被解析为上下文数据用于响应操作。
例如, 表达式01 02 @U8<num> 04
匹配01 02 03 04
时, num
的值为数值3
。
则在响应规则模板中可以使用 {{num}}
来引用上下文数据。
当匹配规则为JSON
时, 会将请求数据解析为JSON对象后进行匹配, 如果接收到的数据与规则匹配成功, 则执行对应的响应操作。
并且收到的数据会被解析为JSON对象, 以便于后续的响应操作。
例如, 规则 $request.name === 'test'
匹配 {"name":"test"}
时, 则执行对应的响应操作。
其中 $request
表示整个JSON对象, $request.name
表示JSON对象中的 name
属性。
当匹配成功时, 会将匹配到的JSON对象作为上下文数据用于响应操作,
例如在响应规则模板中可以使用 {{$request.name}}
来引用上下文数据。
当规则为表达式
时, 会以表达式方式进行匹配, 如果接收到的数据与规则匹配成功, 则执行对应的响应操作。
其中,表达式可以调用 MOCK服务中脚本到处的函数, 例如在脚本中导出函数 test
:
export function test(name) {
return name === 'test';
}
则可以在匹配规则中使用 test('test')
进行匹配, 如果表达式返回 true
, 则执行对应的响应操作。
片段用于保存一些常用的传输内容,以便在需要时重复使用。 片段支持文本和HEX两种格式, 支持批量发送。
启用
: 配置是否启用该片段, 当片段被禁用时, 批量发送时不会发送该片段。名称
: 片段名称, 用于标识片段。格式
: 配置片段的格式, 支持文本和HEX两种格式。内容
: 配置片段的内容, 根据不同的格式填写不同的内容。延时
: 配置片段发送的延时时间, 单位毫秒。手动内容发送用于发送自定义内容。 支持文本和HEX两种格式, 支持定时发送。
Bittly 的 TCP Mock 服务支持通过脚本来改变执行流程以及自定义响应内容。 脚本采用 JavaScript
语法,
在服务执行时, Bittly 会将脚本编译为 Javascript Module 并在适当的实际执行对应的函数。
脚本函数可以分为两种类型, 一种是生命周期函数,例如 init
等,
另一种是由用户自定义的函数, 可用于在响应模板以及匹配条件中调用。
init()
初始化函数, 用于初始化脚本环境, 仅在服务启动时执行一次, 如果该函数执行失败,则服务启动失败。
例如
export async function init() {
$this.variableSet('counter', 0);
}
onClientData
当客户端发送数据时, 会调用该函数处理数据,例如追加自定义帧头,帧尾或者解析值到变量等,该函数必须返回处理后的数据。
例如
export async function onClientData( data ) {
return data;
}
beforeClientWrite
在客户端发送数据前, 会调用该函数处理数据,例如追加自定义帧头,帧尾或者解析值到变量等,该函数必须返回处理后的数据。
例如
export async function beforeClientWrite( data ) {
return data;
}
$this.variableGet(name)
获取当前变量值, 例如 $this.variableGet('counter')
。 当变量不存在时将会抛出异常。
请求参数
name
: 变量名称。返回值: 变量值
例如:
export async function init() {
// 获取变量值
let counter = $this.variableGet('counter');
console.log('Counter:', counter);
}
$this.variableSet(name, value)
设置当前变量值, 当变量不存在时将会抛出异常。
请求参数
name
: 变量名称。value
: 变量值。返回值: 无
例如:
export async function init() {
// 设置变量值
$this.variableSet('counter', 1);
}