×
您的位置: 首页 > 编程笔记

NodeJs+WebSocket 实现串口实时通信

Node.js WebSocket SerialPort 时间:2019-08-03  查看:1383   收藏

前言:最近这两天在研究如何实现web页面和串口间通信,在网上也查了各种资料,electron、nw或者chrome serial,发现对于我来说都太难实现了,一来可用的资料太少,二来安装东西老是出问题,算了还是放弃吧,自己用常用且最熟悉的方式来实现吧,作为一名前端码农,选用的肯定是node作为服务器了,然后网页请求方式用ajax或websocket都可以,实现方式下文都有。
先说说基本需求:硬件:usb插口的led蜂鸣器(就一个单片机),有红黄蓝三种灯,通过下发相应的指令,实现亮相应的登或者响起蜂鸣器

一.  node下先跑通

1) 安装serialport

npm install serialport

2)新建server.js文件

var SerialPort = require('serialport')//Opening a Portvar serialPort = new SerialPort('COM4', {//波特率,可在设备管理器中对应端口的属性中查看baudRate : 9600,
    autoOpen:false})//连接串口后进行写入指令操作serialPort.open(function (err) {console.log('IsOpen:',serialPort.isOpen)
    console.log('err:',err)if(!err){//16进制Buffer流const buf1 = new Buffer("01050000ff008C3A","hex") //打开红灯const buf11 = new Buffer("010500000000CDCA","hex") //关闭红灯const buf2 = new Buffer("01050001f000D80A","hex") //打开黄灯const buf21 = new Buffer("0105000100009C0A","hex") //关闭黄灯const buf3 = new Buffer("01050002f000280A","hex") //打开绿灯const buf31 = new Buffer("0105000200006C0A","hex") //关闭绿灯const bufs = [buf1,buf2,buf3]// const bufs = [buf11,buf21,buf31]var i = 0eachWrite(bufs[i])function eachWrite(item) {console.log(item)
            serialPort.write(item, function (error, result) {i++if(i>=bufs.length)return//指令是一条一条下发的setTimeout(function () {eachWrite(bufs[i])
                },40)
            })
        }
    }
})//指令监听serialPort.on('data',function (data) {console.log('data received: '+data)
})//错误监听serialPort.on('error',function (error) {console.log('error: '+error)
})//获取端口列表SerialPort.list(function (error, ports) {ports.forEach(function(port) {console.log(port.comName);
        console.log(port.pnpId);
        console.log(port.manufacturer);
    });
})

3)执行代码

node server.js

4)运行代码 最终结果
这里写图片描述

二. websocket方式

1) 安装nodejs-websocket

npm install nodejs-websocket

2)新建文件websocket.js

var ws=require('nodejs-websocket');var SerialPort = require('serialport')var server = ws.createServer(function (conn, res) {conn.on("text",function(str){broadcast(server,str.split(','));
        server.emit('my other event', { my: 'data' });
    });
    conn.on("close",function(code,reason){console.log('connection closed');
    })//处理错误事件信息conn.on('error',function(err){console.log('throw err',err);
    })
}).listen(5000);/*
**指令下发
* msg:string ;  eg: '01050000ff008C3A,01050001f000D80A'
* server:socket server
* */function broadcast(server, msg) {var recData = [];
    msg.map(function (item, index) {//发送数据到客户端server.connections.forEach(function (conn) {conn.sendText(item);
        })//16进制Buffer流const str = new Buffer(item,"hex")
        recData.push(str)
    })var i = 0eachWrite(recData[i])function eachWrite(item) {serialPort.write(item, function (error, result) {i++if(i>=recData.length)return//指令是一条一条下发的setTimeout(function () {eachWrite(recData[i])
            },40)
        })
    }

}//Opening a Portvar serialPort = new SerialPort('COM4', {
    baudRate : 9600,
    autoOpen:false})//连接串口serialPort.open(function (err) {console.log('IsOpen:',serialPort.isOpen)
})//指令监听serialPort.on('data',function (data) {console.log('data received: '+data)
})//错误监听serialPort.on('error',function (error) {console.log('error: '+error)
})//获取端口列表SerialPort.list(function (error, ports) {ports.forEach(function(port) {console.log(port.comName);
        console.log(port.pnpId);
        console.log(port.manufacturer);
    });
})

3)新建html文件,index.html

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>form{margin: 30px auto;width: 35%;}</style></head><body><br><form class="form"><fieldset><legend>wobsocket 控制</legend><br><br><div><input type="button" onclick="clickDend('01050000ff008C3A,01050001f000D80A')" value="红黄灯"><input type="button" onclick="clickDend('01050001f000D80A')" value="黄灯"><input type="button" onclick="clickDend('01050002f000280A')" value="绿灯"><input type="button" onclick="clickDend('01050003f300793A')" value="蜂鸣器"><input type="button" onclick="clickDend('0105000300003DCA')" value="关闭蜂鸣器"><input type="button" onclick="clickDend('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA')" value="关闭所有"></div><br><ul id="content"></ul><input type="text" placeholder="请输入发送的消息" class="message" id="message"/><input type="button" value="发送" id="send" class="connect"/><input type="button" value="连接" id="connect" class="connect"/></fieldset></form><script>var oUl=document.getElementById('content');var oConnect=document.getElementById('connect');var oSend=document.getElementById('send');var oInput=document.getElementById('message');var ws=null;
    oConnect.οnclick=function(){ws=new WebSocket('ws://localhost:5000');
        ws.onopen=function(){oUl.innerHTML+="<li>客户端已连接</li>";
        }
        ws.onmessage=function(evt){oUl.innerHTML+="<li>"+evt.data+"</li>";
        }
        ws.onclose=function(){oUl.innerHTML+="<li>客户端已断开连接</li>";
        };
        ws.οnerrοr=function(evt){oUl.innerHTML+="<li>"+evt.data+"</li>";

        };
    };
    oSend.οnclick=function(){if(ws){
            ws.send(oInput.value);
        }
    }function clickDend(val){console.log(val)if(ws){//            ws.send('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA');ws.send(val);
        }
    }</script></body></html>

