继上篇的MQTT学习,此篇主要是实现一个安卓客户端,利用activemq服务器,实现安卓客户端之间的推送
首先需要说明客户端的结构
客户端的组成如下:
登录界面,如下图所示
注册界面,如图
推送界面,如图
接收推送显示界面,待会接收消息时演示
界面不重要对吧,关键在于功能,哥界面追求的是精简~~
多说明几点,首先给出整个框架 见下图
图已经很清楚了吧,不需要过多解释
接下来我们把辅助服务器和activeMQ服务器运行起来。辅助服务器是基于tomcat容器的web服务器,因为我们需要验证登录与注册信息,所以我们还需要一个mysql数据库。
我简单的说一下登录注册的原理,代码你们等下可以自己去看。注册与登录相似,因此我就说下登录。客户端把账号密码post给服务器,服务器与数据库相连,服务器用的是一个servlet,使用doget方法,获取账号密码信息,接着把信息与数据库相比较,如果成功,返回一个成功信息给客户端,客户端进入推送界面。
我在后面会把我整个demo贴出来。
好了,让我们进入主题部分,activemq服务器。
客户端我用了wmqtt.jar这个包,里面已经包含了mqtt推送,订阅的函数,相当于提供了接口,只需要合理去使用这个接口就可以了。注意,我要开始放代码了…
private class MQTTConnection implements MqttSimpleCallback {
IMqttClient mqttClient = null;// Creates a new connection given the broker address and initial topic
public MQTTConnection(String brokerHostName, String initTopic) throws MqttException {
String pushMessage =mPrefs.getString(Message, null);
String Obj =mPrefs.getString(Object, null);
int whichkey =mPrefs.getInt(WhichKey, 0);
initTopic = mPrefs.getString(SubTopic, null);
if(whichkey==5&&initTopic.equals("")){
Toast.makeText(getApplicationContext(), "订阅主题为空", Toast.LENGTH_SHORT).show();
stop();
stopSelf();
return;
}
if(whichkey==3&&(pushMessage.equals("")||Obj.equals(""))){
Toast.makeText(getApplicationContext(), "消息或主题为空", Toast.LENGTH_SHORT).show();
stop();
stopSelf();
return;
}else{
// Create connection spec
String mqttConnSpec = "tcp://" + brokerHostName + "@" + MQTT_BROKER_PORT_NUM;
// Create the client and connect
mqttClient = MqttClient.createMqttClient(mqttConnSpec, MQTT_PERSISTENCE);
String clientID = MQTT_CLIENT_ID + "/" + mPrefs.getString(PREF_DEVICE_ID, "");
//String clientID = mPrefs.getString(SubTopic, "");
mqttClient.connect(clientID, MQTT_CLEAN_START, MQTT_KEEP_ALIVE);
// register this client app has being able to receive messages
mqttClient.registerSimpleHandler(this);
// Subscribe to an initial topic, which is combination of client ID and device ID.
//initTopic = MQTT_CLIENT_ID + "/" + initTopic;
//说明一下,whichkey==3说明是推送按钮
if(whichkey==3){
publishToTopic(Obj,pushMessage);
onDestroy();
Log.d("hi", pushMessage);
} //这里是订阅按钮
if(whichkey==5&&!initTopic.equals("")){
subscribeToTopic(initTopic);
}
//取消订阅按钮
if(whichkey==6){
UnsubscribeToTopic(initTopic);
}
log("Connection established to " + brokerHostName + " on topic " + initTopic);
// Save start time
mStartTime = System.currentTimeMillis();
// Star the keep-alives
startKeepAlives();
setStarted(true);
}
}
// Disconnect
public void disconnect() {
try {
stopKeepAlives();
mqttClient.disconnect();
} catch (MqttPersistenceException e) {
log("MqttException" + (e.getMessage() != null? e.getMessage():" NULL"), e);
}
}
/*
* Send a request to the message broker to be sent messages published with
* the specified topic name. Wildcards are allowed.
*/
private void subscribeToTopic(String topicName) throws MqttException {
if ((mqttClient == null) || (mqttClient.isConnected() == false)) {
// quick sanity check - don't try and subscribe if we don't have
// a connection
log("Connection error" + "No connection");
} else {
String[] topics = { topicName };
mqttClient.subscribe(topics, MQTT_QUALITIES_OF_SERVICE);
}
}
private void UnsubscribeToTopic(String topicName) throws MqttException {
if ((mqttClient == null) || (mqttClient.isConnected() == false)) {
// quick sanity check - don't try and subscribe if we don't have
// a connection
log("Connection error" + "No connection");
} else {
String[] topics = { topicName };
mqttClient.unsubscribe(topics);
}
}
/*
* Sends a message to the message broker, requesting that it be published
* to the specified topic.
*/
private void publishToTopic(String topicName, String message) throws MqttException {
if ((mqttClient == null) || (mqttClient.isConnected() == false)) {
// quick sanity check - don't try and publish if we don't have
// a connection
log("No connection to public to");
} else {
mqttClient.publish(topicName,
message.getBytes(),
MQTT_QUALITY_OF_SERVICE,
MQTT_RETAINED_PUBLISH);
log("");
}
}
/*
* Called if the application loses it's connection to the message broker.
*/
public void connectionLost() throws Exception {
log("Loss of connection" + "connection downed");
stopKeepAlives();
// null itself
mConnection = null;
if (isNetworkAvailable() == true) {
reconnectIfNecessary();
}
}
/*
* Called when we receive a message from the message broker.
*/
@Override
public void publishArrived(String topicName, byte[] payload, int qos, boolean retained) {
// Show a notification
String s="";
try {
s = new String(payload,"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
showNotification(s);
log("Got message: " + s);
}
public void sendKeepAlive() throws MqttException {
log("Sending keep alive");
// publish to a keep-alive topic
publishToTopic(MQTT_CLIENT_ID + "/keepalive", mPrefs.getString(PREF_DEVICE_ID, ""));
}
}
核心就是这部分了,应该很容易看懂吧,OK,让我们把整个流程运行一遍吧
首先确认你的两个服务器,以及mysql数据库都开了
1.我们在两个手机上都下载了我们的客户端,并且让我们两个手机都处于一个网段,这里的服务器和数据库都在我电脑上,我电脑开了一个猎豹wifi,让两个手机都连上这个wifi,这样两个手机处于一个网段,接着你得查一下,你电脑的ip,我这里是192.168.191.1,如果你的不是,你得在客户端相应的位置修改,如果你运行的时候连不上服务器,估计就是这里没修改的原因。
2.现在客户端应该连上服务器了,让我们首先注册一个账号吧(说明一下,这里的登录注册不是我研究的重点,因此我只是简单的把注册信息放到数据库,登录时候再比较下,所以没做验重之类的东西)
点击sign me up,然后注册成功,现在来登录
可以选择记住密码功能,方便下次再登录。
3.接着可以看到进入了推送画面
我们订阅主题 mqttTest
4.然后我们用另外一个手机向这个手机发送一条消息 hello world
5.在原来的手机可以看到收到一条通知
点开
好了其他的功能你们可以自己慢慢去试,去加。
demo地址:
http://pan.baidu.com/s/1pL9ZMbD
有任何问题可以留言!