一、MQTT介绍

链接1(菜鸟教程):https://www.runoob.com/w3cnote/mqtt-intro.html

连接2(MQTT中文网):http://mqtt.p2hp.com/

连接3(Android开发之Mqtt的使用):https://blog.csdn.net/asjqkkkk/article/details/80714234

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)。一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议。构建于TCP/IP协议上,由IBM在1999年发布。

二、程序示例

 public class MqttManager {

     private static boolean initFirst = true;//是否第一次初始化mqtt标识符
private static String host = "tcp://47.106.172.221:8081";
private static String userName; //mqtt用户名
private static String passWord; //mqtt登陆密码
private static MqttManager manager;
private static MqttClient mqttClient;
private static MqttConnectOptions options;
private static String topic;//订阅的主题
private static String clientId; //客户端id private static Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
KLog.d(msg.obj);
EventBus.getDefault()
.post(new MessageEventBean(AppConstants.MQTT_EVENT_TYPE, (String) msg.obj));
} else if (msg.what == 2) {
KLog.d("连接成功");
try {
KLog.d("订阅的主题:" + topic);
mqttClient.subscribe(topic, 0); } catch (Exception e) {
e.printStackTrace();
}
} else if (msg.what == 3) {
KLog.d("连接失败,系统正在重连");
}
}
}; private MqttManager() { }
private static MqttCallback myMqttCallback = new MqttCallback(){ @Override
public void messageArrived(String topic, MqttMessage message){
//subscribe后得到的消息会执行到这里面
KLog.d("messageArrived topic:"+topic);
Message msg = new Message();
msg.what = 1;
msg.obj = message.toString();
handler.sendMessage(msg);
}
@Override
public void connectionLost(Throwable cause) {
KLog.d("connectionLost cause = "+cause);
//连接丢失后,一般在这里面进行重连
try{
KLog.d("mqtt重连");
manager.startReconnect();
}catch (Exception e){
KLog.d("Exception = "+ e);
e.printStackTrace();
}
} @Override
public void deliveryComplete(IMqttDeliveryToken token) {
//publish后会执行到这里
KLog.d("deliveryComplete");
}
};
private ScheduledExecutorService scheduler; public static MqttManager getInstance() {
if (manager == null) {
manager = new MqttManager();
}
return manager;
} public void initConnection() {
if (initFirst){
KLog.d("第一次调用initConnection");
try {
clientId = Preferences.getUserAccount() + System.currentTimeMillis();//客户端标识符(本机mac地址+当前时间ms)
userName = Preferences.getUserAccount();//用户名
passWord = Preferences.getUserToken();//密码
topic = userName;
//host为主机名;clientid即连接MQTT的客户端ID,是客户端的唯一标识符;MemoryPersistence设置clientid的保存形式,默认为以内存保存
mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
//MQTT的连接设置
options = new MqttConnectOptions();
//设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(true);
//断开后,是否自动连接
options.setAutomaticReconnect(true);
//设置连接的用户名
options.setUserName(userName);
//设置连接的密码
options.setPassword(passWord.toCharArray());
// 设置超时时间 单位为秒
options.setConnectionTimeout(10);
// 设置会话心跳时间 单位为秒 服务器会每隔1.5*(20)秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
options.setKeepAliveInterval(20);
//setWill方法,如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
// options.setWill(topic,"close".getBytes(),2,true);
//设置回调
mqttClient.setCallback(myMqttCallback);
KLog.d("clientId: "+clientId +", userName: "+userName+", passWord: "+passWord+", topic: "+topic);
//设置标识符状态
initFirst = false;
//mqtt第一次连接
manager.startReconnect();
} catch (Exception e) {
KLog.d("initConnection Exception: " + e);
e.printStackTrace();
}
}else {
KLog.d("网络重连后调用initConnection");
manager.startReconnect();
}
} public void startReconnect() { if (NetworkUtils.isConnected()){ if (!mqttClient.isConnected()) {
//重新连接
connect();
KLog.d("mqtt连接结束");
}else {
KLog.d("mqttClient.isConnected");
}
// scheduler = Executors.newSingleThreadScheduledExecutor();
// scheduler.scheduleAtFixedRate(new Runnable() {
// @Override
// public void run() {
//
// if (!mqttClient.isConnected()) {
// connect();
// KLog.d("mqtt连接结束");
// }
// }
// }, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
}else {
KLog.d("网络不可用");
// scheduler.shutdown();
} } public void sendMsg(String msg) {
KLog.d("sendMsg");
if (mqttClient != null && mqttClient.isConnected()) {
try {
KLog.d("发送的主题:" + Preferences.getUserAccount());
String topic = Preferences.getUserAccount();
KLog.d(topic);
byte[] msgBytes = msg.getBytes();
KLog.d("0000");
mqttClient.publish(topic, msgBytes, 0, false);
KLog.d("11111111111111111");
} catch (MqttException e) {
KLog.d(e);
}
}
} //发布的主题设为pubTopic = "owh" + Preferences.getUserAccount();
//发布主题(发布主题和订阅主题应设为不同值)
public void publish(String topicName, String payload) {
if (mqttClient != null && mqttClient.isConnected()) {
// 创建和配置一个消息
MqttMessage message = new MqttMessage(payload.getBytes());
message.setPayload(payload.getBytes());
message.setQos(0);
try {
KLog.d("1111");
mqttClient.publish(topicName, message);
KLog.d("2222");
} catch (MqttException e) {
KLog.d("publish : " + e.toString());
}
}
} private void connect() { ThreadPoolManager.getInstance().execute(new Runnable() {
@Override
public void run() {
try {
mqttClient.connect(options);
Message msg = Message.obtain();
msg.what = 2;
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
Message msg = Message.obtain();
msg.what = 3;
handler.sendMessage(msg);
}
}
}); // new Thread(new Runnable() {
//
// @Override
// public void run() {
// try {
// mqttClient.connect(options);
// Message msg = new Message();
// msg.what = 2;
// handler.sendMessage(msg);
// } catch (Exception e) {
// e.printStackTrace();
// Message msg = new Message();
// msg.what = 3;
// handler.sendMessage(msg);
// }
// }
// }).start();
} //断开连接
public static void mqttDisconnect(){
if(mqttClient !=null && mqttClient.isConnected()){
try{
mqttClient.disconnect();
}catch (MqttException e){
KLog.d("mqtt disconnect error");
e.printStackTrace();
}
}
} }

