system: [SYSTEM]

user: 3. 服务器设计 Node.js(简称Node)是一个建立在Chrome的V8 JavaScript引擎的服务器平台。Node使用单线程、事件驱动、非阻塞I/O来处理请求。相对于ASP.NET、PHP等常见的服务器实现工具，Node更加轻量，数据处理效率更高 [ 2 ] 。Node不需要依赖额外的服务器软件或运行库，对于独立且小型的智能地暖系统来说，Node无疑是更好的选择。 Node有良好的开发生态和丰富的功能模块，给开发带来很多便利。Express.js (简称Express)就是一个被广泛使用的HTTP服务器框架。利用Express可快速构建HTTP网站，且更好地实现URL路由管理， 图1. 家庭智能地暖系统结构 提高代码重用率和开发效率 [ 3 ] 。 3.1. 服务器结构 本地局域网中，服务器与嵌入式控制终端(下面简称终端)建立TCP网络连接，向终端采集温控器的数据信息。服务器同时接入互联网中，处在远端的客户机可与之进行连接。客户机成功登录服务器后，可查询服务器上保存的温控器数据；并可发出控制指令，由服务器转达给终端以实现控制操作。服务器结构如图2所示。 服务器主要由五个部分组成： 1) 基于Express框架的HTTP服务器。客户机上的客户端或web页面将从HTTP服务器获取相关的应用服务。HTTP服务器负责处理客户机请求，并作出响应。客户端和web页面的请求URL路径由APP路由和WEB路由分别进行管理； 2) 应用服务接口。它为HTTP服务器提供应用服务的接口调用，负责处理由HTTP服务器获取的客户机请求指令，实现用户管理、信息监控等业务逻辑； 3) 嵌入式接口。该接口负责与局域网中的终端建立网络连接，与之进行数据交互。它负责把从终端采集的数据直接记录到数据库中，并能封装应用服务接口发出的控制指令进而发送给终端； 4) 本地数据管理模块。它对用户、设备进行记录和管理，并对外提供数据管理接口； 5) 文件系统。文件系统保存数据库文件、web页面所需要的HTML页面及JavaScript脚本等文件。 3.2. 与客户机通信 服务器与客户机间使用HTTP协议(超文本传输协议)进行通信。HTTP是互联网中使用最广泛的网络通信协议，一般是被用来传输HTML页面或实现页面与服务器间的通信。然而在本文中，客户端与服务器的通信也应用HTTP协议进行通信。 现在，无论是客户端还是web应用，客户机与服务器之间的通信都是基于HTTP协议的，在服务器看来二者几乎没有任何区别。开发过程中，两个模式下的通信实现有大量可重用的代码；运行时，服务器能以几乎相同的方式处理客户端和web页面的请求。 HTTP通信中主要使用GET和POST方法。GET用于从服务器获取数据，POST则是向服务器发送数据。无论使用任何方法，HTTP报文中都会含有一个唯一的cookie，每个cookie对应于一个session (会话)。服务器使用session保存与客户机通信的相关信息，并利用会话技术，对以不同模式下的客户机通信进行统一管理。 举个例子，当一个用户成功登录后，服务器从数据库中将该用户的权限等信息记录到session中。接 图2. 服务器软件结构图 着，服务器每接受到用户请求，都会从session数据中获取该用户的权限，判断请求合法性并进行处理。如果不使用session技术，每次信息匹配都要进行数据库读写，极大降低处理效率。除此以外，利用session技术还可实现用户登录管理(避免帐号重复登录)、会话超时、控制权分配(避免操作冲突，详见3.6)等功能。 虽然，在C/S模式与B/S模式下都使用HTTP通信，意图将二者的通信实现的差异减到最小，但二者还是有差别的，具体体现在web应用拥有更多的管理配置功能(在web页面容易进行较繁琐的配置操作，移动客户端更适合实现简易监控功能，详见3.6)。为此二者利用URL(统一资源定位器)进行区分。B/S模式的URL路径是以“/”为前缀，而C/S模式则是以“/app”为前缀。基本URL结构如图3所示。 3.3. 与嵌入式控制终端通信 服务器与局域网中的终端建立TCP网络通信。利用Node中的net模块，可以轻松TCP实现TCP网络通信。 实际上，终端上运行TCP Server，而服务器则使用TCP Socket与终端上的TCP Server进行通信连接。嵌入式控制终端是整个家庭智能地暖系统的核心部分，即便远程监控服务器崩溃了，嵌入式控制终端也要确保能够正常运行。况且，地暖系统运行信息数据都需要经过终端处理。所以从逻辑上看，嵌入式控制终端在整个智家庭能地暖系统的局域网中应当以主服务器的形式存在。 由于篇幅有限，服务器与嵌入式控制终端通信的协议不在这里进行详细说明。要说明的是，协议的解析与封装全部由嵌入式接口实现。嵌入式接口所有的控制终端指令封装成函数，对外提供应用接口调用。而如何使用这些应用调用，则是有应用服务接口决定。应用服务器接口属于业务逻辑层，嵌入式接口与本地数据库模块则同属数据访问层，服务于业务逻辑层。 3.4. 数据库设计 服务器数据库使用的是MongoDB，它是一种非关系型的开源数据库，拥有快速的数据库读写速度 [ 4 ] 。并使用基于Node的Mongoose模块作为MongoDB数据库管理接口，以提高开发效率。 MongoDB的数据模型可以JSON格式表示，数据中的每条记录以文档形式保存，文档中可以嵌套其他文档或数组，每个文档则基于特定数据模型实现。为了方便说明，简单列出两个主要的数据模型。 图3. URL路由结构 设备模型： { deviceID: Number， // 设备ID type: String， // 设备类型 status: { // 状态 parameter:[ ]， // 运行参数 … } } 房间模型： { roomID: Number， // 房间ID name: String， // 房间名 devices: [deviceSchema] } // 设备列表，保存设备模型文档 每个房间模型中有一个“devices”的键，它的键值是一个数组，数组中保存设备模型的对象。这在逻辑上很好理解，系统中有多个房间，房间在数据库中以文档形式表现；而每个房间里又有多个设备，这些设备以设备模型的形式存在，其对象被保存在每个房间文档的devices数组中。 相比关系型数据库，MongoDB中的数据结构更为紧凑灵活，逻辑上更为简单直接，与Javascript的对象非常相似，在Node服务器中使用显得非常合适。 设备模型保存设备的型号、运行信息等内容。房间模型保存房间号、设备组等内容。此外还有用户模型，用来保存用户信息。 3.5. 服务器安全 服务器将接入互联网，如果服务器遭入侵，系统就会被非法控制，可能造成不良后果，因此服务器安全问题不可忽视。针对以下安全隐患采取相应的防范措施。 1) 用户信息安全。在登录页面和用户创建页面采用md5对用户密码进行编码，防止用户密码明文在传输途中被截取，服务器端用户密码保存的是md5的编码结果而明文，以防止服务器端的密码泄露； 2) CSRF (Cross-site request forgery，跨站请求伪造)。被攻击者盗用身份(如管理员权限)，对服务器数据非法修改。要防御这类攻击，首先要将能够修改数据请求都改为使用POST (因为伪造GET请求只需要简单的URL路径连接，而POST则需要借助JavaScript实现)方式。服务器给每个成功登录的客户机分配一个数字令牌，当客户机发出指令请求时，需要将这个数字令牌回发，服务器对其进行验证。 除此以外，还有对DoS攻击、XSS攻击等多种安全隐患的预防，在此不一一列举。 3.6. 管理策略 服务器需要按照一个良好有效的管理策略对用户和设备进行管理，以正确处理运行过程中可能发生的冲突。下面是本文所遵循管理策略： 1) 系统中有且只有一个管理员账号，该帐号拥有最高权限，可以登记房间设备、增减用户、更改用户权限等； 2) 同一帐号不允许在同一时刻重复登录； 3) 用户权限分为管理员权限(只有一个)、监控权限、查询权限(只能查询不能控制)； 4) 首先登录系统的拥有监控权限的用户会获取系统控制权(类似于互斥锁)，在该用户登出前，其他用户无法获取系统控制权，只能够查询系统运行信息； 根据所制定的管理策略，服务器可以限定用户权限，让服务器的房间设备配置稳定而不会被随意更改；系统控制权可以很好的规避冲突操作，并尽可能降低对用户访问的影响。