來自掃碼槍應用適配的經驗及擴展。
查了好多資料,發現實現思路不外乎以下幾種:
1.使用服務端開發語言開發一個讀取串口數據的本地服務模塊,並實現websocket長連接支持,前端開啓長連接到該服務,根據推送的數據進行操作。
2.針對IE瀏覽器,可以採用ActiveX插件讀取串口數據,根據插件的API進行開發。
3.對於chrome瀏覽器,可以使用Chrome.serial實現
這幾種方式本質區別不大,只是瀏覽器兼容方面有區別。第一種方式是兼容性最好的,但增加了一個本地服務模塊的開發,所以開發成本較高。第二種ActiveX插件對IE瀏覽器兼容最好。第三種同樣需要自己開發一個chrome app來調用chrome.serial接口。
由於項目要求使用IE瀏覽器,下面只對IE瀏覽器下使用ActiveX插件讀取串口數據的步驟進行詳述。
在這裏採用的是微軟開發的mscomm32.ocx.
1.下載插件並複製 MSCOMM32.OCX 到 C:\WINDOWS\SysWOW64 (如果是32位系統就是 C:\WINDOWS\SysWOW32 )
2.依次運行下面命令(以管理員身份運行,注意根據系統32位和64位更改命令中的路徑):
regsvr32 /u C:\WINDOWS\SysWOW64\MSCOMM32.OCX
regsvr32 /i C:\WINDOWS\SysWOW64\MSCOMM32.OCX
regsvr32 C:\WINDOWS\SysWOW64\MSCOMM32.OCX
Reg add"HKEY_CLASSES_ROOT\Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905" /v “” /d “kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun” /f
3.設置IE瀏覽器的ActiveX插件的安全控制,將之都設爲啓用或提示狀態。
以上配置完成,可以用下面的代碼嘗試是否安裝成功
<!DOCTYPE html>
<html>
<head>
<title>JavaScript串口測試</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script ID=clientEventHandlersJS LANGUAGE=javascript>
function MSComm1_OnComm() {
switch(MSComm1.CommEvent) {
case 1:
{
window.alert("Send OK!");
break;
} //發送事件
case 2:
{
Receive();
break;
} //接收事件
default:
alert("Event Raised!" + MSComm1.CommEvent);;
}
}
</script>
<script LANGUAGE=javascript FOR=MSComm1 EVENT=OnComm>
// MSComm1控件每遇到 OnComm 事件就調用 MSComm1_OnComm()函數
MSComm1_OnComm()
</script>
<script language="JavaScript" type="text/JavaScript">
String.prototype.Blength = function(){
var arr = this.match(/[^\x00-\xff]/ig);
return arr == null ? this.length : this.length + arr.length;
}
function OperatePort() {
if(MSComm1.PortOpen == true) {
try {
MSComm1.PortOpen = false;
document.getElementById("OperateButton").value = "打開串口";
} catch(ex) {
alert(ex.message);
}
} else {
try {
MSComm1.PortOpen = true;
document.getElementById("OperateButton").value = "關閉串口";
} catch(ex) {
alert(ex.message);
}
}
}
function ConfigPort() {
alert("串口狀態:" + MSComm1.PortOpen);
if(MSComm1.PortOpen == false) {
try {
MSComm1.CommPort = document.getElementById("ComName").value;
alert(MSComm1.CommPort)
MSComm1.Settings = document.getElementById("BaudRate").value.toString() + "," +
document.getElementById("CheckBit").value.toString() + "," +
document.getElementById("DataBits").value.toString() + "," +
document.getElementById("StopBits").value.toString();
MSComm1.OutBufferCount = 0; //清空發送緩衝區
MSComm1.InBufferCount = 0; //滑空接收緩衝區
alert("已配置串口COM" + MSComm1.CommPort + "\n 參數:" + MSComm1.Settings);
} catch(ex) {
alert(ex.message);
}
} else {
alert("請先關閉串口後再設置!");
}
}
function Send() {
//alert(document.getElementById("txtSend").value);
var orgstr = document.getElementById("txtSend").value;
var newstr = "";
var hexflag = document.getElementById("isSendHex").checked;
if(hexflag && orgstr != "") {
if(orgstr.substr(0, 2) == "0x" || orgstr.substr(0, 2) == "0X") orgstr = orgstr.substring(2, orgstr.length);
if(orgstr.length % 2 != 0) orgstr = "0" + orgstr;
//alert(str2hex(orgstr));
if((newstr = str2hex(orgstr)) == "") {
alert("錯誤的16進制數");
return false;
}
}
try {
MSComm1.Output = hexflag ? newstr : orgstr;
//alert(MSComm1.Output)
} catch(ex) {
alert(ex.message);
}
}
function Receive() {
//alert("InBufferCount::" + MSComm1.InBufferCount); // 緩衝區接收的字節
document.getElementById("txtReceive").value += MSComm1.Input; //alert("InBufferCount::"+MSComm1.InBufferCount);
}
function ClearReceived() {
document.getElementById("txtReceive").innerText = "";
}
function str2hex(s) {
var a, b, d;
var hexStr = '';
for(var i = 0; i <
s.length; i++) {
d = s.charCodeAt(i);
a = d % 16;
b = (d - a) / 16;
hexStr += '%' + "0123456789ABCDEF".charAt(b) + "0123456789ABCDEF".charAt(a);
}
//alert(hexStr);
return hexStr;
}
function charCode(v) {
return String.fromCharCode(v);
}
</script>
</head>
<body>
<form name="form1">
<fieldset style="width:200px;height:250px;text-align:center;">
<legend>配置串口</legend>
<div style="float:left;width:200px">
<br/>
<span>串口號:</span>
<select name="ComName" id="ComName" style="width:75px">
<option value="1">COM1</option>
<option value="2">COM2</option>
<option value="7" selected>COM7</option>
<option value="4">COM4</option>
<option value="5">COM5</option>
<option value="9">COM9</option>
</select>
<br/>
<span>波特率:</span>
<select name="BaudRate" id="BaudRate" style="width:75px">
<option value="9600">9600</option>
<option value="57600">57600</option>
<option value="115200" selected>115200</option>
</select>
<br/>
<span>校驗位:</span>
<select name="CheckBit" id="CheckBit" style="width:75px">
<option value="N" selected>無NONE</option>
<option value="O">奇ODD</option>
<option value="E">偶EVEN</option>
</select>
<br/>
<span>數據位:</span>
<input type=text id="DataBits" name="DataBits" value=8 style="width:75px;height:20px">
<br/>
<span>停止位:</span>
<input type=text id="StopBits" name="StopBits" value=1 style="width:75px;height:20px">
<br/>
<br/>
<input type="button" id="ConfigButton" style="width:80px;height:30px;font-size:13px" name="ConfigButton" value="配置串口" onClick="ConfigPort()">
<input type="button" id="OperateButton" style="width:80px;height:30px;font-size:13px" name="OperateButton" value="打開串口" onClick="OperatePort()">
</div>
</fieldset>
<fieldset style="width:200px;height:250px;text-align:center;">
<legend>發送區域</legend>
<div style="float:left;">
<textarea id="txtSend" name="txtSend" style="width:200px;height:160px"></textarea>
<br/>
<span><input id="isSendHex" name="isSendHex" type="checkbox" />16進制</span>
<input type="button" id="SendButton" style="width:100px;height:30px" name="SendButton" value="發送" onClick="Send()">
</div>
</fieldset>
<fieldset style="width:200px;height:250px;text-align:center;">
<legend>接收區域</legend>
<div style="float:left;">
<textarea id="txtReceive" READONLY=TRUE name="txtReceive" style="width:200px;height:160px"></textarea>
<br/>
<span><input id="isReceiveHex" name="isReceiveHex" type="checkbox" />16進制</span>
<input type="button" id="ClearButton" style="width:100px;height:30px" name="ClearButton" value="清空" onClick="ClearReceived()">
</div>
</fieldset>
</form>
<OBJECT id=MSComm1 CLASSID="clsid:648A5600-2C6E-101B-82B6-000000000014" codebase="MSCOMM32.OCX" type="application/x-oleobject" style="LEFT:54px;TOP:14px">
<PARAM NAME="CommPort" VALUE="3"/>
<PARAM NAME="DataBits" VALUE="8"/>
<PARAM NAME="StopBits" VALUE="1"/>
<PARAM NAME="BaudRate" VALUE="9600"/>
<PARAM NAME="Settings" VALUE="9600,N,8,1"/>
<PARAM NAME="RTSEnable" VALUE="1"/>
<PARAM NAME="DTREnable" VALUE="1"/>
<PARAM NAME="Handshaking" VALUE="0"/>
<PARAM NAME="NullDiscard" VALUE="0"/>
<PARAM NAME="ParityReplace" VALUE="?"/>
<PARAM NAME="EOFEnable" VALUE="0"/>
<PARAM NAME="InputMode" VALUE="0"/>
<PARAM NAME="InBufferSize" VALUE="1024"/>
<PARAM NAME="InputLen" VALUE="0"/>
<PARAM NAME="OutBufferSize" VALUE="512"/>
<PARAM NAME="SThreshold" VALUE="0"/>
<PARAM NAME="RThreshold" VALUE="1"/>
</OBJECT>
</body>
</html>