三、注意事项

1、MQTT的客户端id(clientId)须唯一。在此项目中clientId = 本机mac地址 + 当前时间(ms)。

2、一个客户端的一个MQTT连接最好只new一个对象,避免一台设备产生多个客户端账号。

当多个发布(/订阅)的clientId相同时,会发生Mqtt反复重连的现象,无法正常发送或接收消息。

当多个发布(/订阅)的clientId不同时,会造成一台设备多个Mqtt账号同时在线,占用了多余的服务器资源。

3、一个客户端的发布Topic和订阅Topic不应相同。

Android MQTT的发布与订阅的更多相关文章

  1. MQTT介绍(3)java模拟MQTT的发布,订阅

    MQTT目录: MQTT简单介绍 window安装MQTT服务器和client java模拟MQTT的发布,订阅 在此强调一下mqtt的使用场景: 1.不可靠.网络带宽小的网络 2.运行的设备CPU. ...

  2. 转MQTT--Python进行发布、订阅测试

    前言  使用python编写程序进行测试MQTT的发布和订阅功能.首先要安装:pip install paho-mqtt 测试发布(pub)  我的MQTT部署在阿里云的服务器上面,所以我在本机上编写 ...

  3. MQTT 消息 发布 订阅

    当连接向一个mqtt服务器时,clientId必须是唯一的.设置一样,导致client.setCallback总是走到 connectionLost回调.报connection reset.调查一天才 ...

  4. (转)SqlServer 数据库同步的两种方式 (发布、订阅),主从数据库之间的同步

    最近在琢磨主从数据库之间的同步,公司正好也需要,在园子里找了一下,看到这篇博文比较详细,比较简单,本人亲自按步骤来过,现在分享给大家. 在这里要提醒大家的是(为了更好的理解,以下是本人自己理解,如有错 ...

  5. (原)3.2 Zookeeper应用 - 数据的发布与订阅

    本文为原创文章,转载请注明出处,谢谢 数据的发布与订阅 1.应用 服务端监听数据改变,客户端创建/更新节点数据,客户端提供数据,服务端处理 2.原理 客户端监控节点数据改变事件(例如配置信息,下图的c ...

  6. MSSQL复制中的发布与订阅

    准备条件 1.2台服务器 2.WINDOWS SERVER 2008 64bit + 3.SQL SERVER 2008 R2 + 4.MSSQLSERVER服务与MSSQLAGENT服务正常运行中 ...

  7. 知方可补不足~SQL2008中的发布与订阅模式

    回到目录 作用:完成数据库与数据库的数据同步 原理:源数据库发布需要同时的表,存储过程,或者函数:目标数据库去订阅它,当源发生变化时,目标数据库自己同步,注意,由于这个过程是SQL自动完成的,所以要求 ...

  8. RabbitMQ官方中文入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)

    发布/订阅 在上篇教程中,我们搭建了一个工作队列.每个任务之分发给一个工作者(worker).在本篇教程中,我们要做的之前完全不一样——分发一个消息给多个消费者(consumers).这种模式被称为“ ...

  9. 【SQL Sever】实现SQL Sever的发布。订阅。 双机热备

    实现SQL Sever的发布和订阅  最大的好处就是: 可以实现读写分离,增删改操作在主数据库服务器上进行,查询在备份数据库服务器上进行.一方面提高软件执行效率,另一方面也减轻主库压力. 本次实现发布 ...

随机推荐

  1. IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(Application.StartupPath + "\\temp", 0); 报:异常来自 HRESULT:0x80040228

    原因:未添加License. 解决办法:在窗体中添加LicenseControl即可.如下图,License图标运行时不会显示.

  2. Numpy 基础函数 --《Python 数据分析从入门到精通》

    在Numpy中,方向称作轴,轴的数目称作维.(array(z,y,x)) np.empty() 函数的使用待完全确定.(eg: np.empty([2,3])  -> ([[0,0,0] [0, ...

  3. Jade学习(四)之结合node如何编译执行

    1.首先安装node 2.新建一个文件夹并进入该文件夹 3.安装jade 4.在新建的文件夹下新建js文件,写nodejs代码 5.在vscode中利用插件code runner直接执行js文件,输出 ...

  4. [转载]神经网络偏置项(bias)的设置及作用

    [转载]神经网络偏置项(bias)的设置及作用 原文来自:https://www.cnblogs.com/shuaishuaidefeizhu/p/6832541.html 1.什么是bias? 偏置 ...

  5. 深入Spring Boot:那些注入不了的 Spring 占位符 ( ${} 表达式 )

    Spring里的占位符 spring里的占位符通常表现的形式是: 1 2 3 <bean id="dataSource" destroy-method="close ...

  6. SpringBoot多数据源解决方案(转载)

    1.开源项目地址:MyBatis Plus & Dynamic Datasource Maven配置: <dependency> <groupId>com.baomid ...

  7. python 服务器 cpu 监控程序--转

    后台 py 代码 app.py ''' 服务器cpu监控程序 思路:后端后台线程一旦产生数据,即刻推送至前端. 好处:不需要前端ajax定时查询,节省服务器资源. 作者:hhh5460 时间:2017 ...

  8. 81. Search in Rotated Sorted Array II (JAVA)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  9. 作为测试人员,不能不懂的adb命令和操作

    刚从web转到app测试,很多知识需要补充,记录一下   1.概念 其实我们口中所讲的adb是个泛指,这其中有两个工具——Fastboot和ADB   fastboot 快速启动,usb链接数据线的一 ...

  10. linux的安全--Selinux,tcp_wrappers,iptables使用

    一.linux安全 安全主要是端口与服务的对应配置 1.1 linux安全主要通过下面三个进行加固 Selinux----主要是对内核的访问权限加以控制 tcp_wrappers---一定程度上限制某 ...