Node.js中Hub75 LED矩阵Font常量被销毁致显示失效求助
问题分析与解决方案
问题根源
你看到的Destroying font日志来自rpi-led-matrix库的Font类内部,触发原因是Font实例被Node.js的垃圾回收机制回收。尽管你在全局声明了const font,但如果后续代码未持续持有对它的引用,或者库内部存在自动清理逻辑,就会导致Font被销毁。
另外,你的代码仅在初始化时给matrix设置过一次font(font),后续socket回调调用drawText时,matrix可能已丢失对Font的引用(因Font被回收),所以无法正常渲染文本。
修复步骤
1. 每次绘制前重新绑定Font
在socket回调的绘制逻辑里,每次调用drawText前都重新给matrix设置Font,避免引用丢失:
io.on('connection', (socket) => { socket.on('display_text', (text) => { console.log('Received text:', text); matrix.clear() .font(font) // 重新绑定Font实例 .fgColor(0xff0000) // 可同步重置颜色,避免状态异常 .drawText(text, 1, 1) .sync(); }); });
2. 强制保留Font实例引用
添加全局引用阻止Font被垃圾回收,确保实例始终存活:
// 创建Font实例后添加全局引用 const font = new Font('5x7', __dirname + '/node_modules/rpi-led-matrix/fonts/5x7.bdf'); global._keepFontReference = font;
3. 修复路径错误
原代码中res.sendFile('/index.html')路径缺失根目录,需修正为:
app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); });
4. 优化冗余逻辑
原POST接口/display仅做了clear和emit,未实际绘制文本,可简化或完善:
app.post('/display', (req, res) => { const text = req.body.text; matrix.clear() .font(font) .fgColor(0xff0000) .drawText(text, 1, 1) .sync(); res.send('文本已显示'); });
5. 检查库版本兼容性
确认rpi-led-matrix与Node.js 18.18的兼容性,旧版本可能在新Node.js的GC机制下异常,可尝试更新库:
npm update rpi-led-matrix
完整修复后的App.js代码
const express = require('express'); const http = require('http'); const socketIo = require('socket.io'); const { Font, LedMatrix, LedMatrixUtils } = require('rpi-led-matrix'); const app = express(); const server = http.createServer(app); const io = socketIo(server); // 矩阵配置 const matrixOptions = { ...LedMatrix.defaultMatrixOptions(), rows: 32, cols: 64, chainLength: 2, parallel: 1, brightness: 100, hardwareMapping: 'Adafruit-hat-pwm', }; // 创建Font实例并保留全局引用 const font = new Font('5x7', __dirname + '/node_modules/rpi-led-matrix/fonts/5x7.bdf'); global._keepFontReference = font; const runtimeOptions = LedMatrix.defaultRuntimeOptions(); const matrix = new LedMatrix(matrixOptions, runtimeOptions); // 初始化显示 matrix .clear() .brightness(100) .fgColor(0x00adff) .drawRect(0, 0, 63, 31) .font(font) .fgColor(0xff0000) .drawText('Hello', 1, 1) .drawText('World', 1, 8) .sync(); app.use(express.static(__dirname)); app.use(express.urlencoded({ extended: true })); app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.post('/display', (req, res) => { const text = req.body.text; matrix.clear() .font(font) .fgColor(0xff0000) .drawText(text, 1, 1) .sync(); res.send('文本已显示'); }); io.on('connection', (socket) => { socket.on('display_text', (text) => { console.log('Received text:', text); matrix.clear() .font(font) .fgColor(0xff0000) .drawText(text, 1, 1) .sync(); }); }); server.listen(8080, () => { console.log('Server is running on port 8080'); });
额外说明
Node.js的垃圾回收机制与Python不同:Python全局对象默认不会被回收,但Node.js中只要对象没有任何活跃引用(即使是全局声明),就可能被GC回收。这里的核心是确保Font实例始终有活跃引用,且每次绘制时明确绑定到matrix上。
内容的提问来源于stack exchange,提问作者Jarrett Dunn
相关产品推荐
相关产品推荐

