openfire插件最佳實踐(四)離線消息推送ios服務器

要實現離線消息推送服務器端
閱讀openfire源碼後發現,如果要實現離線消息推送服務器端,我們必須找到
1)接收信息廣播,並且經過一些列的處理(和源代碼相同邏輯),最終到達我們要進行推送的邏輯
2)在存儲離線消息的位置發出自定義iq,自定義插件對iq進行處理,到達我們的推送邏輯
3)使用數據庫觸發器,數據庫中有離線消息存儲就觸發調用遠程java方法,從而到達我們的推送邏輯
 
 
 
(1)    經過閱讀源碼,發現其發送廣播的位置過早,如果要接收廣播並進行一些列處理的話,邏輯過於複雜
(2)    這種方法會造成修改openfire源碼,不便於openfire升級
(3)    這種方法會增大數據庫壓力,同時需要使用c來寫一個mysql擴展,來實現發送未讀消息信息到推送邏輯的過程。
 
最終確定試驗(2)(3)兩種方案
 
推送邏輯:
jiddeviceid 存儲於一個自定義表中
每次用戶登錄會把自己的jiddeviceid存儲到表中
推送數據:
根據message中的jid和從表中獲取到相對應的deviceid,組成push條件,推送消息,推送的消息必須進行處理,將以前約定的特殊標誌串去除,分別是文本、圖片、音頻


下面講解最終實現方案。

個人與個人聊天記錄存儲在ofoffline表中,羣組聊天記錄存儲在緩存中,兩種實現方案不一致,因此需要在兩個位置進行自定義聊天記錄IQ發送


定位後:
個人聊天插入點:OfflineMessageStore.addMessage
羣聊插入點:LocalMUCUser.process

插入方式:將發送iq 的複雜邏輯提取成一個工程,在openfire源碼使用時引用jar包。
相關iq接收處理:
(1)接收設備信息:

<iq id="***" type="set"from="***">

  <query xmlns="***">

         <username>111</username>

        <method>store</method>

        <token>sdsdsd</token>

        <type>1</type>

        <language>zh</language>

</query>

</iq>


刪除iq

<iq id="***" type="set" from="***">

  <query xmlns="***">

         <username>111</username>

        <method>del</method>

</query>

</iq>

(2)在處理離線消息位置插入自定義iq發送

	public void sendPushIQ(String username,String body){
		PacketRouter packetRouter = XMPPServer.getInstance().getPacketRouter();
    	IQ reply = new IQ();
    	reply.setType(Type.set);
    	Element probeResult =  DocumentHelper.createElement(QName.get("query", "******")) ;
		probeResult.addElement("username").setText(username);
		probeResult.addElement("body").setText(body);
		reply.setChildElement(probeResult);
    	        packetRouter.route(reply);
	}


(3)自定義插件接收自定義iq,進行處理:
其中ios推送的代碼如下
public static void push( String deviceToken,String content){
		try {

            //被推送的iphone應用程序標示符      
            PayLoad payLoad = new PayLoad();
            payLoad.addAlert(content);
            payLoad.addBadge(1);
            payLoad.addSound("default");
                     
            PushNotificationManager pushManager = PushNotificationManager.getInstance();
            pushManager.addDevice("iphone", deviceToken);
           
         //Device c = pushManager.getDevice("iphone");
            String host= "gateway.sandbox.push.apple.com";  //測試用的蘋果推送服務器
            int port = 2195;
            //注意在linux中插件路徑問題

        
            String certificatePath = "E:/***.p12";
            String certificatePassword= "***";
            pushManager.initializeConnection(host, port, certificatePath,certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);//初始化tcp連接
                      
            //Send Push
            Device client = pushManager.getDevice("iphone");
            pushManager.sendNotification(client, payLoad); //推送消息
            pushManager.stopConnection();
            pushManager.removeDevice("iphone");
           }
           catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
           }
           System.out.println("push succeed!");

	}









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章