如何用Node.js向RabbitMQ云端发送视频?队列创建后为空
问题描述
使用Node.js向RabbitMQ云端发送普通文本消息可正常运行,但发送视频文件时,虽成功创建新队列,队列却显示为空。相关代码如下:
import {Router} from 'express'; let router = Router(); import env from 'dotenv'; import amqp from 'amqplib'; import fs from 'fs'; env.config(); const videoData = fs.readFileSync('test/venice.mp4'); async function sendMessageToQueue(queueName, message) { try { // Connect to RabbitMQ const connection = await amqp.connect(process.env.RABBITMQ_URL); const channel = await connection.createChannel(); // Assert a queue to ensure it exists await channel.assertQueue(queueName, { durable: true }); // Send a message to the queue channel.sendToQueue(queueName, Buffer.from(message), {persistent: true}); console.log(`Sent message to queue ${queueName}: ${'message'}`); // Close the connection and channel await channel.close(); await connection.close(); } catch (error) { console.error('Error sending message to queue:', error); } } router.get('/hello',async (req,res)=>{ res.send(`lets send`); sendMessageToQueue('venice', videoData); });

问题排查与解决方案
核心问题:消息未完成发送即断开连接
sendToQueue是异步操作,视频文件体积较大时,客户端需要时间将数据推送到RabbitMQ服务器。你在调用sendToQueue后立刻关闭通道和连接,导致消息还未完成投递就被中断,最终队列无数据。
修复步骤
开启消息确认机制
启用通道的confirm模式,确保消息成功投递到RabbitMQ后再关闭连接:async function sendMessageToQueue(queueName, message) { try { const connection = await amqp.connect(process.env.RABBITMQ_URL); const channel = await connection.createChannel(); // 开启confirm模式,等待服务器确认消息投递 await channel.confirmSelect(); await channel.assertQueue(queueName, { durable: true }); channel.sendToQueue(queueName, Buffer.from(message), {persistent: true}); // 等待服务器返回确认 await channel.waitForConfirms(); console.log(`消息已成功发送到队列 ${queueName}`); await channel.close(); await connection.close(); } catch (error) { console.error('发送消息到队列失败:', error); } }验证文件读取有效性
确认视频文件被正确读取,添加日志检查文件大小:const videoData = fs.readFileSync('test/venice.mp4'); console.log('读取的视频文件字节数:', videoData.length); // 若输出为0则说明文件读取失败检查RabbitMQ消息大小限制
RabbitMQ默认消息大小上限为128MB,若视频文件超出此限制,需修改RabbitMQ配置中的frame_max参数,或对视频文件进行分片后再发送。路由中等待异步任务完成
在Express路由内调用发送函数时添加await,避免请求结束后进程提前终止:router.get('/hello',async (req,res)=>{ res.send(`lets send`); await sendMessageToQueue('venice', videoData); });
内容的提问来源于stack exchange,提问作者Aviato
相关产品推荐
相关产品推荐

