基于MQTT的推送,连接服务器问题
来源:互联网 发布:淘宝魅力惠官方旗舰店 编辑:程序博客网 时间:2024/06/06 02:33
最近,项目中要实现基于MQTT协议IM功能。此时,觉得头疼,赶紧问问MQTT的官网,看看这玩意到底是怎么一回事。看过之后,哇哦,还挺神奇的,了解之后,我们自己就可以开发即时通讯了,还用什么第三方的类库啊。好了,闲话不多说,我们进入正题吧。
第一:MQTT的简介
MQTT轻量发布订阅消息协议
概览
MQTT是一个轻量的发布订阅模式消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用设计。
MQTT官网: http://mqtt.org
MQTT V3.1.1协议规范: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
特点
1.开放消息协议,简单易实现
2.发布订阅模式,一对多消息发布
3.基于TCP/IP网络连接
4.1字节固定报头,2字节心跳报文,报文结构紧凑
5.消息QoS支持,可靠传输保证
应用
MQTT协议广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等领域。
1.物联网M2M通信,物联网大数据采集
2.Android消息推送,WEB消息推送
3.移动即时消息,例如Facebook Messenger
4.智能硬件、智能家具、智能电器
5.车联网通信,电动车站桩采集
6.智慧城市、远程医疗、远程教育
7.电力、石油与能源等行业市场
下面附上MQTT协议的中文连接:http://docs.emqtt.cn/zh_CN/latest/mqtt.html
第二:需要配置的文件
1.在build.gradle文件中添加所需的包。
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0' compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
以为这两个一添加就完了嘛???对,没有,如果只是这样的话,是永远收不到推送的,最关键的就是第二步。
2.在AndroidManifest.xml文件中添加如下代码:
<service android:name="org.eclipse.paho.android.service.MqttService" />
有人可能会有疑问,还要添加这行嘛,对,没错,必须添加。
现在所有的准备工作做完了,让我们连接服务器吧。
第三:连接服务器
我在代码中,书写了相关的注释,大家看代码,这里就不多解释了,如果有不懂的,可以看看上面的中文连接的MQTT协议。
public class MqttTest { private static final String TAG = "MqttTest"; private static final String MQTT_BROKER = "后台的地址"; // Broker URL or IP Address private static final String MQTT_PORT = "端口号"; // Broker Port private static final String MQTT_URL_FORMAT = "tcp://%s:%s"; // URL Format normally don't change private String myTopic = "test/topic"; private ScheduledExecutorService scheduler; private MqttAsyncClient mqttClient; private String userName = "admin"; // 连接的用户名 private String passWord = "123456"; //连接的密码 private String mDeviceId = ""; // Device ID, Secure.ANDROID_ID private ConnectivityManager mConnectivityManager; // To check for connectivity changes private MqttConnectOptions options; private Context context; public MqttTest(Context context) { this.context = context; } /** * 初始化相关数据 */ public void init() { try { //host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存 String url = String.format(Locale.US, MQTT_URL_FORMAT, MQTT_BROKER, MQTT_PORT); String clientId = String.valueOf(System.currentTimeMillis()); mqttClient = new MqttAsyncClient(url, clientId, new MemoryPersistence()); //MQTT的连接设置 options = new MqttConnectOptions(); //设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接 options.setCleanSession(true); //设置连接的用户名 options.setUserName(userName); //设置连接的密码 options.setPassword(passWord.toCharArray()); // 设置超时时间 单位为秒 options.setConnectionTimeout(10); // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制 options.setKeepAliveInterval(20); //设置回调 options.setAutomaticReconnect(true);//设置自动重连// mqttAsyncClient.connect(connOpts).waitForCompletion(); mqttClient.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { //连接丢失后,一般在这里面进行重连 if (isNetworkAvailable()) { reconnectIfNecessary(); } } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { //subscribe后得到的消息会执行到这里面 Log.e(TAG, "message=:" + message.toString()); } @Override public void deliveryComplete(IMqttDeliveryToken token) { //publish后会执行到这里 long messageId = token.getMessageId(); Log.e(TAG, "messageId=:" + messageId); } }); } catch (Exception e) { e.printStackTrace(); } mConnectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE); context.registerReceiver(mConnectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } /** * Query's the NetworkInfo via ConnectivityManager * to return the current connected state * 通过ConnectivityManager查询网络连接状态 * * @return boolean true if we are connected false otherwise * 如果网络状态正常则返回true反之flase */ private boolean isNetworkAvailable() { NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); return (info == null) ? false : info.isConnected(); } /** * Checkes the current connectivity * and reconnects if it is required. * 重新连接如果他是必须的 */ public synchronized void reconnectIfNecessary() { if (mqttClient == null || !mqttClient.isConnected()) { connect(); } } private void connect() { new Thread(new Runnable() { @Override public void run() { try { mqttClient.connect(options); // 连接成功之后,处理相关逻辑 } catch (Exception e) { e.printStackTrace(); // 连接出错,可以设置重新连接 } } }).start(); } /** * 调用init() 方法之后,调用此方法。 */ public void startReconnect() { scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { if (!mqttClient.isConnected() && isNetworkAvailable()) { connect(); } } }, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS); } /** * Receiver that listens for connectivity chanes * via ConnectivityManager * 网络状态发生变化接收器 */ private final BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i("BroadcastReceiver", "Connectivity Changed..."); if (!isNetworkAvailable()) { Toast.makeText(context, "网络错误", Toast.LENGTH_SHORT).show(); scheduler.shutdownNow(); } else { startReconnect(); } } };}
嗯,相关连接后台的数据,基本上就这么多,看后天给你返回的数据是怎么样,自己拿上用即可。
最后,加上github的例子,
https://github.com/honeylife/paho.mqtt.javascript,可以下载跑起来,看看相关的例子,逻辑特别严谨。
我会在下面的文章,写即时通讯的相关代码,以及聊天界面的实现,还有图片切换时键盘高度的控制等。
- 基于MQTT的推送,连接服务器问题
- 基于MQTT的消息推送
- 【ESP8266】基于ESP8266的MicroPython连接MQTT服务器
- 基于Vue的mqttws31.js连接mqtt服务器(WebSocket)
- 自己解决基于MQTT的android推送
- C# 接受MQTT服务器推送的消息
- Android推送 基于MQTT
- 基于MQTT实现推送
- 基于libevent的长连接Android 推送服务器 1
- 基于Apollo代理服务器的MQTT推送平台搭建
- 采用基于MQTT的ActiveMQ实现消息推送
- Android基于MQTT协议实现的推送功能
- 采用基于MQTT的ActiveMQ实现消息推送
- 采用基于MQTT的ActiveMQ实现消息推送
- 用mqtt实现安卓手机软件的服务器推送功能
- java 连接mqtt服务器
- Android消息推送(二)--基于MQTT协议实现的推送功能
- Android消息推送(二)--基于MQTT协议实现的推送功能
- python的基础语法
- Toast源码解析
- Redis之配置文件:单位,包含,通用
- 广播
- Java设计模式-适配器模式
- 基于MQTT的推送,连接服务器问题
- 621. Task Scheduler--任务调度
- 关于#include <iomanip>中iomanip的作用~
- Moment.js进行时间类型转换
- MySQL(3):可视化数据库管理工具
- Spring mongoTemplate的批量更新操作,取自Stack Overflow
- 洛谷P3375 KMP字符串匹配
- 数据结构与算法三:希尔排序
- java实现将文件或文件夹压缩