iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android如何开发MQTT协议的模型及通信
  • 625
分享到

Android如何开发MQTT协议的模型及通信

2023-07-05 07:07:33 625人浏览 安东尼
摘要

本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android如何开发MQtT协议的模型及通信”吧!什么是MQTT协议MQTT协议又

本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android如何开发MQtT协议的模型及通信”吧!

什么是MQTT协议

MQTT协议又称为消息队列要测传输协议,他是一种基于发布/订阅范式的消息协议,并且它是一种基于tcp/IP协议族的应用层协议。

可以看出的它的特点:轻量、简单、基于发布/订阅范式、基于TCP/IP、是一种应用层协议。

如果还是不明白,我们可以简单拿它和我们常用的Http协议做个比较。

HTTP协议MQTT协议
基于TCP或UDP基于TCP
基于 请求/响应 模型基于 发布/订阅 模型
http1.x是传数据包传输二进制数据

MQTT协议的模型

我们得知道它是一个怎样的模型才好去了解它的一个工作方式。比如说HTTP协议简单分为两个角色,一个Client代表客户端,一个Server代表服务端。

而MQTT简单来看分为3个角色,publisher表示发布者,subscriber表示订阅者,它们两个都是Client,所以任何一个Client客户端既能充当publisher,也能充当subscriber。还有一个角色是broker表示代理,它是Server服务端。可以看出MQTT也是基于C/S的通信架构,只不过分为3种角色。

如果理解了这个模型之后,你就会有个疑问,发布和订阅什么呢?这就需要引入一个新的东西叫主题topic(如果不理解主题这个概念的话也没关系,后面用代码就很容易理解主题是什么)

Android如何开发MQTT协议的模型及通信

所以它的工作流程就是:

  • subscriber订阅者连接broker代理,并订阅主题topic

  • publisher发布者连接broker代理(当然如何订阅者和发布者是同一个Client的话就不需要重复连接),并发布消息到相应的主题

  • broker代理会把消息发给对应订阅的主题的subscriber订阅者

开发MQTT通信

1. 处理客户端和服务端

前面我们说了MQTT是继续C/S的结构,那我们就需要有一个客户端和一个服务端。

(1)服务端开发

很不幸我是开发前端的,后台的开发我并不熟悉,所以这里的演示中我选择用云服务EMQX,想尝试的朋友可以上这个网页去部署自己的云服务,流程很简单 cloud.emqx.com/ ,免费试用14天。

Android如何开发MQTT协议的模型及通信

(2)客户端开发

因为我是做Android开发的,所以这里我用Android来举例子。正常来说可以在TCP的基础上开发,自己去封装,但我这只是浅谈,所以我用第三方框架进行演示,用Paho的mqtt

2. 客户端开发

先导入Paho的mqtt

