Node.js Azure node IOT SDK如何为MQTT异常设置回调

Node.js Azure node IOT SDK如何为MQTT异常设置回调,node.js,azure,mqtt,azure-iot-hub,azure-iot-sdk,Node.js,Azure,Mqtt,Azure Iot Hub,Azure Iot Sdk,我在几个项目中使用了Azure IOT SDK for C。有相当好的文档,并且很清楚如何注册回调,以便在消息无法发送或MQTT连接中断时收到通知。查看节点的javascript SDK,我不知道如何注册类似的回调。例如,在创建客户端之后,我可以调用client.open(onConnect),并且在建立连接时调用onConnect方法。我还可以调用client.sendEvent(message,…)发送消息,如果成功,我会收到消息排队的通知。然而: 如果mqtt连接被中断,如何注册回调以得

我在几个项目中使用了Azure IOT SDK for C。有相当好的文档,并且很清楚如何注册回调,以便在消息无法发送或MQTT连接中断时收到通知。查看节点的javascript SDK,我不知道如何注册类似的回调。例如,在创建客户端之后,我可以调用
client.open(onConnect)
,并且在建立连接时调用
onConnect
方法。我还可以调用
client.sendEvent(message,…)
发送消息,如果成功,我会收到消息排队的通知。然而:

  • 如果mqtt连接被中断,如何注册回调以得到通知
  • 如果成功接收到数据包(QOS 1或QOS 2)或发送失败,如何注册一个回调来告知
  • 如何指定我想要的QOS级别

首先,关于物联网集线器中的MQTT QoS支持,有几点需要注意:

  • 物联网集线器不支持QoS 2消息。如果设备应用发布QoS为2的消息,IoT Hub将关闭网络连接。当 设备应用程序订阅QoS为2的主题,IoT Hub授予最大 子包数据包中的QoS级别1。之后,物联网中心将提供 使用QoS 1向设备发送消息
  • 默认情况下,设备SDK连接到QoS为1的物联网集线器,以便与物联网集线器进行消息交换
有关详细信息,请参阅

现在进入问题,您有两种选择:

使用Azure IoT SDK: 如果您想使用,下面是一个处理断开连接场景的参考。关于QoS 1相关的交换(如PUBACK确认),它不允许在较低级别进行,但在内部进行处理以确保有保证的消息传递。有关直接使用MQTT的信息,请参阅我回答的后面部分

//版权所有(c)Microsoft。版权所有。
//根据麻省理工学院许可证授权。有关完整的许可证信息,请参见项目根目录中的许可证文件。
"严格使用",;
const Protocol=require('azure-iot-device-mqtt')。mqtt;
//取消对其中一个传输的注释,然后在fromConnectionString中将其更改为测试其他传输
//const Protocol=require('azure-iot-device-amqp')。AmqpWs;
//const Protocol=require('azure-iot-device-http')。http;
//const Protocol=require('azure-iot-device-amqp')。amqp;
//const Protocol=require('azure-iot-device-mqtt')。MqttWs;
const Client=require('azure-iot-device')。客户端;
const Message=require('azure-iot-device')。消息;
//包含主机名、设备Id和设备密钥的字符串,格式如下:
//“主机名=;设备ID=;SharedAccessKey=”
const deviceConnectionString=process.env.DEVICE\u CONNECTION\u STRING;
让我们休息一下;
函数disconnectHandler(){
clearInterval(sendInterval);
client.open().catch((err)=>{
控制台错误(错误消息);
});
}
//AMQP和HTTP传输具有完成、拒绝或放弃消息的概念。
//例如,这仅在AMQP和HTTP中起作用:
//client.complete(msg,printResultFor('completed'));
//如果使用MQTT调用来完成、拒绝或放弃,则没有操作。
//完成消息时,发送C2D消息的服务将收到消息已被处理的通知。
//拒绝消息时,发送C2D消息的服务将被通知设备将不处理该消息。要使用的方法是client.reject(msg,callback)。
//当放弃该消息时,IoT Hub将立即尝试重新发送该消息。要使用的方法是client.about(msg,callback)。
//MQTT更简单:它默认接受消息,不支持拒绝或放弃消息。
函数messageHandler(msg){
console.log('Id:'+msg.messageId+'Body:'+msg.data);
client.complete(msg,printResultFor('completed'));
}
函数生成消息(){
常数风速=10+(Math.random()*4);//范围:[10,14]
常数温度=20+(Math.random()*10);//范围:[20,30]
常数湿度=60+(Math.random()*20);//范围:[60,80]
const data=JSON.stringify({deviceId:'myFirstDevice',风速:风速,温度:温度,湿度:湿度});
const message=新消息(数据);
message.properties.add('temperatureAlert',(温度>28)?'true':'false');
返回消息;
}
函数errorCallback(err){
控制台错误(错误消息);
}
函数connectCallback(){
log(“客户端连接”);
//每两秒钟创建一条消息并将其发送到物联网中心
sendInterval=setInterval(()=>{
const message=generateMessage();
log('Sending message:'+message.getData());
client.sendEvent(消息,printResultFor('send'));
}, 2000);
}
//fromConnectionString必须指定来自任何传输包的传输构造函数。
让client=client.fromConnectionString(设备连接字符串,协议);
client.on('connect',connectCallback);
client.on('error',errorCallback);
on('disconnect',disconnectHandler);
client.on('message',messageHandler);
client.open()
.catch(错误=>{
console.error('无法连接:'+错误消息);
});
//用于在控制台中打印结果的助手函数
函数printResultFor(op){
返回函数printResult(err,res){
if(err)console.log(op+'error:'+err.toString());
if(res)console.log(op+'状态:'+res.constructor.name);
};
}
直接使用MQTT: 如中所述,还可以使用端口8883上的MQTT协议连接到公共设备端点。为此,您可以使用任何可用的标准MQTT库(例如)。但是,出于某些特殊考虑,请注意以下事项:

在连接数据包中,设备应使用以下值:

  • 对于ClientId字段,使用deviceId
  • 对于用户名字段,使用{iothubhostname}/{device_id}/?api version=2018-06-30,其中 {iothubhostname}是IoT hu的完整CName