㈠ 如何采用mqtt协议实现android消息推送
使用一个代理服务器message broker,客户端client连接上这个服务器,然后告诉服务器,可以接收哪些类型的消息,同时client也可以发布自己的消息,这些消息根据协议的内容,可以别的client获取。这样就实现了消息推送。㈡ Android使用MQTT通讯
主要讲下Android如何使用MQTT通讯。用到的软件或者框架有:
EMQ: https://www.emqx.io/cn/
org.eclipse.paho的MQTT通讯框架: https://github.com/eclipse/paho.mqtt.android
如果已经有MQTT相关服务,可以跳过第一项,从第二项开始看。
1.安装所需要的依赖包
2.使用以下命令设置稳定存储库,以 CentOS7 为例
3.安装最新版本的 EMQ X
4.安装特定版本的 EMQ X
5.启动 EMQ X
地址:xxx.xxx.xxx:18083,地址为服务器ip或者域名,端口为18083端口
1.在Android中导入依赖
项目地址: https://github.com/eclipse/paho.mqtt.android
2.创建MQTT连接的一个Service
㈢ 如何写一个MQTT连接的android客户端
MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案。 我们可以从这里下载该项目的实例代码,并且可以找到一个采用php书写的服务器端实现。 架构如下所示: wmqtt.jar 是IBM提供的MQTT协议的实现。你可以从如下站点下载它。你可以将该jar包加入你自己的Android应用程序中。 Really Small Message Broker (RSMB) ,他是一个简单的MQTT代理,同样由IBM提供。缺省打开1883端口,应用程序当中,它负责接收来自服务器的消息并将其转发给指定的移动设备。 SAM是一个针对MQTT写的PHP库。你可以从这个下载它. send_mqtt.php是一个通过POST接收消息并且通过SAM将消息发送给RSMB的PHP脚本。 实例代码: Ø 采用XMPP协议实现Android推送 这是我在项目中采用的方案。事实上Google官方的C2DM服务器底层也是采用XMPP协议进行的封装。 XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。 androidpn是一个基于XMPP协议的java开源Android push notification实现。它包含了完整的客户端和服务器端。经过源代码研究我发现,该服务器端基本是在另外一个开源工程openfire基础上修改实现的,不过比较郁闷的是androidpn的文档是由韩语写的,所以整个研究过程基本都是读源码。它的实现示意图如下: androidpn客户端需要用到一个基于java的开源XMPP协议包asmack,这个包同样也是基于openfire下的另外一个开源项目smack,不过我们不需要自己编译,可以直接把androidpn客户端里面的asmack.jar拿来使用。客户端利用asmack中提供的XMPPConnection类与服务器建立持久连接,并通过该连接进行用户注册和登录认证,同样也是通过这条连接,接收服务器发送的通知。 androidpn服务器端也是java语言实现的,基于openfire开源工程,不过它的Web部分采用的是spring框架,这一点与openfire是不同的。Androidpn服务器包含两个部分,一个是侦听在5222端口上的XMPP服务,负责与客户端的XMPPConnection类进行通信,作用是用户注册和身份认证,并发送推送通知消息。另外一部分是Web服务器,采用一个轻量级的HTTP服务器,负责接收用户的Web请求。服务器架构如下: 最上层包含四个组成部分,分别是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager负责管理客户端与服务器之间的会话,Auth Manager负责客户端用户认证管理,Presence Manager负责管理客户端用户的登录状态,NotificationManager负责实现服务器向客户端推送消息功能。 服务器端界面如下,分别对应了上述的几个功能模块: 发送以后,我们可以在手机端看到接收的消息:
㈣ 安卓mqtt 同一个客户端ip是否会踢掉前一个连接
不会,除非客户端CLIENTID一致,在连接时会将上一个相同clientId的连接踢掉,并且会出现EOFException。windows同一台PC机上面使用MQTT协议连接服务端,最多也就1000过些,因为端口有限。目前我也在做这个,使用LINUX操作系统,调整句柄数,这样能连接的更多
㈤ android消息推送GCM、XMPP、MQTT三种方案的优劣,越仔细越好,有具体分析更好!
android消息推送GCM、XMPP、MQTT三种方案的优劣:㈥ android studio怎么安装mqtt
1、 下载Apollo服务器,下载后解压,然后运行apache-apollo-1.6\bin\apollo.cmd,输入create mybroker(名字任意取,这里是根据 官网 介绍的来取的)创建服务器实例,服务器实例包含了所有的配置,运行时数据等,并且和一个服务器进程关联。
2、create mybroker之后会在bin目录下生成mybroker文件夹,里面包含有很多信息,其中etc\apollo.xml文件下是配置服务器信息的文件,etc\users.properties文件包含连接MQTT服务器时用到的用户名和密码,后面会介绍,可以修改原始的admin=password,可以接着换行添加新的用户名密码。
3、打开cmd,运行…apache-apollo-1.6\bin\mybroker\bin\apollo-broker.cmd run 开启服务器,可以在浏览器中输入 http://127.0.0.1:61680/ 查看是否安装成功,该界面展示了topic,连接数等很多信息。
经过上面的简单步骤,服务器基本上就已经完成,下一篇将介绍Android客户端的编写和注意事项。
客户端使用的API,开始我使用的是mqtt-client,使用过后发现问题百出,不能很好的满足要求,后来使用了官方推荐的 Eclipse Paho ,下面开始客户端代码的编写,为了方便测试这里有android和j2se两个工程:
1、新建android工程MQTTClient
2、MainActivity代码如下:
[java] view plainprint?
package ldw.mqttclient;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheledExecutorService;
import java.util.concurrent.TimeUnit;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView resultTv;
private String host = "tcp://127.0.0.1:1883";
private String userName = "admin";
private String passWord = "password";
private Handler handler;
private MqttClient client;
private String myTopic = "test/topic";
private MqttConnectOptions options;
private ScheledExecutorService scheler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
resultTv = (TextView) findViewById(R.id.result);
init();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == 1) {
Toast.makeText(MainActivity.this, (String) msg.obj,
Toast.LENGTH_SHORT).show();
System.out.println("-----------------------------");
} else if(msg.what == 2) {
Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
try {
client.subscribe(myTopic, 1);
} catch (Exception e) {
e.printStackTrace();
}
} else if(msg.what == 3) {
Toast.makeText(MainActivity.this, "连接失败,系统正在重连", Toast.LENGTH_SHORT).show();
}
}
};
startReconnect();
}
private void startReconnect() {
scheler = Executors.();
scheler.scheleAtFixedRate(new Runnable() {
@Override
public void run() {
if(!client.isConnected()) {
connect();
}
}
}, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
}
private void init() {
try {
//host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
client = new MqttClient(host, "test",
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);
//设置回调
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
//连接丢失后,一般在这里面进行重连
System.out.println("connectionLost----------");
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
//publish后会执行到这里
System.out.println("deliveryComplete---------"
+ token.isComplete());
}
@Override
public void messageArrived(String topicName, MqttMessage message)
throws Exception {
//subscribe后得到的消息会执行到这里面
System.out.println("messageArrived----------");
Message msg = new Message();
msg.what = 1;
msg.obj = topicName+"---"+message.toString();
handler.sendMessage(msg);
}
});
// connect();
} catch (Exception e) {
e.printStackTrace();
}
}
private void connect() {
new Thread(new Runnable() {
@Override
public void run() {
try {
client.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();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(client != null && keyCode == KeyEvent.KEYCODE_BACK) {
try {
client.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
scheler.shutdown();
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
}
由于项目需要,我用到了心跳重连。根据 这里 的解释设置apollo.xml,主要有设置主机连接的地址。另外,options还有个setWill方法,如果项目中需要知道客户端是否掉线可以调用该方法。
㈦ MQTT在Android中的使用
MQTT 是一种基于发布订阅模型的即时通讯协议,主要应用于物联网设备中
MQTT主要需要MQ服务器地址、用户名、密码、发布主题和响应主题,以及客户端唯一标识
使用方法:
为了防止内存泄漏,我们使用Application的Context
㈧ 怎么实现服务器给android客户端主动推送消息
采用MQTT协议实现Android推送功能是一种解决方案。MQTT是一个轻量级的消息发布/订阅协议,是实现基于手机客户端的消息推送服务器的理想解决方案。
常见的解决方案实现原理:
1、轮询(Pull)方式:客户端定时向服务器发送询问消息,一旦服务器有变化则立即同步消息。
2、SMS(Push)方式:通过拦截SMS消息并且解析消息内容来了解服务器的命令,但这种方式一般用户在经济上很难承受。
3、持久连接(Push)方式:客户端和服务器之间建立长久连接,这样就可以实现消息的及时行和实时性。
(8)androidmqtt客户端扩展阅读:
推送消息注意事项:
1、支持第三方推送内容,是要客户端和服务器都支持的,客户端和服务器都导入推送SDK。
2、服务器推送内容,可以精确指定推送时间,推送的具体接收人,用户群,位置。
3、即推送的维度可以使时间,位置,人群。
4、极光使用了两种不同的通知方式,一种是推送通知,一种是推送消息。
5、如果要使用androidpn,则还需要做大量的工作,需要理解XMPP协议、理解Androidpn的实现机制,需要调试内部存在的BUG。
参考资料来源:网络-服务器
参考资料来源:网络-Android客户端
参考资料来源:网络-信息推送
㈨ 为什么每份 Android 简历都说 “熟悉 MQTT 协议”
MQTT (Message Queuing Telemetry Transport,消息队列遥测传输) 是一种基于 TCP/IP 协议族的应用层协议。MQTT 协议是专门针对硬件性能低下 & 网络状况不稳定的场景设计的,这使得 MQTT 在物联网和移动应用等受限场景得到广泛应用。
目前,MQTT 主要分为两个大版本:
物联网和移动应用场景的特点是硬件性能低下和网络状况不稳定,而 MQTT 协议就是专门针对这种环境设计的,主要在四个方面有优势:
结论:这三种协议并没有绝对的优胜者,最好的协议取决于具体的需求和限制条件。但如果只从带宽、电池、功能多样性这些基本条件看,MQTT 在其中是更占优的选择。
MQTT 协议的设计特性中包含了一项 “高可靠性交付”,它需要一个保证可靠的底层传输层协议,因此 TCP 协议、TLS 协议、WebSocket 协议都可以作为 MQTT 的底层协议。而无连接的 UDP 协议会丢失或重排数据,不能满足 MQTT 协议的传输需要。
MQTT 是基于发布 - 订阅模型 (pub/sub) 的消息传递协议,与请求 - 响应模型不同,发布 - 订阅模型主要有三种角色: publisher & subscriber & subscriber :
当 client 发布某个主题的消息时,broker 会将该消息分发给任何已订阅该主题的 client。通常来说,client 不会存储消息,一旦消息被发送到这些 client,消息就会从 broker 上删除。另外,保留消息、持久连接和服务质量 QoS 可能会导致消息临时存储在 broker 上。
发布 - 订阅模式使得 消息的发布者和订阅者解耦 ,主要体现为空间解耦和时间解耦:
图片引用自 https://juejin.cn/post/6976441705067184135 —— cxuan 着
一个 MQTT 消息由三部分组成:
1、固定报头: 每一个 MQTT 消息都包含一个固定报头,包含消息类型、标志位和剩余长度三个部分。固定报头长度为 2 ~ 5 字节,具体取决于 “剩余长度” 的大小,格式如下:
2、可变报头: 不同消息的可变报头内容不一样,不过其中有一个比较通用的字段:
3、载荷: 某些 MQTT 消息会包含一个有效载荷,对于 PUBLISH 消息来说,有效载荷就是应用消息。
MQTT 的连接总是发生在 client 和 broker 之间,两个 client 之间不会互相感知。请求连接时,client 会向 broker 发送 CONNECT 连接消息,broker 接受连接后会响应 CONNACK 连接确认消息。一旦连接建立,连接会一直保持打开状态,直到 client 发送 DISCONNECT 断开连接消息或连接异常中断。
CONNECT 是 client 发送给 broker 的首个消息,并且在一次连接中,client 只能发送一次 CONNECT 消息,发送的第二个 CONNECT 消息会被 broker 当作违反协议处理,并断开连接。在 CONNECT 消息中,主要包含以下内容:
CONNACK 消息用于确认 CONNECT 消息。CONNECT 是 client 发送给 broker 的首个消息,相应地,broker 发送给 client 的首个消息一定是 CONNACK 消息。在 CONNACK 消息中,主要包含以下内容:
DISCONNECT 消息由 client 发送给 broker,用于断开连接。 DISCONNECT 消息没有可变报头和有效载荷,也没有对应的确认应答消息,表示一个干净利索地断开连接操作 。断开连接后,client 不能再发送除 CONNECT 消息之外的消息,broker 也需要丢弃和当前会话有环的遗嘱消息。
MQTT 是基于发布订阅模型的协议,在建立连接后,client 可以向 broker 订阅感兴趣的一个或多个话题。
SUBSCRIBE 消息由 client 发送给 broker,用于订阅感兴趣的话题,SUBSCRIBE 消息主要包含以下内容:
SUBACK 消息用于确认 SUBSCRIBE 消息。SUBACK 消息主要包含以下内容:
UNSUBSCRIBE 消息由 client 发送给 broker,用于退订不感兴趣的话题,UNSUBSCRIBE 消息主要包含以下内容:
UNSUBACK 消息用于确认 UNSUBSCRIBE 消息。UNSUBACK 消息非常简单,只有一个包唯一标识(位于可变报头)。
当 MQTT client 在连接到 broker 之后就可以发送消息了,每条 PUBLISH 消息都包含一个 topic ,broker 会根据 topic 将消息发送给感兴趣的 client。除此之外,每条消息还会包含一个 Payload,Payload 是真正发布的应用消息,载荷的内容和格式由应用层决定,MQTT 协议层不关心。
PUBLISH 消息可以由 client 发送给 broker,也可以由 broker 发送给 client,用来运送应用层消息。PUBLISH 消息主要包含以下内容:
PUBLISH 消息的接收方需要发送确认应答,不同 QoS 等级的 PUBLISH 消息响应的消息不同:
当 client 和 broker 在一段时间内没有数据交互时,client 会发送 PINGREQ 探测消息,用于判断连接是否正常,来决定是否要关闭该连接,这就是 MQTT 协议的保活机制。
PINGREQ 消息由 client 发送给 broker。
PINGRESP 消息由 broker 发送给 client,代表 client 是存活的。
MQTT 主题本质上是一种 “寻址形式” ,用于将应用层消息分发到期望的客户端。MQTT 主题是一种类似于文件系统的分层结构,使用 “/” 正斜杠 作为分隔符。
客户端订阅主题时,可以订阅确定的主题(例如 “group/group123”),也可以使用 “通配符” 来同时订阅多个主题。需要注意的是: 在发布消息是不允许使用主题通配符,client 每次发布消息只能发布到单个主题。
$SYS 主题是 broker 上默认创建的只读主题,除此之外,broker 不会默认创建任何主题,所有主题都是由客户端订阅或发布才创建的,都不是永久性的。关于 $SYS 主题的更多介绍在 这里
当 client 连接到 broker 时,可以使用持久连接或非持久连接,这是通过 CONNECT 消息中的 CleanSession 标志来决定的(当 CleanSession = 0 时表示持久连接)。对于持久会话,broker 会存储会话状态;而对于非持久会话,broker 不会存储 client 的任何内容。会话状态主要包含以下内容:
QoS 0 等级的 PUBLISH 消息的交付能力完全依赖于底层传输层,QoS 1 和 QoS 2 等级开始在应用层提高 PUBLISH 消息的交付能力。当消息丢失时,发送端会重新发送早前尝试发送过的 PUBLISH 消息(DUP = 1),接收者收到消息也会发送确认响应消息。
在 QoS 0 的等级的 PUBLISH 消息中不包含包唯一标识。发送者不考虑消息交付结果,接收者也不发送响应。接收者最多只能收到一次消息,也有可能一次也收不到。
在 QoS 1 等级的 PUBLISH 消息中包含包唯一标识,发送方会一直将该消息当作 “未确认” 的消息,直到收到对应的 PUBACK 确认消息。具体消息流如下:
QoS 2 是最高的服务质量,保证消息不会丢失也不会重复,缺点是会增加开销。在 QoS 2 等级的 PUBLISH 消息中包含包唯一标识,发送者会一直将该消息当作 “未确认” 的消息,知道收到对应的 PUBCOMP 确认消息。
当 client 发布某个主题的消息时,broker 会将该消息分发给任何已订阅该主题的 client,随后这条消息会从 broker 上删除。可以设置 RETAIN 保留标志设置该 PUBLISH 消息为保留消息,broker 会存储该主题的最后一条保留消息,当新的 client 注册订阅时,并且匹配该消息主题时,该保留消息会发送给订阅者。 需要注意:broker 只会为每个主题保存最近一条保留消息,新收到的 RETAIN = 1 的消息会覆盖原本那条保留消息;
持久会话 & 服务质量等级 & 保留消息都会影响新订阅者是否接受消息,总结如下表:
标记 DUP = 1 的消息是重复发送的消息,MQTT 消息重传有两种场景:
需要注意:DUP 标志只对 OoS > 0 的消息有效,所有 QoS = 0 的消息 DUP 标志必须设置为 0;
TCP 协议的报文重传机制是对所有 TCP 报文有效的重传机制,而 MQTT 协议的消息重传机制只对一小部分消息有效,用于实现更可靠的消息交付保证。虽然 TCP 协议在一般情况下可以保证不丢包,但是这并不是绝对的,依然存在请求超时或者连接中断等情况。而 MQTT 协议的 QoS 1 和 QoS 2 要求更可靠的交付能力,并且需要在客户端重连后也能保证交付。因此,MQTT 协议也定义了一个消息重传机制。
到这里,关于 MQTT 协议的工作原理 & 协议消息格式 & 核心特性等内容就介绍完了。我知道你应该会对 MQTT 协议的实战应用更加感兴趣,下一篇文章里,我将带你实现基于 MQTT 协议的 IM 服务,请关注。