You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure IoT Hub无法接收Event Hub onMessage函数发送的消息

问题分析与解决方案

我仔细看了你的代码,发现两个核心问题导致树莓派接收不到onMessage函数里发送的消息,下面逐一拆解并给出修复方案:

1. EventHub接收客户端被立即终止

你的Web API代码里,刚创建接收处理器就立刻调用了receiveHandler.stop()和client.close(),这会直接终止接收线程,根本来不及处理任何消息(除非消息刚好在那极短的瞬间到达,概率极低)。这应该是你保留了示例代码的停止逻辑,但忘记移除了。

修复方式

把这两行停止/关闭代码注释掉,或者放到你真正需要停止接收的场景中(比如监听进程退出信号时):

async function main() { 
  sendingClient.sendMessage('raspberry',{},"allDevices") // 树莓派能收到这条
  const client = await EventHubClient.createFromIotHubConnectionString(connectionString); 
  const onError = (err) => { 
    console.log("An error occurred on the receiver ", err); 
  }; 
  const onMessage = (msg) => { 
    console.log(msg.body); 
    sendingClient.sendMessage('raspberry',{},"allDevices")// 现在这条应该能收到了
  }; 
  const receiveHandler = client.receive("1", onMessage, onError, { eventPosition: EventPosition.fromEnqueuedTime(Date.now()) }); 

  // 移除这两行,或在需要停止时再调用
  // await receiveHandler.stop(); 
  // await client.close(); 
}

2. SendingClient重复调用open()导致消息无法发送

你的sendingClient.sendMessage函数里,每次发送消息都会执行sendingClient.open(),但open是异步操作:

  • 第一次调用时,客户端从关闭状态打开,回调正常执行并发送消息;
  • 但在onMessage里调用时,客户端已经处于连接状态,再次调用open的回调不会触发,导致消息根本没发出去。

修复方式

提前初始化客户端连接,确保只建立一次连接:

var Client = require('azure-iothub').Client; 
var Message = require('azure-iot-common').Message; 
var connectionString = 'myConnectionString' 
var sendingClient = Client.fromConnectionString(connectionString);
let isConnected = false;

// 封装连接逻辑,确保只连接一次
function ensureConnection() {
  return new Promise((resolve, reject) => {
    if (isConnected) {
      resolve();
      return;
    }
    sendingClient.open(function (err) {
      if (err) {
        console.error('Could not connect: ' + err.message);
        reject(err);
      } else {
        console.log('Service client connected');
        isConnected = true;
        resolve();
      }
    });
  });
}

exports.sendMessage = async (targetDevice, content, messageId) => {
  try {
    await ensureConnection(); // 先确保连接已建立
    // 注意:Message构造函数需要字符串/Buffer,对象要转成JSON字符串
    var message = new Message(JSON.stringify(content)); 
    message.ack = 'full';
    message.messageId = 'message';
    message.properties.add('message', messageId);
    console.log('Sending message: ' + message.getData());
    console.log('Sending message to : ' + targetDevice);
    await sendingClient.send(targetDevice, message);
  } catch (err) {
    console.error('Failed to send message:', err);
  }
};

另外补充一个小细节:你创建Message时传入的是空对象,直接传入会导致树莓派收到[object Object],解析JSON时出错,所以需要用JSON.stringify(content)转成字符串。

优化树莓派接收逻辑

树莓派代码里通过msg.properties.propertyList[1].value判断消息类型,依赖数组索引不够可靠,建议改用属性名直接获取:

client.on('message', (msg) => {
  // 直接通过属性名获取,避免索引变化导致错误
  const messageType = msg.properties.get('message');
  if (messageType === 'allDevices') {
    try {
      const devices = JSON.parse(msg.data.toString());
      response(devices); // 传递消息内容
    } catch (err) {
      console.error('Failed to parse message data:', err);
    }
  }
});

这样修改后,应该就能解决树莓派接收不到onMessage中发送的消息的问题了。

内容的提问来源于stack exchange,提问作者Jeff Aknine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:47:00