dependencies {    ......    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'}

在manifest中注册Paho的MqttService

<application    android:allowBackup="true"    android:icon="@mipmap/ic_launcher"    android:label="@string/app_name"    android:roundIcon="@mipmap/ic_launcher_round"    android:supportsRtl="true"    android:theme="@style/Theme.MyApplication">    <activity        android:name=".MainActivity"        android:exported="true">        <intent-filter>            <action android:name="android.intent.action.MAIN" />            <cateGory android:name="android.intent.category.LAUNCHER" />        </intent-filter>    </activity>    <service android:name="org.eclipse.paho.android.service.MqttService"/>    <service android:name=".MqttActionService"/></application>

我这边为了用一个项目来演示Mqtt通信,所有把MainActivity当成publisher发布者,把MqttActionService当成subscriber订阅者。

所以整体的流程是这样的,我们先开启MqttActionService,然后在MqttActionService中进行连接和订阅。再在MainActivity进行连接和发送消息。

先把Mqtt的Client给封装起来(我这里防止有些朋友看不懂Kotlin,我就用了Java,后面不重要的地方我直接用Kotlin,一般也比较容易看懂)。

public class MyMqttClient {    private MqttAndroidClient mClient;    private MqttConnectOptions mOptions;    private OnMqttConnectListener mOnMqttConnectListener;    private final String mClientId;    private MqttCallbackExtended mExtended = new MqttCallbackExtended() {        @Override        public void connectComplete(boolean reconnect, String serverURI) {            if (mOnMqttConnectListener != null){                mOnMqttConnectListener.onConnectComplete(serverURI);            }        }        @Override        public void connectionLost(Throwable cause) {            if (mOnMqttConnectListener != null){                mOnMqttConnectListener.onConnectFailure(cause);            }        }        @Override        public void messageArrived(String topic, MqttMessage message) throws Exception {        }        @Override        public void deliveryComplete(IMqttDeliveryToken token) {        }    };    private IMqttActionListener mConnectAction = new IMqttActionListener() {        @Override        public void onSuccess(IMqttToken asyncActionToken) {        }        @Override        public void onFailure(IMqttToken asyncActionToken, Throwable exception) {            if (mOnMqttConnectListener != null){                mOnMqttConnectListener.onConnectFailure(exception);            }            exception.printStackTrace();        }    };    private IMqttMessageListener messageListener = new IMqttMessageListener() {        @Override        public void messageArrived(String topic, MqttMessage message) throws Exception {            if (mOnMqttConnectListener != null){                mOnMqttConnectListener.onMessageArrived(topic, message);            }        }    };    public MyMqttClient(Context context){        this(context, null);    }    public MyMqttClient(Context context, String clientId){        if (!TextUtils.isEmpty(clientId)) {            this.mClientId = clientId;        }else {            this.mClientId = MqttConfig.clientId;        }        init(context);    }    public void init(Context context){        mClient = new MqttAndroidClient(context, MqttConfig.mqttUrl, mClientId);        mClient.setCallback(mExtended);        mOptions = new MqttConnectOptions();        mOptions.setConnectionTimeout(4000);        mOptions.seTKEepAliveInterval(30);        mOptions.setUserName(MqttConfig.username);        mOptions.setPassword(MqttConfig.passWord.toCharArray());    }    public void setOnMqttConnectListener(OnMqttConnectListener onMqttConnectListener) {        this.mOnMqttConnectListener = onMqttConnectListener;    }        public void connect(){        try {            if (!mClient.isConnected()){                mClient.connect(mOptions, null, mConnectAction);            }        }catch (Exception e){            e.printStackTrace();        }    }        public void subscribeToTopic(String mTopic){        this.subscribeToTopic(mTopic, 0);    }    public void subscribeToTopic(String mTopic, int qos){        try {            mClient.subscribe(mTopic, qos, null,null, messageListener);        }catch (Exception e){            e.printStackTrace();        }    }        public void sendMessage(String mTopic, byte[] data){        try {            MqttMessage message = new MqttMessage();            message.setPayload(data);            mClient.publish(mTopic, message);        }catch (Exception e){            e.printStackTrace();        }    }    public void onDestroy(){        try {            mClient.disconnect();            mExtended = null;            mConnectAction = null;            messageListener = null;        }catch (Exception e){            e.printStackTrace();        }    }        public interface OnMqttConnectListener{        void onConnectComplete(String serverURI);        void onConnectFailure(Throwable e);        void onMessageArrived(String topic, MqttMessage message);    }}

当中有些配置我直接抽出来

public interface MqttConfig {    String mqttUrl = "tcp://r0c36017.cn-shenzhen.emqx.cloud:11005";    String clientId = "deployment-r0c36017";    String username = "yeshuaishizhenshuai";    String password = "123456";    String oneTopic = "kylin/topic/one";}

可以讲一下这些参数

(1) mqttUrl: 连接代理的连接,可以看到我上面云服务那张截图里面的“连接地址”和“连接端口” (2) clientId: 客户端ID,无论是subscriber还是publisher都属于客户端,这个在上面说过,所以都有一个对应的ID标识他们是属于哪个客户端。我下面的Demo中MqttActionService用的ClienId是deployment-r0c36017,MainActivity用的ClienId是deployment-r0c36018,不同的,所以是两个客户端。 (3) username和password: 这两个参数都是一个标识,会和后台记录,如果你没有的话,那你就连不上代理,也就是连不上服务端。 (4) oneTopic: 就是主题,你订阅和发送消息都要对应是哪个主题。

然后subscriber连接并订阅主题

class MqttActionService : Service() {    private var mqttClient : MyMqttClient ?= null    override fun onCreate() {        super.onCreate()        mqttClient = MyMqttClient(this)        mqttClient?.setOnMqttConnectListener(object : MyMqttClient.OnMqttConnectListener{            override fun onConnectComplete(serverURI: String?) {                mqttClient?.subscribeToTopic(MqttConfig.oneTopic)            }            override fun onConnectFailure(e: Throwable?) {            }            override fun onMessageArrived(topic: String?, message: MqttMessage?) {                val h = Handler(Looper.getMainLooper())                h.post {                    Toast.makeText(this@MqttActionService.applicationContext, message.toString(), Toast.LENGTH_SHORT).show();                }            }        })    }    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {        val handler = Handler()        handler.postDelayed({ mqttClient?.connect() }, 1000)        return START_STICKY    }    override fun onBind(intent: Intent?): IBinder? {        return null    }    override fun onDestroy() {        super.onDestroy()        mqttClient?.onDestroy()    }}

然后publisher连接并发送消息

class MainActivity : AppCompatActivity() {    private var clinet : MyMqttClient ?= null    private var isConnect = false    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        init()        val btn : Button = findViewById(R.id.btn_connect)        val send : Button = findViewById(R.id.btn_send)        val open : Button = findViewById(R.id.open)        open.setOnClickListener {            val intent = Intent()            intent.setClass(this, MqttActionService::class.java)            startService(intent)        }        btn.setOnClickListener {            clinet?.connect()        }        send.setOnClickListener {            clinet?.sendMessage(MqttConfig.oneTopic, "你干嘛啊~哎呦~".toByteArray())        }    }    private fun init(){        clinet = MyMqttClient(this, "deployment-r0c36018")        clinet?.setOnMqttConnectListener(object : MyMqttClient.OnMqttConnectListener{            override fun onConnectComplete(serverURI: String?) {                isConnect = true            }            override fun onConnectFailure(e: Throwable?) {                e?.printStackTrace()                isConnect = false            }            override fun onMessageArrived(topic: String?, message: MqttMessage?) {            }        })    }}

