您好,登錄后才能下訂單哦!
在客戶端中,我們在AndroidManifest.xml文件中找到程序入口,即如下的DemoAppActivity類,
在此類中主要代碼如下
ServiceManager serviceManager = new ServiceManager(this);
serviceManager.setNotificationIcon(R.drawable.notification);
serviceManager.startService();
一路跟進(jìn),NotificationService中有個XmppManager類的調(diào)用(xmppManager.connect();),而XmppManager類就是客戶端比較重要的類,有這幾個方法
public void connect() {
Log.d(LOGTAG, "connect()...");
submitLoginTask();
}
private void submitConnectTask() {
Log.d(LOGTAG, "submitConnectTask()...");
addTask(new ConnectTask());
}
private void submitRegisterTask() {
Log.d(LOGTAG, "submitRegisterTask()...");
submitConnectTask();
addTask(new RegisterTask());
}
private void submitLoginTask() {
Log.d(LOGTAG, "submitLoginTask()...");
submitRegisterTask();
addTask(new LoginTask());
}
addTask方法中有一個線程隊列,依次添加連接,注冊和登陸任務(wù)。用runTask方法執(zhí)行這些任務(wù)
在XmppManager類中有三個內(nèi)部類,即連接(ConnectTask),注冊(RegisterTask),登陸(LoginTask)三個線程類。
連接類負(fù)責(zé)與服務(wù)端的連接。
注冊類中,即用UUID生成唯一的username和password,然后把它們保存到SharedPreferences中
final String newUsername = newRandomUUID();
final String newPassword = newRandomUUID();
.....
Editor editor = sharedPrefs.edit();
editor.putString(Constants.XMPP_USERNAME, newUsername);
editor.putString(Constants.XMPP_PASSWORD, newPassword);
editor.commit();
而在登陸類中,首先進(jìn)行連接登陸,把客戶端的信息更新到服務(wù)端,即
xmppManager.getConnection().login(
xmppManager.getUsername(),
xmppManager.getPassword(), XMPP_RESOURCE_NAME);
這個操作可能執(zhí)行多次,直到真正更新到服務(wù)器。
執(zhí)行連接登陸時,服務(wù)端就會收到信息。
在服務(wù)端,接受消息的類是router包(org.androidpn.server.xmpp.router)下的PacketRouter類,在這里分析消息的類型是什么類型,然后在調(diào)用具體的Router,如響應(yīng)登陸的IQRouter。
如果是登陸(即通過唯一的客戶端標(biāo)識獲取的session就是為null的),那么就要對這個包進(jìn)行處理。處理消息包的操作是在 org.androidpn.server.xmpp.handler包下進(jìn)行的。把消息包處理完后就在維護(hù)連接的 org.androidpn.server.xmpp.net包下的Connection類中傳遞消息包到客戶端
XMLWriter xmlSerializer = new XMLWriter(new IoBufferWriter(
buffer, (CharsetEncoder) encoder.get()),
new OutputFormat());
xmlSerializer.write(packet.getElement());
xmlSerializer.flush();
buffer.flip();
ioSession.write(buffer);
如果登陸失敗,就獲取這個異常,重新進(jìn)行登陸連接直到登陸成功。
注冊登錄的流程就如下所述,下面再講一下,在服務(wù)端怎么發(fā)送消息到客戶端,客戶端怎么發(fā)消息到服務(wù)端,客戶端怎么接收來自服務(wù)端的消息(服務(wù)端接收來自客戶端的消息在如下登陸時已經(jīng)講了)
在服務(wù)端的推送消息的頁面中(form.jsp),是通過notification.do?action=send來跳轉(zhuǎn)后臺的,那么這個后臺是哪個類 呢,在web.xml中,我們可以看到,攔截器都是spring的類,即這些都通過spring來托管了,那么我們再打開dispatcher- servlet.xml的spring的配置文件,可以看到
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
/index.do=filenameController
/user.do=userController
/session.do=sessionController
/notification.do=notificationController
notification.do跳轉(zhuǎn)的頁面就是notificationController即org.androidpn.server.console.controller.NotificationController這個類
class="org.androidpn.server.console.controller.NotificationController">
打開NotificationController類發(fā)現(xiàn)它是調(diào)用了NotificationManager
if (broadcast.equalsIgnoreCase("Y")) {
notificationManager.sendBroadcast(apiKey, title, message, uri);
} else {
notificationManager.sendNotifcationToUser(apiKey, username, title,
message, uri);
}
一路跟進(jìn),可以發(fā)現(xiàn)最終發(fā)送消息的類還是Connection的deliver方法。而中間的過程就是解析和生成消息的操作
那么客戶端怎么接受消息呢,這個類應(yīng)該是一個監(jiān)聽器,從類名和在客戶端一路跟進(jìn)的過程中,我們大概可以知道是NotificationPacketListener類,在這個類中獲取各個節(jié)點的值,然后在客戶端上發(fā)送一個通知
那么客戶端發(fā)送消息的類又是在哪個類中呢,我們可以參考服務(wù)端的發(fā)送消息的類是在哪里,沒錯,是在Connection類中,那么我們在客戶端的連接類中 尋找一下是否有發(fā)送消息的類。果然,在org.jivesoftware.smack包下的XMPPConection這個類中有個發(fā)送消息的方法 sendPacket。我們可以通過xmppManager.getConnection()來獲取連接。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。