You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Node.js Socket.io串口项目迁移到Express路由的实现方法

问题分析与解决方案

你的核心问题在于Express与Socket.io的集成方式错误,以及页面缺少Socket.io客户端依赖,导致串口数据无法推送到前端页面。以下是分步修复方案:


1. 修正主app.js的Socket.io集成逻辑

Express的app并非原生HTTP服务器,Socket.io需要挂载在HTTP服务器实例上才能正常工作。同时要确保串口逻辑能获取到Socket.io的io实例来发送数据。

修改后的app.js代码:

const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const http = require('http');

const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const sensorsRouter = require('./routes/senzori');

// 创建Express应用和HTTP服务器实例
const app = express();
const server = http.createServer(app);

// 初始化Socket.io并绑定到HTTP服务器
const io = require('socket.io')(server);
// 将io实例挂载到app,方便后续路由或模块调用
app.set('io', io);

// 原有Express配置
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 挂载路由
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/senzori', sensorsRouter);

// 串口配置与数据推送逻辑(建议后续抽成单独模块)
const { SerialPort } = require('serialport');
const { ByteLengthParser } = require('@serialport/parser-byte-length');
const serialPort = new SerialPort({ path: 'COM4', baudRate: 9600 });
const parser = serialPort.pipe(new ByteLengthParser({ length: 30 }));

parser.on('data', (data) => {
  const sensorData = data.toString('UTF8');
  console.log('串口数据:', sensorData);
  // 通过Socket.io推送数据给所有连接的客户端
  io.emit('data', sensorData);
});

// 监听Socket连接状态(调试用)
io.on('connection', (socket) => {
  console.log('前端客户端已连接');
  socket.on('disconnect', () => {
    console.log('前端客户端已断开');
  });
});

// 启动HTTP服务器(必须用server.listen而非app.listen)
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

2. 修正路由文件(routes/senzori.js)

确保路由正确渲染sensors.ejs页面:

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
  // 渲染传感器页面
  res.render('sensors');
});

module.exports = router;

3. 修复sensors.ejs页面

必须引入Socket.io的客户端脚本,否则前端无法建立Socket连接:

<!-- 在页面<body>末尾添加客户端脚本 -->
<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io();
  socket.on('data', (data) => {
    console.log('收到传感器数据:', data);
    // 这里添加数据展示逻辑,比如更新页面DOM
    // 示例:document.getElementById('sensor-display').textContent = data;
  });
</script>

问题根源说明

  1. 旧代码直接使用原生http.createServer,Socket.io可直接绑定;但Express的app是封装后的实例,必须显式创建HTTP服务器才能挂载Socket.io。
  2. 你之前把串口逻辑放在路由中,无法获取到Socket.io的io实例,导致数据无法推送。
  3. 前端页面缺少Socket.io客户端脚本,无法建立WebSocket连接,自然接收不到数据。

内容的提问来源于stack exchange,提问作者Dikembe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:15:27