MQCB回调触发MQRC_NO_MSG_AVAILABLE时无法识别对应空队列的咨询
解决MQCB回调中MQRC_NO_MSG_AVAILABLE时无法识别对应队列的问题
你这个思路完全没问题——在回调上下文(MQCBD的CallbackContext字段)中存入队列对象句柄,就是处理这种场景的标准且官方推荐的做法。下面给你详细拆解原因、实现步骤和注意事项:
为什么会出现Hobj为MQHO_NONE?
当你用MQGMO_WAIT设置了等待,而队列中没有可用消息触发超时的时候,这个事件本质是连接层面的“无消息通知”,而非某个特定队列的消息事件。所以MQ不会把它关联到具体的队列句柄,此时context->Hobj就会被设为MQHO_NONE(也就是0),这是MQ 8.0版本的预期行为,不是你的代码问题。
具体实现:给每个回调绑定队列句柄
你需要为每个队列单独创建MQCBD结构体,把对应的队列句柄(甚至可以是包含队列名称等更多信息的自定义结构体指针)存入CallbackContext字段,这样即使context->Hobj为空,也能从上下文里拿到对应的队列标识。
修改后的核心代码
// 注册第一个队列的回调时,绑定句柄到上下文 MQCBD cbd1 = {MQCBD_DEFAULT}; cbd1.CallbackType = MQCBT_MESSAGE_CONSUMER; cbd1.CallbackFunction = &my_message_consumer; cbd1.CallbackContext = (PMQVOID)&hobj1; // 把队列句柄存入上下文 MQCB(hconn, MQOP_REGISTER, &cbd1, hobj1, &md, &gmo, &c, &r); check_fail("MQCB register queue 1", c, r); // 注册第二个队列的回调,同样绑定句柄 MQCBD cbd2 = {MQCBD_DEFAULT}; cbd2.CallbackType = MQCBT_MESSAGE_CONSUMER; cbd2.CallbackFunction = &my_message_consumer; cbd2.CallbackContext = (PMQVOID)&hobj2; MQCB(hconn, MQOP_REGISTER, &cbd2, hobj2, &md, &gmo, &c, &r); check_fail("MQCB register queue 2", c, r);
更新回调函数获取队列信息
void my_message_consumer(MQHCONN hconn, PMQMD md, PMQGMO gmo, PMQVOID buffer, PMQCBC context) { MQHOBJ target_queue = MQHO_NONE; // 从回调上下文取出预先存储的队列句柄 if (context->CallbackContext != NULL) { target_queue = *(PMQHOBJ)context->CallbackContext; } if (context->Reason == MQRC_NO_MSG_AVAILABLE) { printf("No message available for queue handle %d\n", target_queue); } else { printf("Completion code %s, reason %s, object handle %d\n", MQCC_STR(context->CompCode), MQRC_STR(context->Reason), context->Hobj != MQHO_NONE ? context->Hobj : target_queue); } events_received++; }
额外要注意的点
- 确保
CallbackContext指向的内存有效:如果是栈上的变量(比如示例中的hobj1、hobj2),要保证在MQCTL运行期间这些变量不会被销毁;如果是动态分配的结构体,记得在注销回调后释放内存,避免泄漏。 - 要是你需要更详细的队列信息(比如队列名称),可以自定义一个结构体:
然后把这个结构体的指针存入typedef struct { MQHOBJ hobj; char queue_name[MQ_Q_NAME_LENGTH + 1]; } QueueCallbackContext;CallbackContext,回调时就能直接拿到队列名称了。 - 你的MQ版本(8.0.0.2队列管理器 + 8.0.0.5客户端)完全支持这个特性,没有遗漏任何关键配置——这就是MQ处理等待超时事件的标准方式。
内容的提问来源于stack exchange,提问作者legoscia
相关产品推荐
相关产品推荐

