mqtt的连接、订阅、发布:
依赖库:compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2'
/**
* Created by Administrator on 2017/2/23.
* 支持mqtt连接,断开,订阅,发布,添加和移除监听器
*/
public class MqttManager {
private static final String TAG = MqttManager.class.getSimpleName();
private static MqttManager instance = null;
private MqttClientControl mqttClientControl;
private MqttResponseCallbackManager mqttResponseCallbackManager;
// private String createTime;
private MqttManager() {
// createTime = TimeUtils.date2String(TimeUtils.getNowDate());
mqttClientControl = new MqttClientControl();
mqttResponseCallbackManager = new MqttResponseCallbackManager();
}
public static MqttManager getInstance() {
if (instance == null) {
instance = new MqttManager();
}
return instance;
}
void addCallback(MqttResponseCallback callback) {
mqttResponseCallbackManager.addCallback(callback);
}
void removeCallback(MqttResponseCallback callback) {
mqttResponseCallbackManager.removeCallback(callback);
}
//订阅到服务器
public void mqttConn() {
mqttClientControl.mqttConn();
}
//断开
public void mqttDisConn() {
mqttClientControl.disConn();
}
//订阅到服务器
public void mqttSubscribe(String subscribeTopic) {
mqttClientControl.mqttSubscribe(subscribeTopic);
}
//发布到服务器
public void mqttPublish(String publishTopic, String json) {
mqttClientControl.mqttPublish(publishTopic, json);
}
public MqttResponseCallbackManager getMqttResponseCallbackManager() {
return mqttResponseCallbackManager;
}
}
public class MqttClientControl {
private static final String TAG = MqttClientControl.class.getSimpleName();
private MqttClient mqttClient;
private void initMqttClient() throws MqttException {
if (mqttClient != null) {
mqttClient.setCallback(null);
if (mqttClient.isConnected()) {
mqttClient.disconnect();
}
mqttClient = null;
}
MqttBean mqttBean = MqttParamsUtils.getMqttProperties();
mqttClient = new MqttClient(MqttParamsUtils.getMqttServerUrl(mqttBean), mqttBean.getClientID(), new MemoryPersistence());
mqttClient.setCallback(new MyMqttCallback());
}
//连接到到服务器,退出应用前未断开mqtt连接,下次进来时,mqttClient状态为未连接,调用连接的方法时会连接失败,应该是应用上次和服务器的连接还在,退出应用是否要断开
void mqttConn() {
try {
initMqttClient();
} catch (MqttException e) {
e.printStackTrace();
}
doConnect();
}
void disConn() {
try {
mqttClient.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
mqttClient.setCallback(null);
mqttClient = null;
}
private void doConnect() {
try {
// LogUtils.d(TAG, "mqttComm-------------->mqtt正在连接");
mqttClient.connect(MqttParamsUtils.getConnOpts());
MqttManager.getInstance().getMqttResponseCallbackManager().onConnectionSuccess();
MqttReconnectManager.getInstance().onConnectionSuccess();
// LogUtils.d(TAG, "mqttComm-------------->mqtt连接成功");
} catch (MqttException e) {
e.printStackTrace();
// LogUtils.d(TAG, "mqttComm-------------->mqtt连接失败");
MqttManager.getInstance().getMqttResponseCallbackManager().onConnectionFailed(e);
}
}
//订阅到服务器
void mqttSubscribe(String subscribeTopic) {
try {
mqttClient.subscribe(subscribeTopic, 1);
// LogUtils.d(TAG, "订阅成功");
} catch (MqttException e) {
e.printStackTrace();
}
}
//发布到服务器
void mqttPublish(String publishTopic, String json) {
// LogUtils.d(TAG, "mqtt发送json---------------->" + json);
MqttMessage message = new MqttMessage(json.getBytes());
message.setQos(1);
try {
mqttClient.publish(publishTopic, message);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
回调接口管理:
public class MqttResponseCallbackManager {
private Set<MqttResponseCallback> mqttResponseCallbacks;
public MqttResponseCallbackManager() {
init();
}
public void onConnectionSuccess() {
for (MqttResponseCallback callback : mqttResponseCallbacks) {
callback.onConnectionSuccess();
}
}
private void init() {
mqttResponseCallbacks = new HashSet<>();
}
public void addCallback(MqttResponseCallback callback) {
mqttResponseCallbacks.add(callback);
}
public void removeCallback(MqttResponseCallback callback) {
mqttResponseCallbacks.remove(callback);
}
public void onSendSuccess(IMqttDeliveryToken token) {
for (MqttResponseCallback callback : mqttResponseCallbacks) {
callback.onSendSuccess(token);
}
}
public void onMqttResponse(String topic, MqttMessage message) {
for (MqttResponseCallback callback : mqttResponseCallbacks) {
callback.onMqttResponse(topic, message);
}
}
public void onConnectionLost(Throwable cause) {
for (MqttResponseCallback callback : mqttResponseCallbacks) {
callback.onConnectionLost(cause);
}
}
public void onConnectionFailed(MqttException e) {
for (MqttResponseCallback callback : mqttResponseCallbacks) {
callback.onConnectionFailed(e);
}
}
}
public abstract class MqttResponseCallback {
public abstract void onSendSuccess(IMqttDeliveryToken token);
public abstract void onMqttResponse(String topic, MqttMessage message);
public void onConnectionLost(Throwable cause) {
}
public void onConnectionFailed(MqttException e) {
}
public void onConnectionSuccess() {
}
}
mqtt接收消息,注册和注销回调接口处理
public abstract class MqttReceiveMsgControl {
private static final String TAG = MqttReceiveMsgControl.class.getSimpleName();
private MqttResponseCallback callback = new MqttResponseCallback() {
@Override
public void onSendSuccess(IMqttDeliveryToken token) {
LogUtils.d(TAG, "发送成功-----------》" + token.getMessageId());
}
@Override
public void onMqttResponse(String topic, MqttMessage message) {
// Charset charset = Charset.forName("GB2312");
Charset charset = Charset.forName("UTF-8");
String msg = new String(message.getPayload(), charset);
LogUtils.d(TAG, "返回的消息主题----------》" + topic);
LogUtils.d(TAG, "返回的消息内容----------》" + msg);
MqttResponseMsgHandler mqttResponseMsgHandler = new MqttResponseMsgHandler(topic, msg);
MqttReceiveMsgControl.this.onMqttResponse(mqttResponseMsgHandler);
}
@Override
public void onConnectionLost(Throwable cause) {
onMqttConnectionLost(cause);
}
@Override
public void onConnectionFailed(MqttException e) {
onMqttConnectionFailed(e);
}
@Override
public void onConnectionSuccess() {
onMqttConnectionSuccess();
}
};
public void onMqttConnectionSuccess() {
}
public void onMqttConnectionLost(Throwable cause) {
}
public void onMqttConnectionFailed(MqttException e) {
}
protected abstract void onMqttResponse(MqttResponseMsgHandler mqttResponseMsgHandler);
public MqttReceiveMsgControl() {
MqttManager.getInstance().addCallback(callback);
}
public void addCallback() {
MqttManager.getInstance().addCallback(callback);
}
public void removeCallback() {
MqttManager.getInstance().removeCallback(callback);
}
public void mqttPublish(DeviceInfo deviceInfo, String json) {
MqttManager.getInstance().mqttPublish(MqttUtils.getPublishTopic(deviceInfo), json);
}
}
mqtt重连
public class MqttReconnectManager {
private static MqttReconnectManager mInstance;
private MqttReconnectManager() {
}
public static MqttReconnectManager getInstance() {
if (mInstance == null) {
synchronized (MqttReconnectManager.class) {
if (mInstance == null) {
mInstance = new MqttReconnectManager();
}
}
}
return mInstance;
}
private TimeoutControl timeoutControl = new TimeoutControl() {
@Override
protected void onTimeout() {
String loginId = LoginDataSource.getINSTANCE().getLoginId();
String powerKey = LoginDataSource.getINSTANCE().getPowerKey();
LoginDataSource.getINSTANCE().login(loginId, powerKey, LOGIN_TYPE_LOGINID_POWERKEY, "10",
new ResponseHandler.ResponseCallback<String>() {
@Override
public void onError(ResponseHandler<String> responseHandler) {
if (LoginPowerKeyErrorControl.isPowerKeyError(responseHandler)) {
} else {
ToastUtils.showShort(responseHandler.getErrorMsg());
}
}
@Override
public void onResponse(ResponseHandler<String> responseHandler) {
connect();
}
});
}
};
void connectionLost(Throwable cause) {
LoginDataSource loginDataSource = LoginDataSource.getINSTANCE();
if(TextUtils.isEmpty(loginDataSource.getPowerKey())){
return;
}
if(TextUtils.isEmpty(loginDataSource.getCacheData().getMqtt_ip())){
return;
}
if (NetworkUtils.isConnected()) {
connect();
}
}
private boolean connectToggle = true;
private void connect() {
timeoutControl.stopAllTimeouts();
timeoutControl.startTimeout(1000 * 15);
connectToggle = true;
for (int i = 0; i < 5; i++) {
if (!connectToggle) {
return;
}
LogUtils.d("mqtt断开重连-----------》"+i+"次");
MqttManager.getInstance().mqttConn();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void onConnectionSuccess() {
MqttManager.getInstance().mqttSubscribe(LoginDataSource.getINSTANCE().getCacheData().getMqtt_url_sub());
timeoutControl.stopAllTimeouts();
connectToggle = false;
}
}
mqtt协议处理(根据自己公司的业务):
public class MqttResponseMsgHandler {
private static final String TAG = MqttResponseMsgHandler.class.getSimpleName();
private String topic;
private String msg;
private List<MqttData> data;
private MqttMsgBean mqttMsgBean;
public MqttResponseMsgHandler(String topic, String msg) {
this.topic = topic;
this.msg = msg;
parse();
}
private void parse() {
mqttMsgBean = JsonUtils.fromJson(msg, MqttMsgBean.class);
data = mqttMsgBean.getData();
}
public String getDt(int index) {
return data.get(index).getDt();
}
public <T> T getDa(int index, Class<T> tClass) {
String json = JsonUtils.objectToJson(data.get(index).getDa());
return JsonUtils.fromJson(json, tClass);
}
public <T> List<T> getDaList(int index, Class<T> tClass) {
String jsonArrayStr = JsonUtils.objectToJson(data.get(index).getDa());
return JsonUtils.fromJsonArray(jsonArrayStr, tClass);
}
public MqttMsgBean getMqttMsgBean() {
return mqttMsgBean;
}
}
public class MqttData {
String dt;
Object da;//这个字段用的很精妙,Gson可以对它进行json的序列化,所以不确定的字段可以用Object来定义
public MqttData() {
}
public MqttData(String dt, Object da) {
this.dt = dt;
this.da = da;
}
}
public class MqttMsgBean {
private String pdid;
private String sender;
private String receiver;
private String timestamp;
@SerializedName("return")
private String returnData;
// private String powerkey;
private String password;
private List<MqttData> data;
}
public class MqttSendMsgUtils {
public static String getSendMsg(DeviceInfo deviceInfo, String dt, Object da) {
MqttMsgBean mqttMsgBean = new MqttMsgBean();
LoginResponseInfo cacheData = LoginDataSource.getINSTANCE().getCacheData();
String mqtt_devname = cacheData.getMqtt_devname();
mqttMsgBean.setPdid(deviceInfo.getPdid());
mqttMsgBean.setSender(mqtt_devname);
mqttMsgBean.setReceiver(deviceInfo.getDevname());
mqttMsgBean.setTimestamp(TimeUtils.getNowMills() + "");
mqttMsgBean.setReturnData("");
// mqttMsgBean.setPowerkey(LoginDataSource.getINSTANCE().getPowerKey());
mqttMsgBean.setPassword(cacheData.getMqtt_password());
List<MqttData> datas = new ArrayList<>();
MqttData data = new MqttData();
data.setDt(dt);
data.setDa(da);
datas.add(data);
mqttMsgBean.setData(datas);
String sendJson = JsonUtils.toJson(mqttMsgBean, MqttMsgBean.class);
LogUtils.d("mqtt发布json数据------------》" + sendJson);
return sendJson;
}
/***************************************app下发的mqtt json*****************************************/
public static String getSendMsg1001(DeviceInfo deviceInfo) {
return getSendMsg(deviceInfo, MqttDt.DT_1001, "");
}
public static String getSendMsg11023(DeviceInfo deviceInfo) {
return getSendMsg(deviceInfo, MqttDt.DT_11023, "");
}
public static String getSendMsg11024(DeviceInfo deviceInfo) {
return getSendMsg(deviceInfo, MqttDt.DT_11024, "");
}
public static String getSendMsg21001(DeviceInfo deviceInfo,Object da) {
return getSendMsg(deviceInfo, MqttDt.DT_21001, da);
}
public static String getSendMsg21002(DeviceInfo deviceInfo, Map<String,String> daMap) {
return getSendMsg(deviceInfo, MqttDt.DT_21002, daMap);
}
public static String getSendMsg21012(DeviceInfo deviceInfo) {
MqttDaShutDownBean shutDownBean = new MqttDaShutDownBean();
shutDownBean.setShutdown("yes");
return getSendMsg(deviceInfo, MqttDt.DT_21012, shutDownBean);
}
public static String getSendMsg21013(DeviceInfo deviceInfo) {
MqttDaCancelAlarm cancelAlarm = new MqttDaCancelAlarm();
cancelAlarm.setCanclealarm("yes");
return getSendMsg(deviceInfo, MqttDt.DT_21012, cancelAlarm);
}
/***************************************app下发的mqtt json*****************************************/
}
public class DeviceInfo {
private String pdid;
private String devsn;
private String devname;
private String isdefault;
private String diyname;//自定义设备名称
public DeviceInfo() {
}
public DeviceInfo(String pdid, String devsn, String devname, String diyname) {
this.pdid = pdid;
this.devsn = devsn;
this.devname = devname;
this.diyname = diyname;
}
}