Angular前端如何获取Node.js采集的模拟器数据?
How to Access Modbus Data from a Node.js Script in an Angular App
我开发了一个基于Angular的前端应用,同时拥有一个从模拟器采集数据的Node.js文件。作为这类跨端连接的新手,我需要执行哪些步骤,才能在Angular应用中访问该Node.js文件中的数据?
Node.js文件代码:
var ModbusRTU = require("modbus-serial"); var client = new ModbusRTU(); client.connectTCP("127.0.0.1", { port: 502 }); client.setID(1); console.log("conected"); setInterval(function() { client.readHoldingRegisters(0, 10, function(err, data) { console.log(data.data); }); }, 1000);
嘿,作为跨端新手,这个问题其实很常见——核心是要让你的Node.js脚本从一个单纯的控制台程序变成能给Angular提供数据的API服务,因为前端没法直接读取后端的本地变量。下面是一步步的具体操作:
步骤1:把Node.js脚本改成带API的Express服务
首先,你需要用Express(Node.js最常用的Web框架)搭建一个HTTP服务器,这样Angular就能通过HTTP请求获取数据。
- 先安装必要的依赖:
npm install express cors modbus-serial
- 修改你的Node.js代码,改成这样(我用了async/await替代回调,代码更清晰):
const ModbusRTU = require("modbus-serial"); const express = require("express"); const cors = require("cors"); const app = express(); app.use(cors()); // 解决跨域问题,后面会解释 let latestModbusData = []; // 缓存最新的Modbus数据 // 初始化Modbus连接 const client = new ModbusRTU(); client.connectTCP("127.0.0.1", { port: 502 }) .then(() => { client.setID(1); console.log("Connected to Modbus simulator"); // 定时读取数据并更新缓存 setInterval(async () => { try { const data = await client.readHoldingRegisters(0, 10); latestModbusData = data.data; console.log("Updated data:", latestModbusData); } catch (err) { console.error("Error reading Modbus data:", err); } }, 1000); }) .catch(err => { console.error("Failed to connect to Modbus simulator:", err); }); // 定义API端点,供Angular获取数据 app.get("/api/modbus-data", (req, res) => { res.json(latestModbusData); }); // 启动服务器,监听3000端口 const PORT = 3000; app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); });
这里的关键改动:
- 用
latestModbusData缓存最新数据,避免每次请求都重新读取Modbus - 新增
GET /api/modbus-data接口,返回缓存的数据 - 加入
cors中间件:因为Angular默认跑在4200端口,Node跑在3000端口,浏览器会阻止跨域请求,这个中间件就是来解决这个问题的
步骤2:启动Node.js服务
运行修改后的脚本:
node your-script-name.js
你会看到控制台输出连接成功的信息,以及定时更新的数据,同时服务器在3000端口运行。
步骤3:在Angular中调用API获取数据
现在需要在Angular里写代码请求这个API。
3.1 确保HTTP客户端已配置
Angular CLI创建的项目默认已经包含HttpClientModule,如果没有,在app.module.ts里导入:
import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ // ...其他导入 HttpClientModule ] }) export class AppModule { }
3.2 创建数据服务(推荐)
用Angular服务封装HTTP请求,方便复用:
ng generate service modbus-data
修改modbus-data.service.ts:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ModbusDataService { private apiUrl = 'http://localhost:3000/api/modbus-data'; constructor(private http: HttpClient) { } getModbusData(): Observable<number[]> { return this.http.get<number[]>(this.apiUrl); } }
3.3 在组件中使用服务获取数据
比如在app.component.ts里:
import { Component, OnInit } from '@angular/core'; import { ModbusDataService } from './modbus-data.service'; import { interval } from 'rxjs'; import { switchMap } from 'rxjs/operators'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { modbusData: number[] = []; constructor(private modbusDataService: ModbusDataService) { } ngOnInit(): void { // 每隔1秒请求一次数据,和Node端的更新频率同步 interval(1000) .pipe(switchMap(() => this.modbusDataService.getModbusData())) .subscribe({ next: data => { this.modbusData = data; console.log('Received data:', this.modbusData); }, error: err => console.error('Failed to fetch data:', err) }); } }
3.4 在模板中展示数据
修改app.component.html:
<h2>Modbus Simulator Data</h2> <div *ngIf="modbusData.length > 0; else noData"> <ul> <li *ngFor="let value of modbusData; let i = index"> Register {{i + 1}}: {{value}} </li> </ul> </div> <ng-template #noData> <p>Waiting for data...</p> </ng-template>
步骤4:测试整个流程
- 确保你的Modbus模拟器在
127.0.0.1:502正常运行 - 启动Node.js服务(步骤2)
- 启动Angular应用:
ng serve
打开http://localhost:4200,你就能看到实时更新的Modbus数据了!
额外优化建议
- 用WebSocket替代HTTP轮询:如果需要更低延迟的实时数据,可以用Socket.io,让Node端主动推数据给Angular,不用前端每隔1秒请求一次
- 环境变量配置:把API URL改成Angular的环境变量,方便在开发/生产环境切换
- 数据验证:在Node端和Angular端都加入数据验证,确保返回的数据格式正确
内容的提问来源于stack exchange,提问作者IosifBulubenchi




