amqplib-init 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.2] - 2026-01-24
4
+
5
+ ### 🐛 修复
6
+ - **修复 ES Module 导入**: 调整 `exports` 配置,`default` 指向 ESM 文件
7
+ - 确保 `"type": "module"` 项目能正确导入 ESM 格式
8
+
9
+ ---
10
+
11
+ ## [1.3.1] - 2026-01-24
12
+
13
+ ### 🐛 修复
14
+ - **修复发布配置**: 移除 `module/` 和 `index.js` 源码文件,只发布混淆后的 `dist/` 目录
15
+ - 确保源码不会被暴露到 npm 包中
16
+
17
+ ---
18
+
3
19
  ## [1.3.0] - 2026-01-24
4
20
 
5
21
  ### 🔥 Breaking Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amqplib-init",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "消息队列初始化 - 移除PM2依赖,改用Supervisor管理 (支持15分钟长任务)",
5
5
  "main": "dist/amqplib-init.cjs.js",
6
6
  "module": "dist/amqplib-init.esm.js",
@@ -8,15 +8,13 @@
8
8
  "types": "index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "require": "./dist/amqplib-init.cjs.js",
12
11
  "import": "./dist/amqplib-init.esm.js",
13
- "default": "./dist/amqplib-init.cjs.js"
12
+ "require": "./dist/amqplib-init.cjs.js",
13
+ "default": "./dist/amqplib-init.esm.js"
14
14
  }
15
15
  },
