*
* Implementations of this method must release all resources held
* by the plugin such as file handles, database or network connections,
* and references to core Openfire classes. In other words, a
* garbage collection executed after this method is called must be able
* to clean up all plugin classes.
*/
public void destroyPlugin();
该接口的2个方法相对简单,一个初始化,一个销毁。
2.打jar包。包里面的目录格式为:
[pluginDir]
* |-- plugin.xml
* |-- classes/
* |-- lib/
Plugin.xml为配置文件
Classes为插件需要的一些resources文件
Lib则是插件的源代码以及源代码依赖的jar包。
举例我开发一个用户状态发生变化后,把状态值插入到redis服务器中的插件。
1.写代码:
package com.netease.openfire.plugin;
import java.io.File;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.event.SessionEventDispatcher;
import org.jivesoftware.openfire.event.SessionEventListener;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.user.PresenceEventDispatcher;
import org.jivesoftware.openfire.user.PresenceEventListener;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class StatusPlugin implements Plugin, PresenceEventListener,
SessionEventListener {
// private XMPPServer server = XMPPServer.getInstance();
// private PresenceUpdateHandler wpuh;
// private Map
private static JedisPool pool;
static {
GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
poolConfig.maxActive = 30;
poolConfig.minIdle = 30;
poolConfig.minEvictableIdleTimeMillis = 500;
pool = new JedisPool(poolConfig, "192.168.150.53");
}
@Override
public void initializePlugin(PluginManager manager, File pluginDirectory) {
PresenceEventDispatcher.addListener(this);
System.out.println("add PresenceEventListener ok !");
SessionEventDispatcher.addListener(this);
System.out.println("add SessionEventListener ok !");
}
@Override
public void destroyPlugin() {
PresenceEventDispatcher.removeListener(this);
}
private void updateCache(String key, String value) {
Jedis jedis = pool.getResource();
jedis.set(key, value);
pool.returnResource(jedis);
}
@Override
public void availableSession(ClientSession session, Presence presence) {
updateCache(session.getAddress().toFullJID(), presence.getStatus());
}
@Override
public void unavailableSession(ClientSession session, Presence presence) {
updateCache(session.getAddress().toFullJID(), presence.getStatus());
}
@Override
public void presenceChanged(ClientSession session, Presence presence) {
updateCache(session.getAddress().toFullJID(), presence.getStatus());
}
@Override
public void subscribedToPresence(JID subscriberJID, JID authorizerJID) {
// TODO Auto-generated method stub
}
@Override
public void unsubscribedToPresence(JID unsubscriberJID, JID recipientJID) {
// TODO Auto-generated method stub
}
@Override
public void sessionCreated(Session session) {
// TODO Auto-generated method stub
}
@Override
public void sessionDestroyed(Session session) {
updateCache(session.getAddress().toFullJID(),
Presence.Type.unavailable.name());
}
@Override
public void anonymousSessionCreated(Session session) {
// TODO Auto-generated method stub
}
@Override
public void anonymousSessionDestroyed(Session session) {
// TODO Auto-generated method stub
}
@Override
public void resourceBound(Session session) {
// TODO Auto-generated method stub
}
}
2.把源代码打成jar包->status_plugin.jar
3.写plugin.xml配置
最后按照要求打成插件的jar包。
把status_plugin.jar放入到lib目录中。
4.把打出来的插件jar包放到openfire的plugins目录下即可。
5.重启openfire.
六.Openfire开发心得
这里简单介绍下你可以基于openfire做扩展的几种方式。
本人通过2个星期对openfire的学习和部分功能的扩展。总结出集中扩展方式。
1. 通过开发插件配合xxxlistener。因为plugin能做的事情非常有限,只能拿到pluginmanager和xmppserver的实例。假如你有强力功能要开发,可能不是很好搞定。
2. 通过hacker思想,在启动plugin的时候替换xmppserver的module并且重启xmppserver
3. 在build的时候做手脚,动态字节码增强。
总之,openfire虽然具有模块化的思想,并且留给大家一些扩展点。但是没有统一约定扩展点,并且比较凌乱,需要自己仔细阅读源代码来搞定。并且还不一定能做到。不过大家尽量还是通过第一种方式来开发,是在憋不住,就改源代码吧。。
最后希望大家与我多多交流哈。。。[email protected]