后端开发
本节介绍电机数据可视化应用案例后端开发流程。
步骤 1:创建工程
依照“Hello EdgerOS > 第一个应用”的 步骤 2 至 步骤 4 操作,新建 server 文件夹,在文件夹中创建后端 server 工程。
在创建后的 server 工程下打开 PowerShell 工具终端,输入
npm install
命令,进行依赖环境的安装。安装完成后,完整的 server 工程目录如下:说明:
本操作依赖 nvm 工具,如未安装,请按照“Hello EdgerOS > 第一个应用”的 步骤 5 的操作。
server 工程根目录 ├── assets 放置静态文件的目录,比如 logo 文件之类 ├── public 放置前端文件的目录 ├── routers 路由目录 ├── views EJS 模板 ├── .eslintrc.json ESLint 配置文件 ├── .gitignore 配置 Git 提交时忽略的文件 ├── edgeros.json EdgerOS 配置文件 ├── jsconfig.json JavaScript 项目配置文件 ├── main.js 入口文件 └── package.json 命令配置和包管理文件
步骤 2:编写 VSOA 客户端
进入步骤 1 中创建的 server 工程目录,右击工程根目录,选择新建文件选项创建 vsoa.js 文件。
在 vsoa.js 文件中编写 VSOA 客户端代码,完成与服务器连接、监听数据、控制电机等功能。
const vsoa = require('vsoa'); // 本例程 VSOA 服务端密码为'123456',因此需要设置连接密码。 const option = { passwd: '123456' }; const client = new vsoa.Client(option); let data = {}; /** * 监听连接事件 */ client.on('connect', function (info) { console.info('Connected with server:', JSON.stringify(info)); client.subscribe('/state', error => { console.log('Subscribe /state', error ? 'error' : 'OK'); }); }); /** * 监听数据事件 */ client.on('message', (url, payload) => { console.log('received event:', url, 'payload:', JSON.stringify(payload)); if (!payload.param) return; if (url == '/state') { const receivedData = payload.param; for (const key in receivedData) { data[key] = receivedData[key]; } } }); /** * 连接 VSOA 服务端 */ client.connect(`vsoa://127.0.0.1:6001`, error => { if (error) { console.warn('Connect error:', error.message); } }); /** * 控制电机 * @param {object} controlData - 控制数据 * @param {boolean} controlData.run - 控制电机启停, true 为启动, false 为停止 */ function control(controlData, successCallback, faildCallback) { client.call( '/control', { method: vsoa.method.SET }, { param: controlData }, function (error, payload) { if (error) { console.error('Command /control error:', error, 'status:', error.status); faildCallback(); } else { console.info('Command /control reply:', JSON.stringify(payload)); successCallback(); } }, 2000 ); } module.exports = { data, control };
步骤 3:向前端推送数据
右击工程根目录,选择新建文件选项创建 socket.js 文件,编写实现 WebSocket 推送数据给前端的功能,代码如下:
const io = require('socket.io'); const socketList = []; /** * 判断是否存在 websocket 连接 * @returns {boolean} */ function checkIsHasSocket() { return socketList.length > 0; } /** * 初始化 websocket * @param {object} app */ function initSocket(app) { const socketio = io(app, { serveClient: false, pingInterval: 10000, pingTimeout: 60000 }); socketio.on('connection', socket => { socketList.push(socket); console.log(`[socket] client connected, id: ${socket.id}`); }); } /** * 推送 /state * @param {object} data * @returns */ function publishState(data) { publishData('/state', data); if (!checkIsHasSocket()) { console.log(`[socket] publish /state failed, socket is not connected!`); return; } console.log(`[socket] publish /state, data: ${JSON.stringify(data)}`); socketList.forEach(socket => socket.emit(url, data)); } module.exports = { initSocket, publishState };
在工程根目录下的 main.js 中,添加如下代码,引入 socket.js 功能的调用。
const socketModule = require('./socket'); socketModule.initSocket(app);
步骤 4:编写 HTTP 接口
右击工程根目录,选择新建文件选项创建 router.js 文件。在文件中实现 vsoa.js 功能的调用,并加入前端用户获取电机数据和控制电机启停操作的 HTTP 接口,代码如下:
const Router = require('webapp').Router; const router = Router.create(); const vsoaModule = require('./vsoa'); /** * 获取电机数据 */ router.get('/state', (req, res) => { res.json(vsoaModule.data); }); /** * 控制电机 * @param {boolean} run - 控制电机启停, true 为启动, false 为停止 */ router.post('/state', (req, res) => { const run = req.body.run; vsoaModule.control( { run }, () => { res.json({ state: 'ok' }); }, () => { res.json({ state: 'faild', errorMessage: '更改失败' }); } ); }); module.exports = router;
在工程根目录下的 main.js 中,添加如下代码,引入 router.js 功能的调用。
const router = require('./router'); app.use(router);
步骤 5:后端全览工程
完整后端工程结构及代码请参考 visual_develop_server 工程示例。