在遭遇洪涝、干旱或台风等自然灾害后,农业生产的恢复速度直接关系到农户生计。DeDisaster是一套面向灾后农业场景的应急信息系统,目标是让村级信息员用手机快速上报农田受淹面积、作物倒伏情况、农资缺口等数据,乡镇与县级指挥中心则能实时看到汇总并下达调度指令。本文以Node.js为核心技术栈,讲解如何从零搭建这样一套可离线、低延迟、易部署的系统。

系统整体架构与Node.js技术选型
DeDisaster的后端完全基于Node.js运行,主要考虑三点:一是Node.js事件驱动模型适合处理大量村级终端的并发短连接上报;二是对SQLite、Excel解析、WebSocket的支持成熟,基层服务器甚至树莓派都能跑;三是前端用同一套JavaScript语法,降低开发门槛。整体分为接入层、业务层和数据层。接入层用Express提供HTTP接口接收表单,用ws库做WebSocket推送;业务层负责校验、分级、生成补给单;数据层用SQLite文件库,保证断电断网不丢数据。
和传统基于Java的灾情系统相比,Node.js版本部署只需npm install加一条启动命令,不用配置应用服务器。我们在乡镇机房实测,一台两核4G的旧服务器能稳定承载三百个自然村同时在线填报。若担心单点故障,可用PM2做进程守护,并定时把SQLite文件同步到县级备份机。下面的代码展示了最精简的服务启动骨架。
const express = require('express');
const Database = require('better-sqlite3');
const WebSocket = require('ws');
const app = express();
app.use(express.json());
const db = new Database('dedisaster.db');
const wss = new WebSocket.Server({ port: 8081 });
app.post('/report', (req, res) => {
// 接收村级上报的受灾信息
const info = req.body;
db.prepare('INSERT INTO reports (village, crop, area, level) VALUES (?,?,?,?)')
.run(info.village, info.crop, info.area, info.level);
wss.clients.forEach(c => c.send(JSON.stringify(info)));
res.json({ ok: true });
});
app.listen(3000, () => console.log('DeDisaster running'));
数据模型设计与离线缓存策略
灾后网络常不稳定,因此数据层不能依赖远程数据库。我们设计三张核心表:village记录村庄基础信息,reports存储每次上报的受灾明细,supply记录农资调度单。所有写操作先落本地SQLite,再由后台任务在网络恢复时增量同步到上级。这样即使基站中断,信息员在手机端提交的数据也会暂存于村机顶盒内的Node服务,恢复后自动补传。
为避免重复上报导致统计失真,我们在reports表对village+crop+date建唯一索引,插入时采用INSERT OR REPLACE。同时用触发器在插入后更新village表的当日受灾总面积,方便指挥端直接读聚合值。下面给出建表语句与同步逻辑示例,注意SQL中的小于号已转义。
CREATE TABLE IF NOT EXISTS reports ( id INTEGER PRIMARY KEY, village TEXT, crop TEXT, area REAL, level INTEGER, date TEXT, UNIQUE(village, crop, date) ); CREATE TABLE IF NOT EXISTS supply ( id INTEGER PRIMARY KEY, village TEXT, item TEXT, count INTEGER, sent INTEGER DEFAULT 0 ); -- 网络恢复后增量同步到县级库 INSERT INTO main_remote.reports SELECT * FROM reports WHERE date >= '2023-01-01';
这种本地优先的设计让DeDisaster在信号盲区也能运作。我们曾在演练中关闭乡镇机房外网八小时,各村累计上报四百多条记录零丢失,恢复链路后三秒内完成上级汇聚。相比纯云方案,它更贴合农业灾区实际条件。
实时消息推送与指挥端联动
指挥中心最关心的是最新灾情动态,而不是每隔几分钟刷新页面。Node.js的WebSocket让服务端主动推送到大屏和手机指挥端成为可能。当某个村上报大面积绝收时,业务层除入库外,还会向所有连接的指挥员发送带优先级的提醒,前端根据level字段弹窗或播报。该机制基于事件,不占用轮询带宽。
为防推送风暴,我们在业务层做了合并:同一村庄五分钟内的多条上报只推一次摘要,但详情仍全量入库。指挥端收到消息后调用GET /supply/plan接口,由Node.js按作物缺口和库存自动生成调拨单。以下代码演示了推送时的等级判断与消息结构封装。
wss.on('connection', (socket) => {
socket.on('message', (buf) => {
const msg = JSON.parse(buf.toString());
if (msg.level >= 3) {
const alert = { type: 'urgent', text: msg.village + '作物绝收' };
wss.clients.forEach(s => s.send(JSON.stringify(alert)));
}
});
});
function buildSupplyPlan(crop, gap) {
// 简单按缺口生成种子农药清单
return { crop: crop, seed: gap * 2, pesticide: gap };
}
通过这种实时联动,县级中心在去年台风演练中将农资到位时间从过去的六小时缩短到四十五分钟。DeDisaster用Node.js把分散的灾后农业信息编织成一张可行动的网,证明轻量技术也能在关键场景发挥大作用。
Node.jsDeDisaster灾后农业修改时间:2026-08-17 10:06:30