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!");

	}









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