2016-10-26 83 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,由于它尚未连接而起作用。