文档章节

一步一步开发自己的Openfire插件(IOS推送插件APNS)

wangjie142
 wangjie142
发布于 2015/02/22 14:18
字数 902
阅读 34
收藏 0

使用IOS强大的APNS 和openfire实现IOS推送

开发环境 : win7/eclipse/jdk1.6/mysql5.0/openfire3.7

IOS的推送需要用到3个jar包:  IOS推送APNS必须的三个包

开发步骤 :

源码下载:  http://www.igniterealtime.org/downloads/source.jsp

1. 布署openfire3.7源码      部署方法链接:  Openfire源代码部署

2. src/plugins目录下新建文件夹push。并按下图的目录结构新建对应的文件 。


 

plugin.xml文件代码如下:

<?xml version="1.0" encoding="UTF-8"?><plugin><class>com.d3.push.PushPlugin</class><name>IOSPush</name>  <description>IOS Push</description>  <author>mzh</author>  <version>1.0.0</version>  <date>13/04/2014</date>  <minServerVersion>1.0.0</minServerVersion></plugin>

ChatHistoryInterceptor.java文件代码如下 :

package com.d3.push;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import javapns.devices.Device;import javapns.devices.implementations.basic.BasicDevice;import javapns.notification.AppleNotificationServerBasicImpl;import javapns.notification.PushNotificationManager;import javapns.notification.PushNotificationPayload;import javapns.notification.PushedNotification;import org.apache.commons.lang.StringUtils;import org.jivesoftware.database.DbConnectionManager;import org.jivesoftware.openfire.PresenceManager;import org.jivesoftware.openfire.XMPPServer;import org.jivesoftware.openfire.interceptor.InterceptorManager;import org.jivesoftware.openfire.interceptor.PacketInterceptor;import org.jivesoftware.openfire.interceptor.PacketRejectedException;import org.jivesoftware.openfire.session.Session;import org.jivesoftware.openfire.user.UserManager;import org.jivesoftware.openfire.user.UserNotFoundException;import org.jivesoftware.util.JiveGlobals;import org.xmpp.packet.JID;import org.xmpp.packet.Message;import org.xmpp.packet.Packet;import org.xmpp.packet.Presence;/**
 * <b>function:</b> send offline msg plugin
 * @author MZH
 */public class PushInterceptor implements PacketInterceptor{  //Hook for intercpetorn  private InterceptorManager interceptorManager;   
  private UserManager userManager;  private PresenceManager presenceManager;    public PushInterceptor(){  interceptorManager = InterceptorManager.getInstance();    interceptorManager.addInterceptor(this);    XMPPServer server = XMPPServer.getInstance();    userManager = server.getUserManager();    presenceManager = server.getPresenceManager();   
  }    /**   * intercept message   */  @Override  public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {  if (processed || !(packet instanceof Message) || !incoming || Message.Type.chat != ((Message) packet).getType())return;    this.doAction(packet, incoming, processed, session);  } 
  /**
* <b>send offline msg from this function </b>
*/private void doAction(Packet packet, boolean incoming, boolean processed,
Session session) {
Message message = (Message) packet;
JID recipient = message.getTo();// get messagetry {// if (recipient.getNode() == null// || !UserManager.getInstance().isRegisteredUser(recipient.getNode())) {// // Sender is requesting presence information of an anonymous// //throw new UserNotFoundException("Username is null");// }Presence status = presenceManager.getPresence(userManager.getUser(recipient.getNode()));if (status == null) {  //offlineString deviceToken = getDeviceToken(recipient.getNode());if(isApple(deviceToken))
pns(deviceToken, message.getBody());
}// end if} catch (UserNotFoundException e) {
System.out.println("user not found");// e.printStackTrace();}
}/**
* 判断是否苹果
* @param deviceToken
* @return*/private boolean isApple(String deviceToken){if(deviceToken!=null&&deviceToken.length()>0){return true;
}return false;
}public String getDeviceToken(String userId) {
String deviceToken = "";
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement("SELECT code_ios FROM ofUser where username = ?");
pstmt.setString(1, userId);
rs = pstmt.executeQuery();if (rs.next()) {
deviceToken = rs.getString(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}return deviceToken;
}public void pns(String token, String msg) {
String sound = "default";// 铃音String certificatePath =  JiveGlobals.getProperty("plugin.push.apnsPath","");
String certificatePassword = JiveGlobals.getProperty("plugin.push.apnsKey",""); // 此处注意导出的证书密码不能为空因为空密码会报错boolean isProduct = JiveGlobals.getBooleanProperty("plugin.push.isProduct", false);try {
PushNotificationPayload payLoad = new PushNotificationPayload();
payLoad.addAlert(msg); // 消息内容payLoad.addBadge(1); // iphone应用图标上小红圈上的数值if (!StringUtils.isBlank(sound)) {
payLoad.addSound(sound);// 铃音}
PushNotificationManager pushManager = new PushNotificationManager();// true:表示的是产品发布推送服务 false:表示的是产品测试推送服务pushManager.initializeConnection(new AppleNotificationServerBasicImpl(
certificatePath, certificatePassword, isProduct));// 发送push消息Device device = new BasicDevice();
device.setToken(token);
PushedNotification notification = pushManager.sendNotification(
device, payLoad, true);
pushManager.stopConnection();
} catch (Exception e) {
e.printStackTrace();
}
}


}

