下面用完全自定义的协议做例子:
```
<!--Role: work|web|ws|mq-->
<add key="Role" value="work|web|ws|mq|my;9991;777;test"/>
```
其中 my;9991;777;test 就是自己配置的协议,组成如下:
- my;端口号;最大连接数;服务名
- 服务成功启动后新的服务名为:my_服务名
- 如my;9991;777;test -》
服务名:my_test
端口号:9991
最大连接数:777
可以在下面地址中查看服务情况:
服务器情况:
自定义协议基于目前比较流行的定义开始符与结束符的协议:
两种选择
- 在根目录下
```
"MyProcess": {
"my_test": {
"process": "/./process.ds",
"close": "/./offline.ds",
"main": "/./main.ds"
}
},
```
- 在同名目录下
```
"MyProcess": {
"process": "/./process.ds",//连接成功后的处理逻辑
"close": "/./offline.ds",//连接断开后的处理逻辑
"main": "/./main.ds" //协议解析构成
},
```
下面例子是一个通用的解析处理(参考JT808协议):
```
//定义一个函数方便构成字典
function unit(name, type, length, value) {
return {
"name": name,//单元描述,仅说明含义,无实际用途
"type": type,//单元类型
"length": length,//单元长度
"value": value,//单元值
};
}
return [
unit("标识位", "STRING", 1, [0x7e]),
unit("消息ID", "WORD", 2),
unit("消息体属性", "WORD", 2),
unit("终端手机号", "BCD", 6),
unit("消息流水号", "WORD", 2),
unit("消息体", "BYTE[]", 0),
unit("校验码", "BYTE", 1),
unit("标识位", "STRING", 1, [0x7e]),
]
```
类型说明
类型名 | 字节数 | 说明 |
---|---|---|
BIT | 1位 | 位 |
ASCII | n | ASCII字符串 |
UTF8 | n | UTF8字符串 |
GBK | n | GBK字符串 |
STRING | n | GBK字符串 |
WORD | 2 | 2字节数字 |
DWORD | 4 | 4字节数字 |
DECIMAL | 8 | 8字节数字 |
BCD | 6 | BCD时间 |
DATE | 6 | 时间 |
DATE2 | 6 | 时间 |
BYTE | 1 | 1字节 |
BYTE[] | n | n字节 |
处理程序在协议解析成功后执行:
利用input函数可以知道服务端传过来了哪些内容,下面是调用的结果参考:
{
"server": "my_test",
"session": {
"id": "49fd17b5-0285-4f14-905b-87a0e4cd3d2f",
"ip": "192.168.0.107",
"time": "2020-09-20T01:21:57.322Z"
},
"data": {
"data": ["~", 512, 96, "14533806760", 4133, "AAAAAAAAAAABzqJQBq+NWAAAAAABNiAJFhkzNgEEAAACius8ACQAqQHMAAZwV+8HIHBXnIgtcFeechxwV6PWGnBXnT0WcFfvCRYADACyiYYEAhAgcAAyVgAGAIn/////",
218, "~"],
"bytes": "7E020000600145338067601025000000000000000001CEA25006AF8D5800000000013620091619333601040000028AEB3C002400A901CC00067057EF072070579C882D70579E721C7057A3D61A70579D3D167057EF0916000C00B28986040210207000325600060089FFFFFFFFDA7E",
"ip": "192.168.0.107",
"prop": null
},
"err": "",
"client": null
}
var input = input();//这个可以取到传过来的所有参数,可以记录到日志便于操作。
console.info(input());
//一般input()中会看到所有的输入参数,也就是设备端传过来的数据,参考前面的介绍
//我们可以获取到设备数据内容
var device_data=input.data.data;//其中的base64的内容实际上是二进制数组,后面可以进一步调用解析函数得到具体的内容。
var device_bytes=input.data.bytes;//这是原始的16进制报文
//下面可以通过内置的解析函数解析具体的数据内容:
var 消息体结构=[
unit("经度", "WORD", 4),
unit("纬度", "WORD", 4),
]
var 消息体内容=bytes.parse(device_data[5],消息体结构,device_data);//这里的3个参数:
//1. 二进制报文数据
//2. 消息体构成定义
//3. 收到的总体数据
//消息体内容 就是解析出来的数据,是个数据数组,后面可以将他们存入数据库或者实例进行实时通知等。
//下面是服务返回给设备的内容处理:
result.result = 0;//0表示没问题,如果为1表示有问题,会关掉连接
result.data = ["a", "b", "c"];//协议中的数据,与units里面定义的对应
result.units = [
unit("a", "STRING"),
unit("b", "STRING"),
unit("c", "STRING"),
]
return result;
//定义一个函数便于生成字典
function unit(name, type, length, value) {
return {
"name": name,
"type": type,
"length": length,
"value": value,
};
}
通过平台内置的管理页面可以很方便的进行管理:
下面这个例子可以在自定义的页面中集成实例数据与图形:
<html>
<head>
<file src="/admin/graphic/runtime/link"></file>
</head>
<body>
<b-page a="230" b=""></b-page>
<div>
<div>
<b-data id="message" value="/this/msg.message"></b-data>
</div>
<div>
<b-data value="=/this/msg.message+'_2222222'"></b-data>
</div>
<table>
<tr>
<td>
<b-symbol name="5e868fd3776caf06542a2e90" width="500" height="200" cp.a="/a">
</b-symbol>
</td>
<td>
<b-symbol name="5f017aa7a5a79a0390cd2f77" width="200" height="100" cp.b="/a">
</b-symbol>
</td>
<td>
<b-symbol name="/admin/home/symbols/ccc/mysymbol" width="200" height="100" cp.b="/a">
</b-symbol>
</td>
</tr>
</table>
</div>
</body>
<script>
//可以定义onchange函数,在收到数据后自定义显示
document.getElementById("message").onchange = function(value, time) {
//
document.getElementById("message").innerHTML = value + "," + time;
}
//-------------------------------------------
var myruntime = new GraphicRuntime(); //定义api对象
//在加载前执行,一般用作loading
myruntime.oninit = function(dom) {
//dom.parentElement.style.background = null;
var p = dom.parentElement;
p.style.background = "url(/admin/graphic/runtime/loading.gif) no-repeat 0 0";
p.style.backgroundSize = "50px 50px";
p.style.backgroundPositionX = "center";
p.style.backgroundPositionY = "center";
}
//在数据加载完成后,可以取消loading
myruntime.ondataready = function(dom) {
//dom.parentElement.style.background = null;
var p = dom.parentElement;
p.style.background = null;
}
//在图形加载完成后,参数分别为:(展示对象,图形标题,图形用的数据模板,当前实例)
myruntime.onready = function(display, title, template, instance) {
document.title = "图形-" + title;
var dom = display.getdom();
dom.parentElement.style.background = null;
//可以定义一个重新加载函数,重加载显示
window.reloaddisplay = function(cps) {
display.reload(cps);
}
//可以获取到模板下所有实例,便于操作实例的切换
mxUtils.mypost("/admin/graphic/runtime/api/get_instances.ds", {
"tid": template
}, {},
function(data) {
//
data = JSON.parse(data);
// data = [
// {
// "id": "",
// "name": "",
// "desc": "没有实例",
// "style": ""
// }
// ]
}, function(data) {
alert(data)
});
}
//定义图形尺寸大小
myruntime.getsize = function(dom) {
var p = dom.parentElement;
return {
width: p.clientWidth,
height: p.clientHeight
}
}
//出错后的处理
myruntime.onerror = function(error, dom) {
alert(error);
dom.parentElement.style.background = null;
}
//改变图形数据实例
function changeinstance(iid) {
myruntime.setinstance(iid);
};
//改变图形的自定义属性,也可设置实例:(name使用$.instance)
function setprop(name, value) {
myruntime.setpageprop(name, value);
};
//加载图形和数据
myruntime.load();
</script>
</html>