我这定了3个按钮,第一个按钮open会跳转Service然后subscriber连接并订阅主题,第二个按钮btn会连接代理,第三个按钮send发送消息。看MqttActionService的代码可以看出,我这里发送消息后,会弹出Toast。

Paho的mqtt的BUG

这库我也是第一次用,我们那用的都是自己撸的(这边肯定没法放上来),然后我用的时候发现一个问题。我想给Service去开一条进程去处理订阅的操作的,这样能更真实的去模拟,结果就在连接时出问题了

经检查,连接的context的进程要和org.eclipse.paho.android.service.MqttService的进程一致。我去看他源码是怎么回事。

Android如何开发MQTT协议的模型及通信

发现它内部的Binder竟然做了强转,这里因为不是代理而会出现报错。如果使用这个库的话就小心点你要做的夸进程的操作。

到此,相信大家对“Android如何开发MQTT协议的模型及通信”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: Android如何开发MQTT协议的模型及通信

本文链接: https://www.lsjlt.com/news/350395.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android如何开发MQTT协议的模型及通信
    本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android如何开发MQTT协议的模型及通信”吧!什么是MQTT协议MQTT协议又...
    99+
    2023-07-05
  • Android开发MQTT协议的模型及通信浅析
    目录前言什么是MQTT协议MQTT协议的模型开发MQTT通信1. 处理客户端和服务端(1)服务端开发(2)客户端开发2. 客户端开发Paho的mqtt的BUG总结前言 为什么要讲M...
    99+
    2023-03-01
    Android MQTT协议模型通信 Android MQTT
  • 如何使用WebSocket网络通信协议开发聊天室
    本篇内容主要讲解“如何使用WebSocket网络通信协议开发聊天室”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用WebSocket网络通信协议开发聊天室...
    99+
    2024-04-02
  • 在Node.js下如何运用MQTT协议实现即时通讯及离线推送
    小编给大家分享一下在Node.js下如何运用MQTT协议实现即时通讯及离线推送,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码...
    99+
    2024-04-02
  • PHP商城开发中如何协作与通信
    随着互联网的高速发展,电子商务行业也愈加繁荣。而在电子商务中,开发PHP商城已经成为了一项重要的任务。对于团队合作开发PHP商城的开发者来说,协作和良好的沟通是成功的必备条件。本文将介绍一些PHP商城开发团队应该遵循的协作和通信实践。建立明...
    99+
    2023-05-14
    PHP 商城开发 协作与通信
  • android开发者模式如何关闭及开启
    要关闭或开启Android设备的开发者模式,可以按照以下步骤操作:关闭开发者模式:1. 打开设备的设置菜单。2. 滚动至底部,找到“...
    99+
    2023-10-07
    Android
  • 如何理解WEB开发中的Python WSGI协议
    今天就跟大家聊聊有关如何理解WEB开发中的Python WSGI协议,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Web应用程序开发Web应用程序的本质是什么简单描述Web应用程序的...
    99+
    2023-06-02
  • 如何使用go net实现简单的redis通信协议
    这篇文章主要为大家展示了“如何使用go net实现简单的redis通信协议”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用go net实现简单的redis通信协议”这篇...
    99+
    2023-06-21
  • 如何理解FIX协议的原理、消息格式及配置开发
    本篇文章给大家分享的是有关如何理解FIX协议的原理、消息格式及配置开发,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、定义FIX协议是由国际FIX协会组织提供的一个开放式协议...
    99+
    2023-06-05
  • Java中的HTTP协议:如何实现分布式实时通信?
    HTTP协议在Java中的应用越来越广泛,特别是在分布式实时通信方面。本文将介绍Java中HTTP协议的相关知识,并演示如何利用HTTP协议实现分布式实时通信。 HTTP协议是Web应用程序中最常用的协议之一,它使用TCP/IP协议作为传输...
    99+
    2023-10-27
    http 分布式 实时
  • Golang开发建议:如何编写高效的网络通信代码
    Golang(又称Go)是由Google开发的一种编程语言,它具有简洁、高效、并发性强等特点,越来越受到开发者的欢迎。在网络通信方面,Golang提供了丰富的库和工具,使得编写高效的网络通信代码变得相对简单。本文将分享一些Golang开发的...
    99+
    2023-11-22
    Golang 网络通信 高效编写
  • C++开发建议:如何进行模块化的C++开发
    C++语言作为一种通用的高级编程语言,被广泛用于开发各种应用程序和系统。然而,C++的复杂性和灵活性也使得开发人员面临着一些挑战,特别是在大型项目中。在处理大型项目时,模块化的开发方法是至关重要的。本文将介绍如何进行模块化的C++开发,并提...
    99+
    2023-11-23
    模块化开发 C++开发 建议
  • HTTP协议如何与PHP生成的二维码实现实时通信?
    随着移动互联网的发展,二维码已经成为了一种非常流行的传输信息的方式。而PHP作为一种非常流行的服务器端编程语言,也有很多生成二维码的库可以使用。本文将介绍如何使用HTTP协议与PHP生成的二维码实现实时通信。 一、HTTP协议简介 HTT...
    99+
    2023-06-30
    二维码 http 实时
  • Git和HTTP协议如何影响PHP开发者的工作流程?
    在当今的Web开发中,Git和HTTP协议已经成为了不可或缺的工具和协议。Git是一种分布式版本控制系统,而HTTP协议则是Web应用程序之间数据传输的协议。本文将探讨Git和HTTP协议如何影响PHP开发者的工作流程。 Git如何影响P...
    99+
    2023-06-30
    http 关键字 git
  • Python如何制作简易聊天器以及搭建UDP网络通信模型
    这篇文章将为大家详细讲解有关Python如何制作简易聊天器以及搭建UDP网络通信模型,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。前言:互联网的本质是什么?其实就是信息的交换。就比如我们常用...
    99+
    2023-06-22
  • 如何调优PHP开发中的网络通信性能
    随着互联网的发展,网络通信性能对于PHP开发变得越来越重要。优化网络通信性能可以加快应用程序的响应速度,提升用户体验,同时也能减少服务器负载。本文将介绍几种优化网络通信性能的方法,并提供具体的代码示例。使用HTTP/2协议HTTP/2是HT...
    99+
    2023-10-21
    调优 PHP 网络通信
  • Android 开发中如何模仿一个微信拍摄和图像选择界面
    这篇文章将为大家详细讲解有关Android 开发中如何模仿一个微信拍摄和图像选择界面,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 插件运行后的画面如下:下面这张图对图像进行筛选,...
    99+
    2023-05-31
    android roi
  • Android开发中如何使用手势检测及通过手势实现翻页功能
    这篇文章主要介绍了Android开发中如何使用手势检测及通过手势实现翻页功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体如下:手势是指用户手指或触摸笔在触摸屏上的连续触...
    99+
    2023-05-30
    android
  • JSBridge框架如何解决通信问题以及实现移动端跨平台开发
    这期内容当中小编将会给大家带来有关JSBridge框架如何解决通信问题以及实现移动端跨平台开发,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、跨平台开发是趋势目前主流的移动端平台主要是Android和i...
    99+
    2023-06-05
  • 如何解决PHP开发中的网络通信和传输速度
    随着互联网的快速发展,网络通信和传输速度变得越来越重要。在PHP开发中,如何优化网络通信和传输速度,成为了开发者不可忽视的问题。本文将介绍一些有效的方法和具体的代码示例,帮助你解决PHP开发中的网络通信和传输速度问题。一、使用缓存技术缓存技...
    99+
    2023-10-21
    网络通信 传输速度 - HTTP - WebSocket - TCP/IP
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作