node-webkit使用serialport,socket.io與Web通訊;node-webkit與native module

因公司業務需求,想要將電子稱的數據可以經過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

Cannot extract package

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", 不然通不過

相關文章
相關標籤/搜索