4)启动服务,执行代码

node server.js

5)运行页面
这里写图片描述

三. http方式

1) 安装express,cors

npm install express cors

2)新建http.js文件

var express = require('express')var cors = require('cors') //解决跨域var app = express();var port = process.env.PORT || 1124;var SerialPort = require('serialport')var serveStatic = require('serve-static');var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json({limit: '1mb'}));
app.use('/static',serveStatic('public'));
app.listen(port)
app.use(cors())

app.post('/ledControl/on.do',function (req,res) {const str = req.body.dataif(setContrl(str.split(','))){
        res.send({
            code:100,
            data:'开启成功!',
            message:'信息'})return}
    res.send({
        code:101,
        data:'开启失败!',
        message:'信息'})
})/*
**指令下发
* msg:string ;  eg: '01050000ff008C3A,01050001f000D80A'
* */function setContrl(msg){return new Promise(function (resolve,reject) {let recData=[];
        msg.map(function (item, index) {//16进制Buffer流const str = new Buffer(item,"hex")
            recData.push(str)
        })var i = 0eachWrite(recData[i])function eachWrite(item) {serialPort.write(item, function (error, result) {i++if(i>=recData.length){
                    resolve(true)return}//指令是一条一条下发的setTimeout(function () {eachWrite(recData[i])
                },40)
            })
        }//错误监听serialPort.on('error',function (error) {console.log('error: '+error)
            resolve(false)
        })
    })

}//Opening a Portvar serialPort = new SerialPort('COM4', {
    baudRate : 9600,
    autoOpen:false})//连接串口serialPort.open(function (err) {console.log('IsOpen:',serialPort.isOpen)
})//指令监听serialPort.on('data',function (data) {console.log('data received: '+data)
})//获取端口列表SerialPort.list(function (error, ports) {ports.forEach(function(port) {console.log(port.comName);
        console.log(port.pnpId);
        console.log(port.manufacturer);
    });
})

3)补充上面index.html文件

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>form{margin: 30px auto;width: 35%;}</style></head><body><form action=""><fieldset><legend>http控制</legend><br><br><div id="httpCtrol"><input type="button" sy-val = '01050001f000D80A' value="黄灯"><input type="button" sy-val = '01050002f000280A' value="绿灯"><input type="button" sy-val = '010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA' value="关闭所有"></div></fieldset></form><br><form class="form"><fieldset><legend>wobsocket 控制</legend><br><br><div><input type="button" onclick="clickDend('01050000ff008C3A,01050001f000D80A')" value="红黄灯"><input type="button" onclick="clickDend('01050001f000D80A')" value="黄灯"><input type="button" onclick="clickDend('01050002f000280A')" value="绿灯"><input type="button" onclick="clickDend('01050003f300793A')" value="蜂鸣器"><input type="button" onclick="clickDend('0105000300003DCA')" value="关闭蜂鸣器"><input type="button" onclick="clickDend('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA')" value="关闭所有"></div><br><ul id="content"></ul><input type="text" placeholder="请输入发送的消息" class="message" id="message"/><input type="button" value="发送" id="send" class="connect"/><input type="button" value="连接" id="connect" class="connect"/></fieldset></form><script src="jquery.min.js"></script><script>var oUl=document.getElementById('content');var oConnect=document.getElementById('connect');var oSend=document.getElementById('send');var oInput=document.getElementById('message');var ws=null;
    oConnect.οnclick=function(){ws=new WebSocket('ws://localhost:5000');
        ws.onopen=function(){oUl.innerHTML+="<li>客户端已连接</li>";
        }
        ws.onmessage=function(evt){oUl.innerHTML+="<li>"+evt.data+"</li>";
        }
        ws.onclose=function(){oUl.innerHTML+="<li>客户端已断开连接</li>";
        };
        ws.οnerrοr=function(evt){oUl.innerHTML+="<li>"+evt.data+"</li>";

        };
    };
    oSend.οnclick=function(){if(ws){
            ws.send(oInput.value);
        }
    }function clickDend(val){console.log(val)if(ws){//            ws.send('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA');ws.send(val);
        }
    }</script><script>$(function () {$('#httpCtrol input').on('click',function () {var $this = $(this)
            $.ajax({
                method:'post',
                url:'http://localhost:1124/ledControl/on.do',
                data:{data:$this.attr('sy-val')},
                success:function (res) {console.log(res)
                }
            })
        })
    })</script></body></html>

4)启动服务

node server.js

这里写图片描述

代码地址:https://github.com/kylvia/webForSerialPort.git

 

0% (0)
0% (0)