16
16
  "files": [
17
17
  "dist",
18
- "module",
19
- "index.js",
20
18
  "index.d.ts",
21
19
  "README.md",
22
20
  "CHANGELOG.md"
package/index.js DELETED
@@ -1,153 +0,0 @@
1
- const ConfigResolver = require('./module/ConfigResolver');
2
- const ConnectionManager = require('./module/ConnectionManager');
3
- const MessageProcessor = require('./module/MessageProcessor');
4
- const AutoReloader = require('./module/AutoReloader');
5
- const log = require('chalk-style');
6
-
7
- /**
8
- * AMQP初始化器主类
9
- * 协调各个模块完成RabbitMQ的初始化和消息处理
10
- */
11
- class AMQPInitializer {
12
- constructor() {
13
- this.configResolver = new ConfigResolver();
14
- this.connectionManager = null;
15
- this.messageProcessor = null;
16
- this.autoReloader = null;
17
- this.config = null;
18
- }
19
-
20
- /**
21
- * 初始化AMQP连接和消息处理
22
- * @param {Object} options - 配置选项
23
- * @returns {Promise<void>}
24
- */
25
- async init(options = {}) {
26
- try {
27
- // 1. 解析配置
28
- this.config = this.configResolver.resolveConfig(options);
29
- log.log('配置解析完成');
30
-
31
- // 2. 解析连接地址
32
- const amqpLink = await this.configResolver.resolveAmqpLink(
33
- this.config.amqpAutoLink,
34
- this.config.amqpLink
35
- );
36
-
37
- // 3. 初始化各个模块
38
- this.connectionManager = new ConnectionManager(this.config);
39
- this.messageProcessor = new MessageProcessor(this.config);
40
- this.autoReloader = new AutoReloader(this.config);
41
-
42
- // 4. 设置连接地址并初始化连接
43
- this.connectionManager.setAmqpLink(amqpLink);
44
- const channel = await this.connectionManager.initialize();
45
-
46
- // 5. 重新定义重连逻辑,确保重连后重新启动消息处理和自动重载
47
- this._setupReconnectHandler();
48
-
49
- // 6. 启动消息处理
50
- await this.messageProcessor.startConsuming(channel);
51
- log.log('消息处理器已启动');
52
-
53
- // 7. 启动自动重载监控
54
- this.autoReloader.start(channel);
55
-
56
- // 8. 执行初始化完成回调
57
- this.config.finish();
58
-
59
- log.log('AMQP初始化完成');
60
- } catch (error) {
61
- log.error('AMQP初始化失败:', error.message);
62
- throw error;
63
- }
64
- }
65
-
66
- /**
67
- * 设置重连处理器
68
- * 确保重连后各个模块能够正确重新启动
69
- * @private
70
- */
71
- _setupReconnectHandler() {
72
- const originalReconnect = this.connectionManager.reconnect.bind(this.connectionManager);
73
-
74
- this.connectionManager.reconnect = async () => {
75
- try {
76
- // 执行原始重连逻辑
77
- const newChannel = await originalReconnect();
78
-
79
- // 重连后重新启动消息处理
80
- this.messageProcessor.clearProcessingMessages();
81
- await this.messageProcessor.startConsuming(newChannel);
82
- log.log('重连后消息处理器已重新启动');
83
-
84
- // 重连后重新启动自动重载监控
85
- this.autoReloader.restart(newChannel);
86
- log.log('重连后自动重载监控已重新启动');
87
-
88
- return newChannel;
89
- } catch (error) {
90
- log.error('重连处理失败:', error.message);
91
- throw error;
92
- }
93
- };
94
- }
95
-
96
- /**
97
- * 获取当前状态信息
98
- * @returns {Object} 状态信息
99
- */
100
- getStatus() {
101
- return {
102
- isConnected: this.connectionManager ? this.connectionManager.isConnected() : false,
103
- processingCount: this.messageProcessor ? this.messageProcessor.getProcessingCount() : 0,
104
- autoReloaderActive: this.autoReloader ? this.autoReloader.isActive() : false,
105
- channelName: this.config ? this.config.channelName : null
106
- };
107
- }
108
-
109
- /**
110
- * 优雅关闭
111
- * @returns {Promise<void>}
112
- */
113
- async shutdown() {
114
- try {
115
- log.log('开始优雅关闭AMQP连接...');
116
-
117
- // 停止自动重载监控
118
- if (this.autoReloader) {
119
- this.autoReloader.stop();
120
- }
121
-
122
- // 清理消息处理状态
123
- if (this.messageProcessor) {
124
- this.messageProcessor.clearProcessingMessages();
125
- }
126
-
127
- // 关闭连接
128
- if (this.connectionManager) {
129
- await this.connectionManager.close();
130
- }
131
-
132
- log.log('AMQP连接已优雅关闭');
133
- } catch (error) {
134
- log.error('关闭AMQP连接时出错:', error.message);
135
- }
136
- }
137
- }
138
-
139
- // 导出兼容的API
140
- module.exports = {
141
- /**
142
- * 初始化函数 - 保持向后兼容
143
- * @param {Object} options - 配置选项
144
- * @returns {Promise<void>}
145
- */
146
- async init(options) {
147
- const initializer = new AMQPInitializer();
148
- return await initializer.init(options);
149
- },
150
-
151
- // 导出类,供需要更多控制的用户使用
152
- AMQPInitializer
153
- };
@@ -1,109 +0,0 @@
1
- const log = require('chalk-style');
2
-
3
- /**
4
- * 自动重载器模块
5
- * 负责监控队列状态(已移除 PM2 重启功能,改用 Supervisor 管理)
6
- */
7
- class AutoReloader {
8
- constructor(config) {
9
- this.config = config;
10
- this.intervalId = null;
11
- this.isRunning = false;
12
- }
13
-
14
- /**
15
- * 启动自动重载监控
16
- * @param {Object} channel - RabbitMQ频道
17
- */
18
- start(channel) {
19
- const { autoReload, channelName, queryHook } = this.config;
20
-
21
- if (autoReload <= 0) {
22
- log.log('自动重载功能未启用');
23
- return;
24
- }
25
-
26
- if (this.isRunning) {
27
- log.log('自动重载监控已在运行中');
28
- return;
29
- }
30
-
31
- this.isRunning = true;
32
- log.log(`启动队列监控,间隔: ${autoReload}ms`);
33
-
34
- this.intervalId = setInterval(async () => {
35
- try {
36
- await this._checkQueueStatus(channel, channelName, queryHook);
37
- } catch (error) {
38
- log.error('队列状态检查时出错:', error.message);
39
- }
40
- }, autoReload);
41
- }
42
-
43
- /**
44
- * 停止自动重载监控
45
- */
46
- stop() {
47
- if (this.intervalId) {
48
- clearInterval(this.intervalId);
49
- this.intervalId = null;
50
- this.isRunning = false;
51
- log.log('自动重载监控已停止');
52
- }
53
- }
54
-
55
- /**
56
- * 重启自动重载监控(用于重连后)
57
- * @param {Object} channel - 新的RabbitMQ频道
58
- */
59
- restart(channel) {
60
- this.stop();
61
- this.start(channel);
62
- }
63
-
64
- /**
65
- * 获取监控状态
66
- * @returns {boolean} 是否正在运行
67
- */
68
- isActive() {
69
- return this.isRunning;
70
- }
71
-
72
- /**
73
- * 检查队列状态(仅监控,不执行重启)
74
- * @param {Object} channel - RabbitMQ频道
75
- * @param {string} channelName - 频道名称
76
- * @param {Function} queryHook - 查询钩子函数
77
- * @private
78
- */
79
- async _checkQueueStatus(channel, channelName, queryHook) {
80
- try {
81
- // 检查队列中的消息数量
82
- const { messageCount } = await channel.checkQueue(channelName);
83
-
84
- // 执行查询钩子
85
- const hookResult = await queryHook();
86
-
87
- log.log(`队列 ${channelName} 中有 ${messageCount} 条消息,钩子状态: ${hookResult ? 1 : 0}`);
88
-
89
- // 注意: 已移除自动重启功能
90
- // 如需重启服务,请使用 Supervisor: supervisorctl restart <service-name>
91
- } catch (error) {
92
- log.error('检查队列状态时出错:', error.message);
93
- }
94
- }
95
-
96
- /**
97
- * 获取当前配置信息
98
- * @returns {Object} 配置信息
99
- */
100
- getConfig() {
101
- return {
102
- autoReload: this.config.autoReload,
103
- isRunning: this.isRunning,
104
- intervalId: this.intervalId !== null
105
- };
106
- }
107
- }
108
-
109
- module.exports = AutoReloader;
@@ -1,86 +0,0 @@
1
- const axios = require('axios');
2
- const log = require('chalk-style');
3
-
4
- /**
5
- * 配置解析器模块
6
- * 负责处理配置参数和自动获取RabbitMQ连接信息
7
- */
8
- class ConfigResolver {
9
- constructor() {
10
- this.defaultConfig = {
11
- channelName: 'node-test-channel',
12
- prefetch: 1,
13
- callback: () => {},
14
- finish: () => {},
15
- amqpLink: '',
16
- amqpAutoLink: '',
17
- heartbeat: 60, // 增加心跳间隔到60秒,避免长时间处理时连接断开
18
- timeout: 300000, // 增加连接超时到5分钟(300秒)
19
- delay: 0,
20
- autoReload: 0,
21
- queryHook: () => {},
22
- initHook: () => {},
23
- durable: true,
24
- // 新增配置项 - 支持15分钟长任务
25
- messageTimeout: 900000, // 消息处理超时15分钟(900秒)
26
- reconnectDelay: 5000, // 重连延迟5秒
27
- maxReconnectAttempts: 10 // 最大重连次数
28
- };
29
- }
30
-
31
- /**
32
- * 解析和合并配置参数
33
- * @param {Object} options - 用户传入的配置选项
34
- * @returns {Object} 合并后的完整配置
35
- */
36
- resolveConfig(options = {}) {
37
- return { ...this.defaultConfig, ...options };
38
- }
39
-
40
- /**
41
- * 自动获取RabbitMQ连接信息
42
- * @param {string} amqpAutoLink - 自动获取连接信息的HTTPS链接
43
- * @param {string} fallbackAmqpLink - 备用连接地址
44
- * @returns {Promise<string>} 最终使用的连接地址
45
- */
46
- async resolveAmqpLink(amqpAutoLink, fallbackAmqpLink) {
47
- if (!amqpAutoLink) {
48
- return fallbackAmqpLink;
49
- }
50
-
51
- try {
52
- log.log(`正在从 ${amqpAutoLink} 获取连接信息...`);
53
- const response = await axios.post(amqpAutoLink);
54
- const { info } = response.data;
55
-
56
- if (this._validateConnectionInfo(info)) {
57
- const finalAmqpLink = `amqp://${info.AMQPLIB_USER}:${info.AMQPLIB_PWD}@${info.AMQPLIB_PUB}:${info.AMQPLIB_PORT}`;
58
- log.log(`✅ 自动获取连接信息成功: ${finalAmqpLink}`);
59
- return finalAmqpLink;
60
- } else {
61
- log.error('❌ 获取的连接信息不完整,使用默认连接地址');
62
- return fallbackAmqpLink;
63
- }
64
- } catch (error) {
65
- log.error('❌ 获取连接信息失败:', error.message);
66
- log.log('使用默认连接地址继续...');
67
- return fallbackAmqpLink;
68
- }
69
- }
70
-
71
- /**
72
- * 验证连接信息的完整性
73
- * @param {Object} info - 连接信息对象
74
- * @returns {boolean} 是否包含所有必要字段
75
- * @private
76
- */
77
- _validateConnectionInfo(info) {
78
- return info &&
79
- info.AMQPLIB_USER &&
80
- info.AMQPLIB_PWD &&
81
- info.AMQPLIB_PUB &&
82
- info.AMQPLIB_PORT;
83
- }
84
- }
85
-
86
- module.exports = ConfigResolver;
@@ -1,214 +0,0 @@
1
- const amqp = require('amqplib');
2
- const log = require('chalk-style');
3
- const happy = require('happy-help');
4
-
5
- /**
6
- * 连接管理器模块
7
- * 负责RabbitMQ连接管理、重连逻辑、频道管理
8
- */
9
- class ConnectionManager {
10
- constructor(config) {
11
- this.config = config;
12
- this.connection = null;
13
- this.channel = null;
14
- this.amqpLink = '';
15
- this.reconnectInProgress = false; // 防止重复重连
16
- this.reconnectAttempts = 0; // 重连计数器
17
- this.maxReconnectAttempts = config.maxReconnectAttempts || 10; // 最大重连次数
18
- }
19
-
20
- /**
21
- * 设置AMQP连接地址
22
- * @param {string} amqpLink - RabbitMQ连接地址
23
- */
24
- setAmqpLink(amqpLink) {
25
- this.amqpLink = amqpLink;
26
- }
27
-
28
- /**
29
- * 初始化连接和频道
30
- * @returns {Promise<Object>} 返回频道对象
31
- */
32
- async initialize() {
33
- const { channelName, durable, prefetch, heartbeat, timeout, initHook, reconnectDelay } = this.config;
34
-
35
- try {
36
- // 建立连接
37
- this.connection = await amqp.connect(this.amqpLink, { heartbeat, timeout });
38
-
39
- // 创建频道
40
- this.channel = await this.connection.createChannel();
41
-
42
- // 设置队列和预取
43
- await this.channel.assertQueue(channelName, { durable });
44
- await this.channel.prefetch(prefetch);
45
-
46
- // 执行初始化钩子
47
- await initHook({ channel: this.channel, connection: this.connection });
48
-
49
- log.log(`已连接到RabbitMQ,频道: ${channelName}`);
50
-
51
- // 设置连接事件监听
52
- this._setupConnectionEvents();
53
-
54
- return this.channel;
55
- } catch (error) {
56
- log.error('初始化RabbitMQ连接时出错:', error);
57
- throw error;
58
- }
59
- }
60
-
61
- /**
62
- * 重连逻辑
63
- * @returns {Promise<Object>} 返回新的频道对象
64
- */
65
- async reconnect() {
66
- if (this.reconnectInProgress) {
67
- log.log('重连已在进行中,跳过此次重连请求');
68
- return this.channel;
69
- }
70
-
71
- // 检查是否达到最大重连次数
72
- if (this.reconnectAttempts >= this.maxReconnectAttempts) {
73
- log.error(`❌ 已达到最大重连次数 ${this.maxReconnectAttempts},停止重连`);
74
- log.error('请检查 RabbitMQ 服务状态或网络连接');
75
- return null;
76
- }
77
-
78
- this.reconnectInProgress = true;
79
- this.reconnectAttempts++;
80
-
81
- try {
82
- log.error(`🔄 连接丢失,正在尝试第 ${this.reconnectAttempts}/${this.maxReconnectAttempts} 次重连...`);
83
-
84
- // 清理旧的channel状态
85
- await this._cleanupOldChannel();
86
-
87
- // 等待重连间隔,使用配置的延迟时间
88
- const delaySeconds = (this.config.reconnectDelay || 5000) / 1000;
89
- await happy.sleep(delaySeconds);
90
-
91
- // 重新初始化连接
92
- await this.initialize();
93
-
94
- // 重连成功,重置计数器
95
- this.reconnectAttempts = 0;
96
- log.log(`✅ 已重新连接到RabbitMQ,频道: ${this.config.channelName}`);
97
-
98
- return this.channel;
99
- } catch (error) {
100
- log.error(`❌ 第 ${this.reconnectAttempts} 次重连失败:`, error.message);
101
-
102
- // 如果未达到最大次数,继续重试
103
- if (this.reconnectAttempts < this.maxReconnectAttempts) {
104
- const retryDelay = this.config.reconnectDelay || 5000;
105
- setTimeout(() => {
106
- this.reconnectInProgress = false;
107
- this.reconnect();
108
- }, retryDelay);
109
- } else {
110
- log.error('❌ 已达到最大重连次数,停止重连');
111
- }
112
-
113
- throw error;
114
- } finally {
115
- this.reconnectInProgress = false;
116
- }
117
- }
118
-
119
- /**
120
- * 获取当前频道
121
- * @returns {Object|null} 当前频道对象
122
- */
123
- getChannel() {
124
- return this.channel;
125
- }
126
-
127
- /**
128
- * 获取当前连接
129
- * @returns {Object|null} 当前连接对象
130
- */
131
- getConnection() {
132
- return this.connection;
133
- }
134
-
135
- /**
136
- * 检查连接是否正常
137
- * @returns {boolean} 连接状态
138
- */
139
- isConnected() {
140
- return this.connection && this.channel && !this.connection.connection.destroyed;
141
- }
142
-
143
- /**
144
- * 关闭连接
145
- * @returns {Promise<void>}
146
- */
147
- async close() {
148
- try {
149
- if (this.channel) {
150
- await this.channel.close();
151
- this.channel = null;
152
- }
153
- if (this.connection) {
154
- await this.connection.close();
155
- this.connection = null;
156
- }
157
- log.log('RabbitMQ连接已关闭');
158
- } catch (error) {
159
- log.error('关闭连接时出错:', error.message);
160
- }
161
- }
162
-
163
- /**
164
- * 设置连接事件监听
165
- * @private
166
- */
167
- _setupConnectionEvents() {
168
- // 连接错误处理
169
- this.connection.on('error', (err) => {
170
- log.error('连接错误:', err.message);
171
- this.reconnect().catch(error => {
172
- log.error('重连失败:', error.message);
173
- });
174
- });
175
-
176
- // 连接关闭处理
177
- this.connection.on('close', () => {
178
- log.error('与RabbitMQ的连接已关闭');
179
- this.reconnect().catch(error => {
180
- log.error('重连失败:', error.message);
181
- });
182
- });
183
- }
184
-
185
- /**
186
- * 清理旧的频道状态
187
- * @private
188
- */
189
- async _cleanupOldChannel() {
190
- if (this.channel) {
191
- try {
192
- await this.channel.close();
193
- } catch (e) {
194
- log.log('关闭旧channel时出错:', e.message);
195
- }
196
- this.channel = null;
197
- }
198
- }
199
-
200
- /**
201
- * 获取连接统计信息
202
- * @returns {Object} 连接统计
203
- */
204
- getStats() {
205
- return {
206
- isConnected: this.isConnected(),
207
- reconnectAttempts: this.reconnectAttempts,
208
- maxReconnectAttempts: this.maxReconnectAttempts,
209
- reconnectInProgress: this.reconnectInProgress
210
- };
211
- }
212
- }
213
-
214
- module.exports = ConnectionManager;
@@ -1,203 +0,0 @@
1
- const log = require('chalk-style');
2
- const happy = require('happy-help');
3
-
4
- /**
5
- * 消息处理器模块
6
- * 负责消息处理、状态跟踪、ACK/REJECT逻辑
7
- */
8
- class MessageProcessor {
9
- constructor(config) {
10
- this.config = config;
11
- this.processingMessages = new Set(); // 跟踪正在处理的消息
12
- }
13
-
14
- /**
15
- * 开始消费消息
16
- * @param {Object} channel - RabbitMQ频道
17
- * @returns {Promise<Function>} 返回清理函数
18
- */
19
- async startConsuming(channel) {
20
- const { channelName, callback, delay } = this.config;
21
-
22
- log.log(`开始消费: ${channelName}`);
23
-
24
- await channel.consume(channelName, async (msg) => {
25
- if (msg !== null) {
26
- await this._handleMessage(msg, channel, callback, delay);
27
- } else {
28
- // ✅ 修复关键bug:null消息不需要ACK操作
29
- log.log('收到null消息,队列可能为空或连接中断');
30
- // 移除错误的 channel.ack(msg) 调用
31
- }
32
- }, { noAck: false });
33
-
34
- // 返回清理函数,用于重连时清理状态
35
- return () => {
36
- this.processingMessages.clear();
37
- log.log('已清理消息处理状态');
38
- };
39
- }
40
-
41
- /**
42
- * 处理单条消息
43
- * @param {Object} msg - RabbitMQ消息对象
44
- * @param {Object} channel - RabbitMQ频道
45
- * @param {Function} callback - 消息处理回调函数
46
- * @param {number} delay - 延迟ACK时间
47
- * @private
48
- */
49
- async _handleMessage(msg, channel, callback, delay) {
50
- const deliveryTag = msg.fields.deliveryTag;
51
-
52
- // 检查消息是否已在处理中
53
- if (this.processingMessages.has(deliveryTag)) {
54
- log.log(`消息 ${deliveryTag} 已在处理中,跳过`);
55
- return;
56
- }
57
-
58
- this.processingMessages.add(deliveryTag);
59
-
60
- // 检查消息内容有效性,对无效消息直接确认
61
- if (!this._isValidMessageContent(msg)) {
62
- log.log(`⚠️ 收到无效消息 ${deliveryTag},内容为空或无法解析,自动确认以防止阻塞`);
63
- this._acknowledgeMessage(msg, channel, deliveryTag, 0); // 立即确认无效消息
64
- return;
65
- }
66
-
67
- try {
68
- const content = JSON.parse(msg.content.toString());
69
- log.log(`🪴 队列收到消息: ${JSON.stringify(content)}`);
70
- const startTime = Date.now();
71
-
72
- // 创建超时 Promise
73
- const timeoutPromise = new Promise((_, reject) => {
74
- setTimeout(() => {
75
- reject(new Error(`消息处理超时 (${this.config.messageTimeout}ms)`));
76
- }, this.config.messageTimeout);
77
- });
78
-
79
- // 使用 Promise.race 实现超时控制
80
- try {
81
- await Promise.race([
82
- callback(content),
83
- timeoutPromise
84
- ]);
85
-
86
- const endTime = Date.now() - startTime;
87
- log.log(`☘️ 消息处理完成,延迟: ${delay}ms,总时间: ${endTime}ms`);
88
- this._acknowledgeMessage(msg, channel, deliveryTag, delay);
89
-
90
- } catch (callbackError) {
91
- if (callbackError.message.includes('超时')) {
92
- log.error(`⏰ 消息 ${deliveryTag} 处理超时 (${this.config.messageTimeout}ms)`);
93
- } else {
94
- log.log('‼️ 处理消息返回错误:', callbackError.message);
95
- }
96
- await this._rejectMessage(msg, channel, deliveryTag);
97
- }
98
-
99
- } catch (e) {
100
- log.log('‼️ 处理消息时出错:', e.message);
101
- await this._rejectMessage(msg, channel, deliveryTag);
102
- }
103
- }
104
-
105
- /**
106
- * 检查消息内容是否有效
107
- * @param {Object} msg - RabbitMQ消息对象
108
- * @returns {boolean} 消息内容是否有效
109
- * @private
110
- */
111
- _isValidMessageContent(msg) {
112
- try {
113
- // 检查消息对象是否存在
114
- if (!msg || !msg.content) {
115
- return false;
116
- }
117
-
118
- // 获取消息内容字符串
119
- const contentStr = msg.content.toString();
120
-
121
- // 检查内容是否为空或只包含空白字符
122
- if (!contentStr || contentStr.trim() === '') {
123
- return false;
124
- }
125
-
126
- // 检查是否为null字符串
127
- if (contentStr.toLowerCase() === 'null' || contentStr.toLowerCase() === 'undefined') {
128
- return false;
129
- }
130
-
131
- // 尝试解析JSON,如果失败则认为无效
132
- JSON.parse(contentStr);
133
- return true;
134
- } catch (error) {
135
- // JSON解析失败,认为消息无效
136
- return false;
137
- }
138
- }
139
-
140
- /**
141
- * 确认消息
142
- * @param {Object} msg - RabbitMQ消息对象
143
- * @param {Object} channel - RabbitMQ频道
144
- * @param {string} deliveryTag - 消息标签
145
- * @param {number} delay - 延迟时间
146
- * @private
147
- */
148
- _acknowledgeMessage(msg, channel, deliveryTag, delay) {
149
- // 确保消息还在处理集合中再进行ACK
150
- if (this.processingMessages.has(deliveryTag)) {
151
- setTimeout(() => {
152
- try {
153
- channel.ack(msg);
154
- this.processingMessages.delete(deliveryTag);
155
- log.log(`✅ 消息 ${deliveryTag} 已确认`);
156
- } catch (ackError) {
157
- log.error(`ACK消息 ${deliveryTag} 时出错:`, ackError.message);
158
- this.processingMessages.delete(deliveryTag);
159
- }
160
- }, delay);
161
- }
162
- }
163
-
164
- /**
165
- * 拒绝消息并重新排队
166
- * @param {Object} msg - RabbitMQ消息对象
167
- * @param {Object} channel - RabbitMQ频道
168
- * @param {string} deliveryTag - 消息标签
169
- * @private
170
- */
171
- async _rejectMessage(msg, channel, deliveryTag) {
172
- await happy.sleep(5);
173
-
174
- if (this.processingMessages.has(deliveryTag)) {
175
- try {
176
- channel.reject(msg, true);
177
- this.processingMessages.delete(deliveryTag);
178
- log.log(`❌ 消息 ${deliveryTag} 已拒绝并重新排队`);
179
- } catch (rejectError) {
180
- log.error(`拒绝消息 ${deliveryTag} 时出错:`, rejectError.message);
181
- this.processingMessages.delete(deliveryTag);
182
- }
183
- }
184
- }
185
-
186
- /**
187
- * 清理所有处理中的消息状态
188
- */
189
- clearProcessingMessages() {
190
- this.processingMessages.clear();
191
- log.log('已清理所有消息处理状态');
192
- }
193
-
194
- /**
195
- * 获取当前处理中的消息数量
196
- * @returns {number} 处理中的消息数量
197
- */
198
- getProcessingCount() {
199
- return this.processingMessages.size;
200
- }
201
- }
202
-
203
- module.exports = MessageProcessor;