前言
写了一个html测试程序,用来对片上的http_server通讯,下发命令和采集数据.
整完后,将知识点抽取出来,以后一定还会用上。
如果想不阻塞html UI的情况下,连续发送,接收数据,可以用setInterval做个定时器用来发包。
用setInterval做个定时器来做包接收的超时检测。
这样,就能执行分析一个不同命令的通讯序列。
html测试程序效果图
测试程序的效果整的有点丑,做测试够用了。
实验
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="jquery-1.7.1.min.js"></script>
<script type="text/javascript">
var var_url = "http://192.168.1.66/command/my_cmd"; // post 到片上服务器的 url, 这个url负责执行post过去的命令和并负责回答
var var_tm_id = 0; // 定时器ID
var var_tm_valid = 0; // 定时器有效么? 0 = 无效; 1 = 有效
var var_user_click_cmd = 0; // 用户手工点击的命令标记, 0 = 自动查询; 1 = 用户点击
var var_query_cnt = 0; // 查询的次数
var var_recv_package = 0; // 收到包的标记
$(document).ready(function () {
// 在chrome.exe的快捷方式中加入开关 --user-data-dir="d:\ChromeDebug" --test-type --disable-web-security
// 不是html的快捷方式加参数...
// 先打开改过的chrome.exe快捷方式, 然后将测试的html拖入chrome.exe中. 这时,就可以跨域请求了
// 这样调试html时,就不用将html拷贝到设备的磁盘设备中
$("input#cc_cmd_02").click(function () {
exec_cc_ctrl_cmd(get_order_data("cc_cmd_02"));
});
$("input#cc_cmd_18").click(function () {
exec_cc_ctrl_cmd(get_order_data_4("cc_cmd_18", 1, 1, 1, 1));
});
$("input#cc_cmd_19").click(function () {
exec_cc_ctrl_cmd(get_order_data_4("cc_cmd_19", 4, 4, 4, 4));
});
$("input#cc_cmd_58").click(function () {
exec_cc_ctrl_cmd(get_order_data_1("cc_cmd_58", 20));
});
$("input#bat_proc").click(function () {
// 这里按照实际流程填写, 保证执行一个函数就sleep一秒即可
exec_cc_ctrl_cmd(get_order_data("cc_cmd_02"));
sleep(1000);
exec_cc_ctrl_cmd(get_order_data_4("cc_cmd_18", 1, 1, 1, 1));
sleep(1000);
exec_cc_ctrl_cmd(get_order_data_4("cc_cmd_19", 4, 4, 4, 4));
sleep(1000);
exec_cc_ctrl_cmd(get_order_data_1("cc_cmd_58", 20));
sleep(1000);
});
// 任务轮询
if (0 == var_tm_valid) {
var_tm_id = setInterval("query_device_status1()", 500);
var_tm_valid = 1;
}
// 超时检测
setInterval("thread_timeout()", 5000);
});
function sleep(n) { //n表示的毫秒数
// 执行这个函数后, 浏览器UI就阻塞住了
// 如果调用这个函数,不能频繁调用.
// 调用的时候,n也要小点(e.g. 1秒 = 1000)
var start = new Date().getTime();
while (true) if (new Date().getTime() - start > n) break;
}
function get_order_data(order)
{
var var_rc = '{"order":"'+order+'"}';
return var_rc;
}
// p means parameter
function get_order_data_4(order, p1, p2, p3, p4)
{
var var_rc = '{"order":"' + order + '", "p1":"' + p1 + '", "p2":"' + p2 + '", "p3":"' + p3 + '", "p4":"' + p4 + '"}';
return var_rc;
}
function get_order_data_1(order, p1)
{
var var_rc = '{"order":"' + order + '", "p1":"' + p1 + '"}';
return var_rc;
}
function query_device_status1()
{
// 查询设备全部状态值
if (true /*var_query_cnt < 1*/) {
var_query_cnt += 1; // 只查询一次
if (1 != var_user_click_cmd) {
$("textarea#txtPost")[0].value = get_order_data("cc_stat_all");
exec_cc_cmd($("textarea#txtPost")[0].value);
}
}
}
function thread_timeout()
{
if (var_recv_package > 0) {
var_recv_package = 0;
} else {
var_user_click_cmd = 0; // 用户手工点击的命令执行完了
if (0 == var_tm_valid) {
var_tm_id = setInterval("query_device_status1()", 500);
var_tm_valid = 1;
}
}
}
// 控制命令 - 用户手工点击的命令
function exec_cc_ctrl_cmd(order_content)
{
var_user_click_cmd = 1; // 用户点击
exec_cc_cmd(order_content);
}
// 查询命令
function exec_cc_cmd(order_content)
{
if (1 == var_tm_valid) {
clearInterval(var_tm_id); // 停掉定时器
var_tm_valid = 0;
}
var buf_conv = [];
// async: false,
$.ajax({
url: var_url,
type:"post",
cache: false,
timeout:10000,
data:order_content,
success: function(data){
// data = "{"rc":"exec_ok","var1":"v1","var2":"v2","var3":"v3","var4":"v4","var5":"v5","var6":"v6","var7":"v7","var8":"v8","var9":"v9","var10":"v10"}"
console.log("data = " + data);
parser_rc_data(data);
}
});
}
function get_val_status(data)
{
var status = "未知";
if (data == "0")
{ // 0x00
status = "off";
} else if (data == "255")
{ // 0xff
status = "open";
} else if (data == "254")
{ // 0xfe
status = "failed";
}
return status;
}
function get_val_u16(data)
{
var rc;
if (data == 0xfefe) {
rc = "failed";
} else {
rc = data;
}
return rc;
}
function get_val_u8(data)
{
var rc;
if (data == 0xfe) {
rc = "failed";
} else {
rc = data;
}
return rc;
}
function parser_rc_data(data)
{
var var_tmp = "";
// 收到了包
var_recv_package = 1;
// 显示回包
$("textarea#txtResult")[0].value = data;
// 将回包转换成对象
buf_conv = eval('(' + data + ')');
// 显示分析结果
clear_parser_area();
show_parser_order(buf_conv.order);
show_parser_rc(buf_conv.rc);
// 根据order进行分析(每一种order的回包不一样)
if ("cc_stat_all" == buf_conv.order) {
document.getElementById("value0").value = get_val_status(buf_conv.value0);
document.getElementById("value1").value = get_val_status(buf_conv.value1);
document.getElementById("value2").value = get_val_status(buf_conv.value2);
var_tmp = get_val_u16(buf_conv.value3);
if ("failed" != var_tmp) {
var_tmp /= 10;
}
document.getElementById("value3").value = var_tmp;
// 一个包分析完了, 再开一个定时器, 延时后发包
// 下位机是单线程的处理http请求, 在关闭连接到建立新连接之间需要耗时,不能嗖嗖的发包. 需要间隔一个合适的延时后,再发新包
if (0 == var_tm_valid) {
var_tm_id = setInterval("query_device_status1()", 500);
var_tm_valid = 1;
}
}
else if (("cc_cmd_02" == buf_conv.order)
|| ("cc_cmd_18" == buf_conv.order)
|| ("cc_cmd_21" == buf_conv.order)
|| ("cc_cmd_58" == buf_conv.order)
) {
var_user_click_cmd = 0; // 用户手工点击的命令执行完了
// 一个包分析完了, 再开一个定时器, 延时后发包
if (0 == var_tm_valid) {
var_tm_id = setInterval("query_device_status1()", 500);
var_tm_valid = 1;
}
}
}
function clear_parser_area()
{
$("textarea#txt_parse")[0].value = "";
}
function show_parser_order(order)
{
$("textarea#txt_parse")[0].value += "order = ";
$("textarea#txt_parse")[0].value += order;
$("textarea#txt_parse")[0].value += "\r\n";
}
function show_parser_rc(rc)
{
$("textarea#txt_parse")[0].value += "rc = ";
$("textarea#txt_parse")[0].value += rc;
$("textarea#txt_parse")[0].value += "\r\n";
if (rc == "exec_ok") {
$("textarea#txt_parse")[0].value += "执行成功";
} else {
$("textarea#txt_parse")[0].value += "执行失败";
}
$("textarea#txt_parse")[0].value += "\r\n";
}
</script>
</head>
<body>
<a href="test.htm">进入本页</a>
<table>
<tr>
<td>下位机值显示区</td>
</tr>
<tr>
<td>
value0:<input type="text" id="value0" value="" readonly="readonly" />
value1:<input type="text" id="value1" value="" readonly="readonly" />
value2:<input type="text" id="value2" value="" readonly="readonly" />
value3:<input type="text" id="value3" value="" readonly="readonly" />
</br>
</td>
</tr>
<tr>
<td>
<h1>可以手工下发的命令<h1>
<br />
<div class="div1"><h4>• some command<hr></h4></div>
<input id="cc_cmd_02" type="button" value="function 1" >
<input id="cc_cmd_18" type="button" value="function 2" >
<input id="cc_cmd_19" type="button" value="function 3" >
<input id="cc_cmd_58" type="button" value="function 4" >
</td>
</tr>
<tr>
<td>
待发送数据<br />
<textarea id="txtPost" rows="2" cols="120"></textarea>
</td>
</tr>
<tr>
<td>
<input id="btnPostData" type="button" value="提交" />
</td>
</tr>
<tr>
<td>
返回结果<br />
<textarea id="txtResult" rows="2" cols="120"></textarea>
</td>
</tr>
<tr>
<td>
分析结果<br />
<textarea id="txt_parse" rows="2" cols="120"></textarea>
</td>
</tr>
</table>
<br />
</body>
</html>