因公司業務需求,想要將電子稱的數據可以經過COM3端口時時的傳遞的Web頁面中。javascript
方案是寫一個客戶端程序運行接收COM3傳來的數據,同時將接收到的數據經過socket傳遞給頁面。html
本地node版本是v5.0.0,程序主入口是app.js,安裝serialport,socket.io,代碼以下:前端
var io; function ioHandle() { io = require('socket.io').listen(config.socketPort); io.on('connection', function (socket) { //監聽客戶端推送的消息事件 socket.on('connect', function () { console.log('io.connect'); }); socket.on('weight_server', function (data) { console.log('io.data : ' + data); var reg = /\d+.\d/g; var weight = data.match(reg); // 廣播給全部偵聽者 socket.broadcast.emit('weight_client', (weight.length > 0 ? weight[0] : 0)); }); socket.on('disconnect', function () { console.log('io.disconnect someone disconnect server'); }); }); io.on('error', function (err) { console.log("io.error: " + err); setTimeout(ioHandle, 1000); }); } ioHandle(); var ioClient = require("socket.io-client"); var ioConnectUrl = config.socketUrl + ':' + config.socketPort; var socketClient = ioClient.connect(ioConnectUrl); var serialport = require("serialport"); var SerialPort = serialport.SerialPort; var sp; function serialportHandle() { sp = new SerialPort("COM3", { baudrate: 9600, parser: serialport.parsers.readline("\n") }); sp.on("open", function () { console.log('sp.open'); sp.on('data', function (data) { console.log('sp.data received: ' + data); socketClient.emit('weight_server', data); }); sp.on('disconnect', function(err) { console.log('sp.disconnect'); }); sp.on('close', function() { console.log("sp.close someone close the port"); }); }); sp.on('error', function (err) { console.log("sp.error: " + err); setTimeout(serialportHandle, 2000); }); } serialportHandle(); console.log('sscom3 running, god bless love...');
前端index.html,代碼以下:java
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>電子稱應用程序</title> </head> <body > <script src="socket.io.js?v=1"></script> <h2 id="weight">目前重量:無</h2> <script> //socket client connect var url = "http://127.0.0.1:10025"; var socket = io.connect(url); //socket鏈接狀況 socket.on('connect',function(){ console.log('client.connect'); }); socket.on('error',function(){ console.log('client.connect error'); }); socket.on('disconnect',function(){ console.log('client.connect abort'); }); //自定義通知消息 socket.on('weight_client', function (data) { console.log('client.weight_client data: ' + data); document.getElementById('weight').innerHTML = '目前重量:' + data; }); </script> </body> </html>
程序用node app.js,很快也很簡單的成功執行了起來,可是。。。node
還要將其用node-webkit封裝成一個桌面應用程序,package.js內容以下:git
{ "name": "sscom3", "main": "index.html", "nodejs": "true", "node-main": "app.js", "window": { "toolbar": true, "frame": true, "width": 430, "height": 450, "resizable": true }, "webkit": { "plugin": true } }
下載 nwjs,我選擇的版本是v0.12.3,環境爲win7 x64github
將程序打包以後放入nw.exe中執行,程序報錯: web
Failed to unzip the package file: C:\Users\Administrator\Desktop\nwjs-v0.12.3-win-x64\sscom3.zipnpm
網上找了不少資料,有的說的是serialport的庫編譯有問題,要使用node-gyp 或 nw-gyp 編譯!!!!json
最後才發現這個問題是sscom3\node_modules\serialport\node_modules中有個node-pre-gyp-github致使的,直接刪除node-pre-gyp-github文件夾便可。
此問題解決以後,新問題又出現了,程序閃現,執行以後直接退出,一直找不到緣由。
通過一系列的嘗試,去掉 package.json中 "nodejs": true,"node-main": "app.js", 而後將index.html改成以下
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>電子稱應用程序</title> </head> <body style="border-top: solid 2px #ccc;margin:0;padding:0;"> <h2 id="weight" >目前重量:無</h2> <script src="app.js?v=1"></script> <script> //socket client connect var config = require('./config'); var client = require("socket.io-client"); var socketUrl = config.socketUrl + ':' + config.socketPort; var socket = client.connect(socketUrl); //socket鏈接狀況 socket.on('connect',function(){ console.log('client.connect'); }); socket.on('error',function(){ console.log('client.connect error'); }); socket.on('disconnect',function(){ console.log('client.connect abort'); }); //自定義通知消息 socket.on('weight_client', function (data) { console.log('client.weight_client data: ' + data); document.getElementById('weight').innerHTML = '目前重量:' + data + ' g'; }); </script> </body> </html>
此時程序運行不會退出了,原覺得這樣解決了問題,但鏈接上電子稱以後,頁面收不到傳來的值,查看調試器問題以下:
而後網上找解決問題方法,有兩篇文章提供瞭解決方案
http://markding.github.io/2014/11/11/make-node-webkit-works-with-serialport.html
https://github.com/nwjs/nw.js/wiki/Build-native-modules-with-nw-gyp
node-pre-gyp configure --runtime=node-webkit --target=0.12.3
node-pre-gyp build --runtime=node-webkit --target=0.12.3
使用此方法後,程序可正常運行了!
如今開始打包程序爲.exe文件,按網上教程,隨意找一篇如 http://damoqiongqiu.iteye.com/blog/2010720
copy /b nw.exe+sscom3.zip sscom3.exe
此時蛋疼的問題來了,執行後,發現sscom3.exe打開後報生成的serialport.node模塊找不到,報如上一樣的錯。
後來才發現這是nw底層代碼中對原生態C++編譯後的模塊沒法重命名致使的,若是程序命名爲nw.exe,則可成功運行
又找了很久,在網上找了一個帖子 https://github.com/nwjs/nw.js/issues/199
這個帖子已經3-4年了,近兩年才解決這個問題,方法是有個傢伙寫了一個小玩意,地址是 http://developers.ironsrc.com/rename-import-dll/
這東西用了以後,感謝 上帝,終於成功了!!!
總結,node-webkit與 node native module 兼容性真心不高,蛋疼的要命!
最後概括:
1. 安裝端口讀寫庫 npm install serialport 2. npm install node-gyp -g 3. npm install nw-gyp -g 4. 2與3操做不執行好像也能夠,最終仍是依賴與如下操做 5. npm install node-pre-gyp -g 6. 定位到端口庫中 cd node_modules\serialport 7. 執行 node-pre-gyp configure --runtime=node-webkit --target=0.12.3 8. 執行 node-pre-gyp build --runtime=node-webkit --target=0.12.3 9. 在 node_modules\serialport\build\Release中查看是否已經生成一個node-webkit-v0.12.3-win32-x64文件夾 10. 刪除 serialport\node_modules 文件夾下 node-pre-gyp-github 11. 安裝 npm install socket.io 12. 將app.js入口程序綁定到index.html中 13. 壓縮整個文件夾命名sscom3.zip放到 nwj-v0.12.3 包中 14. 定位到 nwj-v0.12.3 文件夾下 15. 執行 copy /b nw.exe+sscom3.zip sscom3.exe 16. 蛋疼的問題來了,執行15步驟以後,發現sscom3.exe打開後報生成的serialport.node模塊找不到,緣由是nw底層代碼中對原生態的C++編譯後的模塊沒法重命名,只能命名爲nw.exe 17. 針對16項目問題,網上找到一個解決方案,http://developers.ironsrc.com/rename-import-dll/,下載rid包 18. 定位到 cd node_modules\serialport\build\Release\node-webkit-v0.12.3-win32-x64 19. 先將rid.exe拷入此文件夾中,執行rid.exe serialport.node,再執行rid.exe serialport.node nw.exe sscom3.exe 20. 刪除rid.exe,從新執行13,14,15 21. 打包以後,sscom3.exe能夠成功運行 22. 使用 Enigma Virtual Box 軟件打包sscom3.exe程序 23. 點擊Add..,加入nwj-v0.12.3中ffm.pegsumo.dll,icudtl.dat,libEGL.dll,libGLESv2.dll,nw.pak,同時在Files Options中勾選Compress Files 24. 注:Enigma Virtual Box 打包以後,將打包文件的名字重命名爲sscom3.exe
注: 無需在package.json中設置 "nodejs": true,"node-main": "app.js", 不然通不過