ChatHistoryPlugin.java文件代码如下:

package com.d3.push;import java.io.File;import org.jivesoftware.openfire.container.Plugin;import org.jivesoftware.openfire.container.PluginManager;import org.jivesoftware.openfire.interceptor.InterceptorManager;public class PushPlugin implements Plugin {private PushInterceptor pushInterceptor = null; 


@Overridepublic void destroyPlugin() {if(pushInterceptor != null){
InterceptorManager.getInstance().removeInterceptor(pushInterceptor);
}
}@Overridepublic void initializePlugin(PluginManager manager, File pluginDirectory) {
pushInterceptor = new PushInterceptor();
InterceptorManager.getInstance().addInterceptor(pushInterceptor);
}


}

3.打包插件

a.第一次打包需配置ant工具。在环境变量中 ,

添加 path=C:\Program Files\Java\jdk1.5.0_09\;D:\Program Files\MyEclipse6.5\eclipse\plugins\org.apache.ant_1.7.0.v200706080842\bin (如果原来有path,在变量值的尾部添加半角分号 ; 然后再加入上面的jdk和ant路径 )

b.编译

进入cmd,进入 openfire/build所在目录:输入命令:ant plugins 等待执行完,而且没有报错,说明打包成功。在openfire3.6.3\target\openfire\plugins目录下就生成了push.jar

4.测试

启动openfire ,没有报错,一切OK。  

如果是通过源码直接运行,在openfire_src\work\lib  下添加三个apns的包

如果是直接用openfire.exe运行, 在Openfire\lib  下添加三个包 ,然后登陆控制台加入插件push

最后记得在mysql的ofproperty里加入三个参数值

add plugin.push.apnsPathPath ,      p12文件路径

plugin.push.apnsPathKey,                    密码

plugin.push.isProduct to ofProperty           是否正式发布

用户需要有个字段判断是否有token 


本文转载自: http://blog.csdn.net/maple1320/article/details/24260513

共有 人打赏支持
wangjie142
粉丝 5
博文 12
码字总数 7731
作品 0
无锡
程序员
私信 提问
iOS 消息推送原理及实现总结

一、消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图: 1、 Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Provide...

mahb520
2013/05/08
0
1
iOS开发系列--通知与消息机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jianxin160/article/details/47753239 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果...

KenshinCui
2015/08/18
0
0
iOS开发系列--通知与消息机制

概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情。iOS中通知机制又叫消息机制,其包...

TomatosX
2015/03/19
0
0
转:基于IOS上MDM技术相关资料整理及汇总

一、MDM相关知识: MDM (Mobile Device Management ),即移动设备管理。在21世纪的今天,数据是企业宝贵的资产,安全问题更是重中之重,在移动互联网时代,员工个人的设备接入企业网络并查...

移动互联百科
2013/10/06
0
0
软件架构杂谈(三) --- APNS

浅谈软件架构(三) —— APNS ----cnyinlinux 本文将讨论的是常见软件架构中的三角关系——APNS。 APNS是Apple Push Notification Service的简称,即苹果推送通知服务。它用在当前很火热的苹果...

cnyinlinux
2015/06/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

剖析Elasticsearch的IndexSorting:一种查询性能优化利器

摘要: 前言 前两周写过一篇《基于Lucene查询原理分析Elasticsearch的性能》,在最后留了一个彩蛋,说下一篇会介绍一种可以极大的优化查询性能的技术。本文就来介绍这种技术——IndexSortin...

阿里云官方博客
42分钟前
1
0
Go 使用channel控制并发

前言 channel一般用于协程之间的通信,channel也可以用于并发控制。比如主协程启动N个子协程,主协程等待所有子协程退出后再继续后续流程,这种场景下channel也可轻易实现。 场景示例 总结 ...

恋恋美食
今天
3
0
斐波那契堆的理解,节点mark属性和势函数

斐波那契堆 看了好多博客,都是照搬算法导论的内容,没有自己的理解,比如为什么有mark属性,势函数的作用,以及为什么叫斐波那契堆,下面说说鄙人的理解。 势函数 势函数是根节点个数加上2...

杨喆
今天
7
0
NIO源码详解

阻塞io和无阻塞io: 阻塞io是指jdk1.4之前版本面向流的io,服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒 ...

沉稳2018
今天
2
0
如何把已经提交的commit, 从一个分支放到另一个分支

在本地master提交了一个commit(8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f),如何提交的test_2分之上? git checkout test_2git cherry-pick 8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f......

stephen_wu
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部