2016-10-26 119 views
1

我正在構建一個node.js &表示通過TCP連接到物聯網設備的應用程序。在應用程序的索引頁面上,我正在渲染頁面並運行開始ping設備的功能。最終設備響應,我打開一個TCP套接字,然後使用socket.io向前端發送一個事件。這個過程比渲染頁面所用的時間要長得多。頁面刷新後保存TCP套接字(連接)的狀態

當我刷新頁面時,我不想重新ping設備。我需要「保存」連接的狀態。知道設備已連接,我不需要重新運行我的連接功能。

可能的解決方案。我的想法:

  1. TCP套接字狀態的布爾變量。在node.js網絡文檔中,我沒有看到套接字連接狀態的變量。另一個stackoverflow答案說._connected沒有記錄,可以工作,但'這不是node.js的方式'。

  2. 會議。我可以在會話中保存設備狀態,並在重新加載時對其進行跟蹤。但是,根據我的閱讀,我無法在調用res.render之後保存會話信息。我特別想在重新加載後保存連接狀態

  3. 使用局部變量。然而,這是頁面加載時的「重置」。

  4. 將狀態保存在JSON文件中。使用帶有狀態信息的單獨deviceState.js文件。我可以導出該文件並將其用作索引頁中的必需模塊。

我的問題是 - 我怎麼可以保存,即使重新加載頁面的設備連接的狀態?我的預感是有一些會話和局部變量的組合,但我不確定這些如何工作基於我上面的觀點。

下面是索引路線的簡化版本。讓我知道,如果它缺少任何有助於解決此問題的東西:

router.get('/', function(req, res, next) { 
    function connectToDevice() { 
     // ping device and open TCP socket... 
     // eventually the following function is called as an eventlistener to 
     // a net socket.on('connect')... 
     function onConnect(socket) { 
      res.io.emit('machine-online'); 
     } 
    } 
    connectToDevice(); 
    res.render('index', { 
     title: 'Page title' 
    }); 
} 

這是我第一次發佈在stackoverflow上。我仍然在學習相關的關鍵詞,並一直無法找到解決這個問題的辦法。

+0

我會使用一個會話,你確定'res.render'的事實嗎?你有沒有嘗試過?在任何情況下,我認爲如果頁面掛起服務器的答案,然後讓'res.render'執行,您可以使用promises進行同步調用。 – Marcs

+0

不可接受掛起https://github.com/expressjs/session「如果會話數據已被更改,則會在HTTP響應結束時自動調用此方法[session.save()](儘管可以更改此行爲在中間件構造函數中有各種選項)因此,通常不需要調用這個方法,在某些情況下,調用此方法很有用,例如,長期請求或WebSocket。因爲我已經給出了響應(res.render),所以會話被自動保存。我不確定是否可以明確再次保存會話信息,請試試 – user25449

回答

0

我解決這個問題的方式是#4,在外部JSON中保存狀態。

deviceStatus.js:文件位於應用程序結構的根部,該結構在JSON對象中包含一些信息。

var status = {}; 
var deviceStatus; 

deviceStatus = function() { 
    status = { 
     "isOnline": false, 
     }; 
    return status; 
}; 

module.exports = deviceStatus(); 

然後在我的index.js中:需要deviceStatus模塊。

var status = require('../deviceStatus'); 

而且我用這來渲染頁面:在(未顯示)connectToDevice()函數,我設置status.isOnline ==真。所以在這裏,如果設備處於脫機狀態,那麼我會連接並呈現頁面。如果沒有,只渲染頁面,不要連接。

if(status.isOnline == false) { 
     connectToDevice(); 
    } 
res.render('index', { 
    title: 'Page title', 
    machineOnline: status.isOnline 
}); 

可能有更好的方法來做到這一點,但這是對我有用的方法。當應用程序重新加載狀態。isOnline開始爲false,由於它尚未連接而起作用。