如何从Heroku部署的Node应用访问本地机器USB串口数据
这个问题的核心是Heroku平台的运行环境限制,无法直接通过部署在Heroku的服务读取你本地的串口数据,具体分析和解决方案如下:
问题根因
Node-Serialport库的功能是读取运行当前Node服务的机器上挂载的物理串口设备:
- 本地运行时,Node服务跑在你的个人电脑上,可正常访问电脑接入的串口硬件,所以代码运行正常
- 部署到Heroku后,服务运行在Heroku提供的虚拟云实例(dyno)中,Heroku的dyno是无硬件外设的纯虚拟化运行环境,既没有接入任何串口设备,也不支持用户外接串口硬件。调用
SerialPort.list()时,底层会因找不到对应设备节点抛出未捕获异常,直接导致进程崩溃退出,对应你日志中的H13错误(未返回响应就断开连接)和进程退出状态码1。
解决方案
根据你的业务需求,可以选择以下两种方案:
- 方案一:读取本地/现场的串口数据
不要将依赖串口操作的服务部署到公共云平台,将Express服务直接部署在可接入串口的本地机器上。如果需要外网访问该服务,可使用内网穿透工具将本地端口暴露到公网即可。也可以在本地运行单独的串口采集程序,将采集到的数据主动上报到部署在Heroku的后端服务,Heroku仅部署不涉及硬件操作的上层业务逻辑,仅处理上报的串口数据。 - 方案二:对接云端服务器的串口硬件
放弃使用Heroku平台,改用支持外接硬件外设的云服务器(如各类云厂商的ECS、轻量应用服务器,或自行托管的物理服务器),将串口硬件直接接入对应服务器后再部署你的代码即可正常运行。
代码优化建议
你当前的代码没有对串口操作做异常捕获,触发错误后会直接导致整个服务进程崩溃,可添加异常捕获逻辑避免服务直接宕机:
var express = require('express'), app = express(), bodyParser = require('body-parser'), port = process.env.PORT || 3000, cors = require('cors'); require("dotenv").config(); const SerialPort = require('serialport'); app.use(bodyParser.json()) app.use(cors({ origin: '*' })); const server = require('http').createServer(app); app.get('/port/list', async (req, res) => { try { const list = await SerialPort.list(); return res.send(list); } catch (err) { console.error('读取串口列表失败:', err); return res.status(500).send({ code: 500, msg: '读取串口列表失败', error: err.message }) } }) server.listen(port, "0.0.0.0", function () { console.log("Listening on Port " + port); });
内容的提问来源于stack exchange,提问作者Pachi
相关产品推荐
相关产品推荐

