论Iot设备在线判断

2019-12-04 18:21:56 浏览数 (1)

在Iot物联网中,有个关键点就是设备是否在线的判断。如果用传统的Http数据传输则通过轮询达到目的,具体就是通过不停的向服务器发送心跳包,让服务器知道设备在线;这种方式简单直接但粗爆,设备数量少可以,但如果设备上千或万,那么服务器基本只能靠分布式部署了。如果用MQTT则减少很多问题,因为MQTT有个遗嘱功能,就是当超过某时间数据断开后,就自动发送。一直以来我都没弄明白这个遗嘱的功能,因为误入了当断电或直接断线连遗嘱都发不出的矛盾圈。好在,最近看Iot的文章里面有个MQTT的说明,详细说了一下遗嘱的功能,其实在MQTT客户端与服务端链接时,就已经将遗嘱发给服务器,当服务器没再收到客户端的数据就将遗嘱拿出来。ok,其实遗嘱不是断气前发送,而是在链接时就签好的。那其实这个遗嘱在MQTT初始化时已经要写好。那么这个初始化是那个呢?经过一番找寻,终于发现签遗嘱是用setWill,怎么用好吧,上配置代码:

代码语言:javascript复制
mqttAndroidClient = new MqttClient(AppInfoKeeper.getRootUrlString(), AppInfoKeeper.getMedchCode(), new MemoryPersistence());
//新建连接设置
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
//断开后,是否自动连接
mqttConnectOptions.setAutomaticReconnect(true);
//是否清空客户端的连接记录。若为true,则断开后,broker将自动清除该客户端连接信息
mqttConnectOptions.setCleanSession(true);
//设置超时时间,单位为秒
mqttConnectOptions.setConnectionTimeout(15);
//心跳时间,单位为秒。即多长时间确认一次Client端是否在线
mqttConnectOptions.setKeepAliveInterval(10);
//允许同时发送几条消息(未收到broker确认信息)
//mqttConnectOptions.setMaxInflight(10);

mqttConnectOptions.setUserName("Username");//MQTT的账号
mqttConnectOptions.setPassword("Password".toCharArray());//MQTT的密码
//遗嘱内容
String message_d = "{"reported": {"TerminalNo":""  AppInfoKeeper.getMedchCode() "","Type":"API_OFFLINE"}}";
mqttConnectOptions.setWill(publishTopic, message_d.getBytes(),2, false);// 最后的遗嘱
//选择MQTT版本
mqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
mqttAndroidClient.setCallback(mqttCallback);
if (!mqttAndroidClient.isConnected() && isConnectIsNomarl()) {
    mqttAndroidClient.connect(mqttConnectOptions);
}
if (mqttAndroidClient.isConnected()) {
    //订阅主题
    mqttAndroidClient.subscribe("$baidu/iot/general/"   AppInfoKeeper.getMedchCode(), 0, iMqttMessageListener);
}

关键点:mqttConnectOptions.setWill(publishTopic, message_d.getBytes(),2,false);// 最后的遗嘱

当MQTT服务器检测不到客户端的链接,则会自动将遗嘱的内容发出。然后根据其遗嘱进行处理就可以达到判断是否在线的目的。

我目前的做法是通过建一个在线表,当客户端与服务端有联系的时间则进行写表进行记录,如果收到遗嘱则对表进行删除;这样只要对数据表进行读取就知道在线的情况了。好吧,再给出在线进行更新的SQL存储过程。。

代码语言:javascript复制
CREATE PROCEDURE [dbo].[TerminalNo_Online]
(   
    @TerminaNo nvarchar(2000)    
)
AS
/*设备在线更新*/
BEGIN
if exists (select top 1 TerminalNo from TerminalOnline where TerminalNo=@TerminaNo)
    update TerminalOnline set Onlinetime=GETDATE() where TerminalNo = @TerminaNo    
ELSE    
    INSERT INTO TerminalOnline(TerminalNo,Onlinetime) VALUES (@TerminaNo,GETDATE())
END
GO

最后,总结一下MQTT确实是一个低流量的数据传输载体,怪不得Iot设备大多都用这个。

-完-

0 人点赞