openfire插件开发
OpenFire源码学习之二十:在openfire中使用redis插件(下)
OpenFire源码学习之二十:在openfire中使用redis插件(下)Redis插件实现首先来看下插件目录:RedisServicePlugin源码清单:[java] view plain copyprint?1.import java.io.File;2.import java.sql.Connection;3.import java.sql.PreparedStatement;4.import java.util.Collection;5.import java.util.HashMap;6.import java.util.Map;7.8.import org.jivesoftware.database.DbConnectionManager;9.import org.jivesoftware.openfire.XMPPServer;10.import org.jivesoftware.openfire.container.Plugin;11.import org.jivesoftware.openfire.container.PluginMana ger;12.import org.jivesoftware.util.JiveGlobals;13.import org.jivesoftware.util.PropertyEventDispatcher;14.import org.jivesoftware.util.PropertyEventListener;15.import org.jivesoftware.util.redis.enity.RedisConfig;16.import er;17.import erVcard;18.import org.slf4j.Logger;19.import org.slf4j.LoggerFactory;20.import redis.clients.jedis.Jedis;21.22.public class RedisServicePlugin implements Plugin, Pr opertyEventListener{23.24.private static final Logger log = LoggerFactory.getLog ger(RedisServicePlugin.class);25.26.private static final String OF_REDIS_CONFIG_DELETE = "delete from redisConfiguration";27.private static final String OF_REDIS_CONFIG_INSERT = "INSERT INTO redisConfiguration (name, ip, port, auto) VALUES (?, ?, ?, ?)";28.29.private XMPPServer server;30.private boolean enabled;31.32.@Override33.public void propertySet(String property, Map<String, Object> params) {34.if (property.equals("plugin.redis.enabled")) {35.this.enabled = Boolean.parseBoolean((String)params.g et("value"));36.}37.}38.......39.public boolean isEnabled() {40.return enabled;41.}42.43.public void setEnabled(boolean enabled) {44.this.enabled = enabled;45.JiveGlobals.setProperty("plugin.redis.enabled", enabled ? "true" : "false");46.}47.48.@Override49.public void initializePlugin(PluginManager manager, Fi le pluginDirectory) {50.enabled = JiveGlobals.getBooleanProperty("plugin.red is.enabled", true);51.server = XMPPServer.getInstance();52.PropertyEventDispatcher.addListener(this);53.}54.55.@Override56.public void destroyPlugin() {57.enabled = JiveGlobals.getBooleanProperty("plugin.redis.enabled", false);58.PropertyEventDispatcher.removeListener(this);59.}60.61.public void initializeAllData () {62.Collection<RedisConfig> crcfs = getAllRedisConfig();63.if (!crcfs.isEmpty()) {64.for (RedisConfig rcf : crcfs) {65.if ("REDIS_USER".equals(rcf.getName())) {66.setRedisByUserInfo();67.}68.}69.}70.}71.72.public void saveRedisConfig(Collection<RedisConfig> object) {73.PreparedStatement pstmt = null;74.Connection con = null;75.try {76.con = (Connection) DbConnectionManager.getConnec tion();77.if (object != null) {78.pstmt = con.prepareStatement(OF_REDIS_CONFIG_DE LETE);79.pstmt.execute();80.pstmt = (PreparedStatement) con.prepareStatement(O F_REDIS_CONFIG_INSERT);81.for (RedisConfig cr : object) {82.pstmt.setString(1, cr.getName());83.pstmt.setString(2, cr.getIp());84.pstmt.setString(3, cr.getPort());85.pstmt.setString(4, cr.getAuto());86.pstmt.executeUpdate();87.}88.}89.} catch (Exception e) {(e.getMessage());91. e.printStackTrace();92.}93.finally {94.DbConnectionManager.closeConnection(pstmt, con);95.}96.}97.98.public Collection<RedisConfig> getAllRedisConfig() {99.if (server == null)100.server = XMPPServer.getInstance();101.return server.getJedisConfDao().getAllRedisConfig();102.}103.104.public void setRedisOfflineMessage() {105.XMPPServer.getInstance().getChatMessageJedisPoolM anager().initDataByOfflineMessage();106.}107.108.public void destroyOfflineMessage() {109.Jedis jedis = server.getChatMessageJedisPoolManager ().getJedis();110.jedis.flushDB();111.server.getChatMessageJedisPoolManager().returnRes(j edis);112.}113.114.public void setRedisUserSearch() {115.XMPPServer.getInstance().getRedisSearchManager().cr eateSearchAllUserData();116.}117.118.public void destroyUserSearch() {119.Jedis jedis = server.getRedisSearchManager().getSearc hJedis();120.jedis.flushDB();121.XMPPServer.getInstance().getUserJedis().returnRes(jed is);122.}123.124.public void destroyRedisByUserInfo () {125.Jedis jedis = server.getUserJedis().getJedis();126.Map<String, String > user = jedis.hgetAll("OFUSER:ad min");127.jedis.flushAll();128.jedis.hmset("OFUSER:admin", user);129.XMPPServer.getInstance().getUserJedis().returnRes(jed is);130.}131.132.public void setRedisByUserInfo () {133.Jedis jedis = server.getUserJedis().getJedis();134.int i = 1;135.136.Collection<User> users = server.getUserJedis().getAll User();137.if (!users.isEmpty()) {138.for (User user : users) {139.Map<String,String> map = new HashMap<String, Stri ng>();140.map.put("PASSWORD", user.getPassword());141.if (user.getName() != null )142.map.put("NAME", user.getName());143.if (user.getMoblie() != null )144.map.put("MOBILE", user.getMoblie().trim());145.if (user.getEmail() != null)146.map.put("EMAIL", user.getEmail().trim());147.map.put("CREATIONDATE",user.getCreationDate().trim ());148.map.put("MODIFICATIONDATE",user.getModificationD ate().trim());149.jedis.hmset("OFUSER:" + user.getUsername(), map);150.151.System.out.println("The " + i++ + "user generation=> username:" + user.getUsername() + ", name:" + user.getName() );152.}153.System.out.println("the end:user base info generated... ");154.i = 1;155.156.for (User user : users) {157.if (user.getMoblie() != null && !"".equals(user.getMoblie())) {158.jedis.set("MOBILE:" + user.getMoblie(), user.getUserna me());159.System.out.println("The" + i++ + "user,mobile relation generation=> mobile:" + user.getMoblie() + ", username:" + us er.getUsername());160.}161.}162.System.out.println("the end:user and mobile relation g enerated...");163.i = 1;164.}165.166.Collection<UserVcard> uservcards = server.getUserJe dis().getUserVcard();167.if (!uservcards.isEmpty()) {168.for (UserVcard uv : uservcards) {169.if (uv.getVcard() != null && !"".equals(uv.getVcard())) {170.jedis.set("OFVCARD:" + uv.getUsername(), uv.getVcard ());171.System.out.println("The" + i++ + "user vcard generati on=> username:" + uv.getUsername());172.}173.}174.i = 1;175.System.out.println("the end:user vcard generated...");176.}177.178.server.getUserJedis().returnRes(jedis);179.}180.}RedisUserInfoOpt:[java] view plain copyprint?1.import java.util.HashMap;2.import java.util.Map;3.4.import org.jivesoftware.openfire.XMPPServer;5.import er;6.import org.slf4j.Logger;7.import org.slf4j.LoggerFactory;8.9.import redis.clients.jedis.Jedis;10.11.public class RedisUserInfoOpt {12.13.private static final Logger Log = LoggerFactory.getLog ger(RedisUserInfoOpt.class);14.15.public void setBaseUserInfo(User user) {16.if (user != null) {17.Jedis jedis = XMPPServer.getInstance().getUserJedis(). getJedis();18.19.try {20.Map<String,String> map = new HashMap<String, Stri ng>();21.map.put("PASSWORD", user.getPassword());22.if (user.getName() != null )23.map.put("NAME", user.getName());24.if (user.getMoblie() != null )25.map.put("MOBILE", user.getMoblie().trim());26.if (user.getEmail() != null)27.map.put("EMAIL", user.getEmail().trim());28.map.put("CREATIONDATE",user.getCreationDate().trim ());29.map.put("MODIFICATIONDATE",user.getModificationD ate().trim());30.jedis.hmset("OFUSER:" + user.getUsername(), map);("user generation=> username:" + user.getUs ername() + ", name:" + user.getName());32.} finally{33.XMPPServer.getInstance().getUserJedis().returnRes(jed is);34.}35.}36.}37.38.public void setUserMobile(User user) {39.if (user != null) {40.Jedis jedis = XMPPServer.getInstance().getUserJedis(). getJedis();41.try {42.43.} finally {44.XMPPServer.getInstance().getUserJedis().returnRes(jed is);45.}46.47.}48.}49.}redis-service.jsp[html] view plain copyprint?1.<%@ page import="java.util.*,.jivesoftware.openfire.XMPPServer,.jivesoftware.util.*,.montnets.redis.plugin.RedisServicePlugin,.jivesoftware.util.redis.enity.RedisConfig"6.errorPage="error.jsp"7.%>8.9.<%@ taglib uri="/jstl/core_rt" prefix="c" %>10.<%@ taglib uri="/jstl/fmt_rt" prefix="fmt" %>11.12.<%-- Define Administration Bean --%>13.<jsp:useBean id="admin" class="org.jivesoftware.util. WebManager" />14.<c:set var="admin" value="${admin.manager}" />15.<% admin.init(request, response, session, application, out ); %>16.17.<% // Get parameters18.boolean save = request.getParameter("save") != null;19.String initdata = request.getParameter("initdata");20.String deldata = request.getParameter("deldata");21.boolean success = request.getParameter("success") != null;22.RedisServicePlugin rsp = new RedisServicePlugin();23.Collection<RedisConfig> rcList = rsp.getAllRedisConfi g();24.25.// Handle a save26.Map errors = new HashMap();27.Collection<RedisConfig> rcColl = new ArrayList<Redis Config>();28.29.if ("REDIS_USER".equals(initdata)) {30.rsp.initializeAllData();31.response.sendRedirect("redis-service.jsp?success=true");32.return;33.}34.else if ("REDIS_USER".equals(deldata)) {35.rsp.destroyRedisByUserInfo();36.response.sendRedirect("redis-service.jsp?success=true");37.return;38.}39.......40.if (save) {41.String uname = request.getParameter("REDIS_USER");42.String r_user_name = request.getParameter("REDIS_U SER_IP").trim();43.String r_user_port = request.getParameter("REDIS_USE R_PORT").trim();44.String r_user_auto = request.getParameter("REDIS_USER_AUTO").trim();45.if (r_user_name == null || r_user_port == null) {46.errors.put("uname", "Redis-User is error!");47.}48.else {49.RedisConfig rc = new RedisConfig();50.rc.setName(uname);51.rc.setIp(r_user_name);52.rc.setPort(r_user_port);53.rc.setAuto(r_user_auto);54.rcColl.add(rc);55.}56.......57.String mmname = request.getParameter("REDIS_MUC _MESSAGE");58.String r_mm_name = request.getParameter("REDIS_M UC_MESSAGE_IP").trim();59.String r_mm_port = request.getParameter("REDIS_MU C_MESSAGE_PORT").trim();60.String r_mm_auto = request.getParameter("REDIS_MU C_MESSAGE_AUTO").trim();61.if (r_mm_name == "" || r_mm_port == "") {62.errors.put("mname", "Redis-MUC MESSAGE is error!");63.}64.else {65.RedisConfig rc = new RedisConfig();66.rc.setName(mmname);67.rc.setIp(r_mm_name);68.rc.setPort(r_mm_port);69.rc.setAuto(r_mm_auto);70.rcColl.add(rc);71.}72.73.String omname = request.getParameter("REDIS_OFFLI NE_MESSAGE");74.......75.if (errors.size() == 0) {76.rsp.saveRedisConfig(rcColl);77.response.sendRedirect("redis-service.jsp?success=true");78.return;79.}80.}81.82.%>83.84.<html>85.<head>86.<title>Redis Service Properties</title>87.<meta name="pageID" content="redis-service"/>88.</head>89.<body>90.<% if (!errors.isEmpty()) { %>91.92.<div class="jive-error">93.<table cellpadding="0" cellspacing="0" border="0">94.<tbody>95.<tr>96.<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16" border="0" alt=""/></td>97.<td class="jive-icon-label">98.99.<% if (errors.get("uname") != null) { %>100.<%=errors.get("uname") %>101.<% } else if (errors.get("gname") != null) { %>102.<%=errors.get("gname") %>103.<% } else if (errors.get("rname") != null) { %>104.<%=errors.get("rname") %>105.<% } else if (errors.get("mname") != null) { %>106.<%=errors.get("mname") %>107.<% } else if (errors.get("mmname") != null) { %>108.<%=errors.get("mmname") %>109.<% } else if (errors.get("omname") != null) { %>110.<%=errors.get("omname") %>111.<% } else if (errors.get("cmname") != null) { %>112.<%=errors.get("cmname") %>113.<% } %>114.</td>115.</tr>116.</tbody>117.</table>118.</div><br>119.120.<% } %>121.122.<p>123.This is redis plugin124.</p>125.126.<% if (success) { %>127.128.<div class="jive-success">129.<table cellpadding="0" cellspacing="0" border="0"> 130.<tbody>131.<tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td> 132.<td class="jive-icon-label">133.redis service properties edited successfully.134.</td></tr>135.</tbody>136.</table>137.</div><br>138.<% } %>139.140.<form action="redis-service.jsp?save=true" method="post">141.142.<fieldset>143.<legend>Redis Service</legend>144.<div>145.<ul>146.<%if (rcList.size() < 1) { %>147.<label for="r_user">REDIS_USER:</label>148.<input type="hidden" id="r_user_name" name="REDI S_USER" value="REDIS_USER"/>149.<input type="text" id="r_user_ip" name="REDIS_USER _IP" size="20" value=""/>150.<label for="r_port">port:</label>151.<input type="text" id="r_user_port" name="REDIS_US ER_PORT" size="5" value=""/>152.<label for="r_auto">auto:</label>153.<input type="text" name="REDIS_USER_AUTO" size=" 10" value=""/>154.<br><br>155.156.<label for="r_user">REDIS_GROUP:</label>157.<input type="hidden" id="r_group_name" name="RE DIS_GROUP" value="REDIS_GROUP"/>158.<input type="text" id="r_group_ip" name="REDIS_GR OUP_IP" size="20" value=""/>159.<label for="r_port">port:</label>160.<input type="text" id="r_group_port" name="REDIS_ GROUP_PORT" size="5" value=""/>161.<label for="r_auto">auto:</label>162.<input type="text" name="REDIS_GROUP_AUTO" size ="10" value=""/>163.<br><br>164.165.<label for="r_user">REDIS_ROSTER:</label>166.<input type="hidden" id="r_roster_name" name="RE DIS_ROSTER" value="REDIS_ROSTER"/>167.<input type="text" id="r_roster_ip" name="REDIS_RO STER_IP" size="20" value=""/>168.<label for="r_port">port:</label>169.<input type="text" id="r_roster_port" name="REDIS_R OSTER_PORT" size="5" value=""/>170.<label for="r_auto">auto:</label>171.<input type="text" name="REDIS_ROSTER_AUTO" size="10" value=""/>172.<br><br>173.174.<label for="r_user">REDIS_MUC:</label>175.<input type="hidden" id="r_muc_name" name="REDI S_MUC" value="REDIS_MUC"/>176.<input type="text" id="r_muc_ip" name="REDIS_MUC _IP" size="20" value=""/>177.<label for="r_port">port:</label>178.<input type="text" id="r_muc_port" name="REDIS_M UC_PORT" size="5" value=""/>179.<label for="r_auto">auto:</label>180.<input type="text" name="REDIS_MUC_AUTO" size=" 10" value=""/>181.<br><br>182.183.<label for="r_user">REDIS_MUC_MESSAGE:</label> 184.<input type="hidden" id="r_mm_name" name="REDI S_MUC_MESSAGE" value="REDIS_MUC_MESSAGE"/> 185.<input type="text" id="r_mm_ip" name="REDIS_MUC _MESSAGE_IP" size="20" value=""/>186.<label for="r_port">port:</label>187.<input type="text" id="r_mm_port" name="REDIS_M UC_MESSAGE_PORT" size="5" value=""/>188.<label for="r_auto">auto:</label>189.<input type="text" name="REDIS_MUC_MESSAGE_AU TO" size="10" value=""/>190.<br><br>191.192.<label for="r_user">REDIS_OFFLINE_MESSAGE:</label>193.<input type="hidden" id="r_om_name" name="REDIS _OFFLINE_MESSAGE" value="REDIS_OFFLINE_MESSAGE"/> 194.<input type="text" id="r_om_ip" name="REDIS_OFFLI NE_MESSAGE_IP" size="20" value=""/>195.<label for="r_port">port:</label>196.<input type="text" id="r_om_port" name="REDIS_OFF LINE_MESSAGE_PORT" size="5" value=""/>197.<label for="r_auto">auto:</label>198.<input type="text" name="REDIS_OFFLINE_MESSAGE _AUTO" size="10" value=""/>199.<br><br>200.201.<label for="r_user">REDIS_CHAT_MESSAGE:</label> 202.<input type="hidden" id="r_cm_name" name="REDIS _CHAT_MESSAGE" value="REDIS_CHAT_MESSAGE"/> 203.<input type="text" id="r_cm_ip" name="REDIS_CHAT_ MESSAGE_IP" size="20" value=""/>204.<label for="r_port">port:</label>205.<input type="text" id="r_cm_port" name="REDIS_CH AT_MESSAGE_PORT" size="5" value=""/>206.<label for="r_auto">auto:</label>207.<input type="text" name="REDIS_CHAT_MESSAGE_A UTO" size="10" value=""/>208.<br><br>209.210.<label for="r_user">REDIS_SEARCH:</label>211.<input type="hidden" id="r_rs_name" name="REDIS_ SEARCH" value="REDIS_SEARCH"/>212.<input type="text" id="r_rs_ip" name="REDIS_SEARCH_IP" size="20" value=""/>213.<label for="r_port">port:</label>214.<input type="text" id="r_rs_port" name="REDIS_SEAR CH_PORT" size="5" value=""/>215.<label for="r_auto">auto:</label>216.<input type="text" name="REDIS_SEARCH_AUTO" siz e="10" value=""/>217.<br><br>218.219.<% } %>220.<% if (rcList.size() >= 1) { %>221.<% for (RedisConfig cr : rcList) { %>222.<label for="r_user"><%=cr.getName() %></label> 223.<input type="hidden" name="<%=cr.getName() %>" value="<%=cr.getName() %>"/>224.<input type="text" name="<%=cr.getName() %>_IP" size="20" value="<%=cr.getIp() %>"/>225.<label for="r_port">port:</label>226.<input type="text" name="<%=cr.getName() %>_PO RT" size="5" value="<%=cr.getPort() %>"/>227.<label for="r_auto">auto:</label>228.<input type="text" name="<%=cr.getName() %>_AU TO" size="10" value="<%=cr.getAuto() %>"/>229.<br>230.<input type="button" value="initialize data" onclick=" window.location.href='redis-service.jsp?initdata=<%=cr.getName() %>'; return false;"/> 231.<input type="button" value="destroy data" onclick=" window.location.href='redis-service.jsp?deldata=<%=cr.getName() %>'; return false;"/>232.<br><br>233.<%} %>234.<% } %>235.</ul>236.</div>237.</fieldset>238.239.<br><br>240.241.<input type="submit" value="Save Settings">242.<input type="hidden" name="initdata" value=""/> 243.</form>244.245.</body>246.</html>Plugin.xml[html] view plain copyprint?1.<?xml version="1.0" encoding="UTF-8"?>2.<plugin>3.<class>com.montnets.redis.plugin.RedisServicePlugin</cl ass>4.<name>Redis Service</name>5.<description>Redis distributed cache</description>6.<author>HuWenFeng</author>7.<version>1.3.3</version>8.<date>17/1/2014</date>9.<minServerVersion>3.8.2</minServerVersion>10.11.<adminconsole>12.<tab id="tab-redis" name="Redis" url="redis-service.jsp">13.<sidebar id="sidebar-redis-settings" name="Redis Service" >14.<item id="redis-service" name="Redis Service" url="redis-service.jsp"15.description="Redis distributed cache" />16.</sidebar>17.</tab>18.</adminconsole>19.</plugin>这里只简单贴出了用户这类的相关数据的预加载。
openfire插件编译及部署
Openfire插件编译及部署插件编译1、编译参数配置打开eclipse或者Myeclipse,点击菜单栏里的run选项,在其下拉菜单中选择External Tools按钮,在它的下一级菜单中点击External Tools Configuration即可进入配置页面。
如图1所示。
图1图2所示为配置页面。
图2选择左侧导航栏中的Ant Build选项,点击新建按钮来新建一个编译配置。
如图3所示。
图3接下来就可以来配置插件的编译参数了。
首先,在Name框中为该编制配置项命名以示区别,如图4所示:图4其次,打开Main选项卡,点击在Buildfile框下面Browse Workspace按钮,来选择用来编译插件的Build文件,它的目录是openfire/build/build.xml。
如图5所示。
图5完成后框内显示数据为“${workspace_loc:/openfire/build/build.xml}”,如图6所示。
图6再填写Arguments框,内容格式为“-Dplugin=XXXX”,其中“XXXX”是我们要编译的插件名。
完成后如图7所示。
图7打开Targets勾选plugin,若编译所有插件就勾选plugins,完成后如图8所示。
图8再打开Common选项卡,设置编译的编码格式一般为UTF_8格式。
完成后如图9所示。
图9最后点击按钮保存设置,点击就可对插件进行编译。
2、检查编译结果当控制台出现编译成功的结果时,即代表编译已经完成,如图10所示。
图10在openfire/target/plugins目录,出现对应的插件jar文件,就代表编译成功了!如图11所示。
图11最后,将编译好的插件jar文件复制出来,以备上传导服务器。
插件部署首先,访问openfire服务器的管理控制台,URL是http://服务器IP:9090。
输入管理员用户名和密码。
如图12所示。
图12登录进入后,选择“插件”网页中机会显示服务器目前所安装的所有插件,如图13所示。
Openfire调试编译开发环境与安装
调试、编译开发环境Openfire与安装自己实践:说明:开发环境(IDE):Eclipse3.3.2+JDK1.6+Ant1.7+Openfire_src_3_5_1.zip1.如果代码中使用了importtestng.xxx语句,就需要导入testng-5.8-jdk15.jar类库;2.对于警告信息,是没有关系的。
因为这些警告信息是使用1.5以上版本JDK时候才出现的,使用JDK1.4是不会出现这些警告信息的。
因为这些代码中的有些是使用JDK1.4编写的,而JDK1.4不支持泛型,而JDK1.5和JDK1.6是支持泛型的。
这些警告信息主要是提示将这些非泛型的代码修改为更加高级的方法——泛型,所以这些警告信息是不影响代码结果的。
如果需要修改为泛型也是可以,使用泛型来处理相关的集合类。
3.在使用ant进行编译的时候,在ant视图中可能会出现警告如下信息:taskdefclasscom.install4j.install4jtaskcannotfound这个主要是要安装用来打包Java应用程序的install4j.exe程序,要安装到其默认的安装路径下。
也就是C:\ProgramFiles\目录下即可。
4.在源码里面有一个文件夹里有个打包的图标,双击那个图标,install4j就会读取你在build.xml文件里的信息、在里面完成做界面等打包工作。
编译调试的环境(IDE):Eclipse3.3.2+JDK1.6+Ant(内置)+openfire_src_2008-06-04.zip 在Windows操作系统下编译、调试openfire之前,需要确保HTTPSSL服务已经启动。
否则,会出现各种错误信息。
1.获取Openfire源代码从官方网站上直接下载官方发布版本的源代码openfire_src_2008-06-04.zip源代码压缩包;2.创建openfire工程将openfire_src_2008-06-04.zip解压后,目录下除了READEME.html、LICENSE.html和changelog.html三个网页文件之外,有下面四个子目录。
[实用参考]XMPP协议及其服务器端的Openfire插件开发
GMPP协议及其服务器端的Openfire插件开发GMPP背景知识GMPP是一种基于GML的协议,它继承了在GML环境中灵活的发展性。
因此,基于GMPP的应用具有超强的可扩展性。
绊过扩展以后的GMPP可以通过发送扩展的信息来处理用户的需求,以及在GMPP的顶端建立如内容发布系统和基于地址的服务等应用程序。
而且,GMPP包含了针对服务器端的软件协议,使乊能不另一个进行通话,这使得开发者更容易建立客户应用程序戒给一个配好系统添加功能。
GMPP(可扩展消息处理现场协议)是基于可扩展标记语言(GML)的协议,它用于即时消息(IM)以及在线现场探测。
它在促进服务器乊间的准即时操作。
这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器丌同。
GMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。
GMPP目前被IETF国际标准组织完成了标准化工作。
标准化的核心绌果分为两部分;核心的GML流传输协议基于GMLFreeEIM流传输的即时通讯扩展应用GMPP的核心GML流传输协议的定义使得GMPP能够在一个比以往网络通信协议更规范的平台上。
借劣于GML 易于解析和阅读的特性,使得GMPP的协议能够非常漂亮。
GMPP的即时通讯扩展应用部分是根据IETF在这乊前对即时通讯的一个抽象定义的,不其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。
GMPP的扩展协议Jingle使得其支持语音和视频。
基本网络结构GMPP中定义了三个角色,客户端,服务器,网关。
通信能够在这三者的任意两个之间双向发生。
服务器同时承担了客户端信息记录,连接管理和信息的路由功能。
网关承担着不异构即时通信系统的互联互通,异构系统可以包括SMS (短信),MSN,ICQ等。
基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在乊上传输GML。
功能传输的是不即时通讯相关的指令。
openfirespark二次开发服务插件
openfirespark二次开发服务插件==================== 废话begin============================最近老大让我为研发平台增加即时通讯功能。
告诉我用comet 在web端实现即时通讯。
最初狂搜集资料。
不能让自己方向错了。
这是很重要的。
不过还是难免的周折了一番。
测试了一个comet4j的聊天小例子。
用它前后端开发成本太大、对服务器也太大压力放弃了。
最终决定使用openfire +jsjac.js + JabberHTTPBind 然后实现老大要求的web 及时通讯功能。
很庆幸找到了hoojo大哥的demo 很不幸,他为了让大家复制代码,自己练习。
不提供jar包js下载。
(虽然好心但是足足浪费了我两天时间)一个jsjac.js库版本有问题。
很费劲的看源码。
哎。
然后、拿这个小demo 先交差。
顺便展示了spark 和web 聊天窗口,交互即时聊天。
顺便构想了一下,修改openfire用户表。
让用户来自系统。
组织则用自带的。
(当然这是预想。
其实openfire已经帮我们想过了。
)接着、全局搜索了openfire源码中包含ofuser表sql的类。
只有两个类。
很庆幸。
改了之后,改造用户密码加密认证方式。
当然这样做是错误的。
直到我发现类名字似乎有些不对的时候。
DefaultUserProvider 哈哈、嘲讽啊。
不出所料有一个实现类JDBCUuserProvider 。
直接配置就可以搞定、但是加密sha256加密过程和我平台不一样。
改造后就顺利搞定。
接着、到了插件开发过程。
这个过程很烦人。
网上很多帖子很多人去讲这个开发过程。
或许是两三年前的贴了。
很多过时了。
只能有一点帮助。
更多的是走向了错误的道路。
磕磕碰碰。
最终还是只能从源码中寻求出路。
这个过程整整浪费了我两星期时间。
很痛苦。
所以。
我会针对最新代码聊聊,spark 开发一个组织架构树插件。
展示出用户。
并可以与之聊天。
Openfire二次开发问题分析及解决
( )其 他 文 件 :ca gl .tl 本 信 息 、r d e tl 7 hn e g m 版 oh e m . m 说 a h
 ̄ 明 、lg lr e.il g s a1i图标 等 。 o o ag gf o o m lg .f
_
—
21 插 件 开 发 分 析 .
2 11新 插 件 要 在 Op n r\r ̄ lgn \ 声 明 该 插 件 .. e fe scpu i 中 l s 新 建 一 个 该 插 件 的 文 件 夹 ,一般 情 况 下 所 必须 的文 件 有 : ( )1 1 i 件 夹 :存放 所 需 类 库 。 b文 ( )s 2 r 件夹 :存 放 相 关 源 文 件 。 e文 ( )d t a e文 件 夹 : 位 于 sc文 件 夹 下 , 如 果 插 件 需 要 3 a bs a e
( )i8 件 夹 :存 放 国 际 化 文 件 , 即 相关 的 文 字 显 示 。 4 1n文
Pu i 个 接 口 ,iia zPu i 件 建 立 ,d soPu i 件 lg n两 nt le lg ii n插 et y lg r n插
销毁 。
数 据 库 的库 表 结 构 操 作 ,例 如 新 建 表 、新 建 字 段 等 .将 S L Q
文件 放于此文件 夹下 ,该 文件夹 下的 S L文件会 在插件 加载 Q
图片 库 、s l 样 式 表 等 相 关 文件 夹 以及 该 插 件 的 JP文件 。 te y S
( )pu is ml 件 :声 明 该 插 件 的文 件 。包 括 如 表 1所 6 lg . 文 nx 示 内容 。
表 1
<as> els
<a > n me
※ 类 文 件 名 。完 整 名 称 ,包 括 其 包 名
openfire开发文档
Openfire开发文档修订记录目录1OPENFIRE项目工程搭建及调试 (1)1.1准备工作 (1)1.2解压源码 (1)1.3创建工程 (2)1.4编译 (3)1.5配置调试与运行环境 (5)1.6打包发布 (10)2OPENFIRE代码框架介绍 (10)2.1框架 (11)2.1.1Module (11)2.1.2数据流 (13)2.2O PENFIRE与MIMA (13)2.3M ULTI-U SER-C HAT (14)2.3.1MUCUser (14)2.3.2MUCRole (15)2.3.3MUCRoom (15)2.3.4MultiUserChatServiceImpl (15)2.3.5时序图 (16)2.4P UB-S UB (16)2.4.1Node (16)2.4.2NodeAffiliate (17)2.4.3NodeSubscription (17)2.4.4PubSubModule (17)2.4.5PubSubEngine (18)2.4.6时序图 (18)2.5插件开发 (19)2.5.1注册为组件 (19)2.5.2注册为拦截器 (19)2.5.3注册为IQHandler (20)2.6命名规则 (21)2.6.1XXStarter (21)2.6.2XXListener (21)2.6.3XXDispatcher (21)2.6.4XXPlugin (21)2.6.5XXProvider (21)2.6.6XXHandler (22)2.7系统配置项 (22)2.8系统启动流程 (23)2.9网络处理 (23)2.9.1presence(出席状态)消息处理流程 (23)2.9.2消息监听服务 (25)2.9.3消息封装 (26)2.9.4Openfire消息包接受处理流程 (27)2.10数据库处理 (28)2.10.1Openfire连接数据库修改 (28)2.10.2ConnectionProvider (28)2.10.3处理方式 (28)2.10.4常用类 (28)3OPENFIRE插件开发流程 (29)3.1O PENFIRE P LUGINS加载流程 (29)3.2开发说明 (29)3.2.1总体插件目录结构 (30)3.2.2编写Plugin.xml (30)3.2.3继承Plugin接口 (33)3.2.4插件开发的最优方法 (34)3.2.5JSP页面配置步骤 (34)3.2.6i18n国际化配置 (37)3.2.7Ant build 插件 (38)4OPENFIRE 的CACHE机制 (39)4.1实现机制 (39)1Openfire项目工程搭建及调试Openfire的最新源码3.7.1下源码的运行及打包1.1 准备工作开发工具:Eclipse源码下载:官网地址/downloads/source.jsp,当前最新版本为3.7.1。
OpenFire 插件开发基础教程
O p e n F i r e插件开发基础教程(总3页)-CAL-FENGHAI.-(YICAI)-Company One1-CAL-本页仅作为文档封面,使用请直接删除OpenFire 插件开发基础教程Openfire是一款优秀的XMPP服务器,而且是开放源码的.大家可以根据自己的需求进行二次开发。
二次开发主要有两种方式:1.修改源代码,2开发openfire插件。
从可扩展性上考虑,自然是开发插件是上策,只有插件无法实现时候才会选择修改源代码。
下面就个人经验,说明一下如何开发openfire插件一、环境基础要有一个配置好的openfire开发环境,这个网络上有比较详细的教程了。
比如《源代码导入eclipse中开发配置指南》和《源码部署及运行》,这时候ant应该是可以正常运行的,先执行openfire 【default】,就生成了openfire的目标代码,再执行plugins,就个生成所以系统自带的插件。
二、目录拷贝打开workspace\openfire_src\src\plugins目录,找一个要修改的插件,我选的是subscription,拷贝生成“subscriptionUF”。
打开src目录,里面有两个文件夹,java就是我们要改的源码,而web里面是修改这个插件所要用的web配置页面,目前用不到,直接删除。
三、修改这个一个xml文件,里面的内容就按照自己的样子更改吧。
最关键是确定<class>,插件所在的类名,既然没有web文件夹了adminconsole也全部注释掉吧.四、修改类和类目录修改src/java里面的目录层次,Class和src/java中的路径必须一致。
五、引入openfire项目右击openfire项目,选择New->Source Folder,在Floder name中选择到刚刚新增的插件目录,注意要选到src/java这一层六、修改类文件SubscriptionPluginUF是完全copy SubscriptionPlugin的,因此有两个类名不符的error修改一下.至此,整个openfire已经把我们新加的SubscriptionPluginUF包含在他的plugins中了,通过控制台也能看到一个仿冒的SubscriptionPluginUF插件七、单独编译插件如果每次都运行plugins,生成所有插件的同时生成我们修改的插件,固然可行,就是慢了一点,插件有什么错误也要找半天。
openfire开发环境搭建
说明: 开发环境(IDE):openfire -3.7.1 +
eclipse-4.2.0
+
jdk-1.7
1. 将 openfire 的源文件拷到 Eclipse 的工作空间中,以源文件名称创建 openfire 的 java 项目
2. 项目有错误是因为 jar 包没有加进来,右键点击项目选择 Properties,java build path-->Libraries 选 卡,Add Jars,选择 openfire 项目 build/lib 下所有的 jar 包,添加
1
3. 此时 project 有错误,下载三个 jar 包:coherence.jar,coherence-work.jar,tangosol.jar,保存在任意文 件夹 4. 在 eclipse 的 Package Explorer 中选中前面建立的 project,右键—>Properties-->java build path-->Libraries 选卡, Add External Jars,选中下载的三个包,完成 5. 此时仍旧有错。源代码中部分 class 继承自 abstract 类,但 abstract 方法没有全部实现,需手动改 正 6. 复制 src/i18n/openfire_i18n_en.properties 和 src/resources/jar/admin-sidebar.xml 两个文件,到项目 下的 bin 目录。 7. 开始用 ant 编译源文件。切换到 ant 视图:菜单栏 ->show view->ant 8. 在 ant 中选 add buildfiles 按钮,在 project 中选 build/build.xml,然后用 ant 编译,直 到编译成功 如果编译出错,是因为 ant 版本不对(太高了)。在 build.xml 中找到下面语段
OPENFIRE使用Hazelcast插件进行集群
OPENFIRE使用Hazelcast插件进行集群参考资料:
我使用的是openfire3.9.3 ,两台linux,还是一样,直接上图:试了几次终于成功了!
openfire设置的域名要一样,数据库要设置到同一个地方,我的是A服务器的openfire数据库设置为本地的数据库,即数据库地址为localhost(A服务器地址),B服务器的openfire数据库则为A服务器的数据地址。
1.为了提高成功率,我是在openfire部署好之后,进入openfire 后台,分别在插件那栏安装Hazelcast Clustering Plugin ,安装过程全部自动进行,如下图
2. 确认5071端口是否开放了:输入
/sbin/iptables -I INPUT -p tcp --dport 9090 -j ACCEPT;
保存重启:
启动openfire之后,分别编辑Hazelcast插件下面的文件夹中classpath中的hazelcast-cache-config.xml
然后重启openfire,在clustering链接那里启用集群选项,耐心等待,虽然我也不知道结果是什么(这个过程坑爹,说好的30秒左右呢,结果我等了十几分钟还是不行,人与人之间的信任都去哪儿了啊!),因为我是后来想重启openfire的,但是停不掉,最后是杀掉进程的:
然后再输入 kill -9 25526杀掉即可。
分别重启openfire之后,进入控制台,终于看到了我希望看到的结果:
在不同的客户端端登陆不同的IP地址,可以登录上去,也可进行聊天,OK!
就这样吧!。
Openfire二次开发问题分析及解决
2.1.1 新插件要在 Openfire\src\plugins\ 中声明该插件 新建一个该插件的文件夹, 一般情况下所必须的文件有: (1) lib 文件夹: 存放所需类库。 (2) src 文件夹: 存放相关源文件。 (3) database 文 件 夹 : 位 于 sec 文 件 夹 下 , 如 果 插 件 需 要
匦查妥??盯workcommunic盯旧???????????????????????????????openfire二次开发问题分析及解决苑为陶卓彬摘要
NETWORK & COMMUNICATION
网络与通信
O penfire 二次开发问题分析及解决
苑 为 陶卓彬
摘 要: 随着计算机技术的迅猛发展, 开源软件的二次开发利用逐渐成为进行快速开发的主要手 段。 针对利用开源软件 Openfire 二次开发搭建即时消息系统平台时遇到的问题, 分析并提出了相 应的解决方案, 并阐述了这些方案的实现。 关键词: Openfire; 即时消息系统; 二次开发
数 据 库 的 库 表 结 构 操 作 , 例 如 新 建 表 、 新 建 字 段 等 , 将 SQL 文 件 放 于 此 文 件 夹 下 , 该 文 件 夹 下 的 SQL 文 件 会 在 插 件 加 载 时运行, 完成所需数据库的相关操作。
(4) i18n 文 件 夹 : 存 放 国 际 化 文 件 , 即 相 关 的 文 字 显 示 。 Openfire 的 相 关 显 示 文 字 都 在 i18n 中 后 缀 名 为 properties 的 文 件中定义, 在程序中直接引用相关定义, 完成语言转换时的显 示工作。
“您好, 诚意??请您加入会议。” 并 且 这 些 “??” 不 是 每 次 都 出 现 , 相 同 的 语 句 、 相 同 的 操 作 也 是 时 有 时 无 。 于 是 , 在 调 试 环 境 下 对 Openfire 源 代 码 流 程 进 行 了 跟 踪 , 发 现 问 题 出 现 在 XMLLightweightParser.java 文件中。 public void read(ByteBuffer byteBuffer) throws Exception {
openfire二次开发-推荐下载
将
build path 的 jar 包 Add To Build Path 5. 完成上部操作后,会有下面的错误:
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术通关,1系电过,力管根保线据护敷生高设产中技工资术艺料0不高试仅中卷可资配以料置解试技决卷术吊要是顶求指层,机配对组置电在不气进规设行范备继高进电中行保资空护料载高试与中卷带资问负料题荷试2下卷2,高总而中体且资配可料置保试时障卷,各调需类控要管试在路验最习;大题对限到设度位备内。进来在行确管调保路整机敷使组设其高过在中程正资1常料中工试,况卷要下安加与全强过,看度并22工且22作尽22下可22都能22可地护以缩1关正小于常故管工障路作高高;中中对资资于料料继试试电卷卷保破连护坏接进范管行围口整,处核或理对者高定对中值某资,些料审异试核常卷与高弯校中扁对资度图料固纸试定,卷盒编工位写况置复进.杂行保设自护备动层与处防装理腐置,跨高尤接中其地资要线料避弯试免曲卷错半调误径试高标方中高案资等,料,编试要5写、卷求重电保技要气护术设设装交备备置底4高调、动。中试电作管资高气,线料中课并敷3试资件且、设卷料中拒管技试试调绝路术验卷试动敷中方技作设包案术,技含以来术线及避槽系免、统不管启必架动要等方高多案中项;资方对料式整试,套卷为启突解动然决过停高程机中中。语高因文中此电资,气料电课试力件卷高中电中管气资壁设料薄备试、进卷接行保口调护不试装严工置等作调问并试题且技,进术合行,理过要利关求用运电管行力线高保敷中护设资装技料置术试做。卷到线技准缆术确敷指灵设导活原。。则对对:于于在调差分试动线过保盒程护处中装,高置当中高不资中同料资电试料压卷试回技卷路术调交问试叉题技时,术,作是应为指采调发用试电金人机属员一隔,变板需压进要器行在组隔事在开前发处掌生理握内;图部同纸故一资障线料时槽、,内设需,备要强制进电造行回厂外路家部须出电同具源时高高切中中断资资习料料题试试电卷卷源试切,验除线报从缆告而敷与采设相用完关高毕技中,术资要资料进料试行,卷检并主查且要和了保检解护测现装处场置理设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
XMPP协议及其服务器端的Openfire插件开发
GMPP协议及其服务器端的Openfire插件开发GMPP背景知识GMPP是一种基于GML的协议,它继承了在 GML环境中灵活的发展性。
因此,基于GMPP的应用具有超强的可扩展性。
绊过扩展以后的GMPP可以通过发送扩展的信息来处理用户的需求,以及在GMPP的顶端建立如内容发布系统和基于地址的服务等应用程序。
而且,GMPP包含了针对服务器端的软件协议,使乊能不另一个进行通话,这使得开发者更容易建立客户应用程序戒给一个配好系统添加功能。
GMPP (可扩展消息处理现场协议)是基于可扩展标记语言(GML )的协议,它用于即时消息(IM )以及在线现场探测。
它在促进服务器乊间的准即时操作。
这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器丌同。
GMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。
GMPP目前被IETF国际标准组织完成了标准化工作。
标准化的核心绌果分为两部分;核心的GML流传输协议基于GMLFreeEIM流传输的即时通讯扩展应用 GMPP的核心GML流传输协议的定义使得GMPP 能够在一个比以往网络通信协议更规范的平台上。
借劣于GML易于解析和阅读的特性,使得 GMPP的协议能够非常漂亮。
GMPP的即时通讯扩展应用部分是根据IETF在这乊前对即时通讯的一个抽象定义的,不其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。
GMPP的扩展协议Jingle 使得其支持语音和视频。
基本网络结构GMPP中定义了三个角色,客户端,服务器,网关。
通信能够在这三者的任意两个之间双向发生。
服务器同时承担了客户端信息记录,连接管理和信息的路由功能。
网关承担着不异构即时通信系统的互联互通,异构系统可以包括SMS (短信),MSN,ICQ等。
基本的网络形式是单客户端通过 TCP/IP连接到单服务器,然后在乊上传输 GML。
功能传输的是不即时通讯相关的指令。
openfire_plugin开发流程
Openfire插件开发流程1.插件结构:testplugin/|- plugin.xml <-配置文件|- readme.html <-用户说明|- changelog.html <-更新日志|- icon_small.gif <-小图标|- icon_large.gif <-大图标|- src/<-存放编译的类文件夹|- database/<-存放数据库改动|- i18n/<-国际化|- lib/<-插件所需要的类库|- web <-显式调用插件时需要的Web页面|- WEB-INF/|- web.xml <-Web配置|- web-custom.xml <-Web配置|- images/2.加入插件目录文件:在eclipse的openfire项目文件夹openfire_src\src\plugins下手动新建一个插件文件夹,定义名为testplugin,进入文件夹根据需要新建以上文件夹或文件,其中web、i18n、icon、database 都不是必须的,可以只创建src文件夹和plugin.xml文件。
在建立的src文件夹下依次创建文件夹java,org,jivesoftware,openfire,plugin,形成src\plugins\testplugin\src\java\org\jivesoftware\openfire\plugin的目录结构。
在最底层,即plugin文件夹下建立java类,起名为TestPlugin.java。
修改建立好的plugin.xml :<?xml version="1.0" encoding="UTF-8"?><plugin><!—插件主类,必须要的 --><class>org.jivesoftware.openfire.plugin.TestPlugin</class><!—插件信息 --><!—插件名称 --><name>Plugin</name><!—插件描述信息 --><description>Test Plugin</description><!—插件作者 --><author>Aaron</author><!—插件版本 --><version>1.0.0</version><!—插件日期,必须格式为MM/dd/yyyy --><date>12/24/2007</date><!—插件需要的openfire最小版本 --><minServerVersion>3.4.1</minServerVersion><!—插件许可类型--><licenseType>gpl</licenseType><!—Web界面需要配置,没有界面则保留<adminconsole>空标签即可 --><adminconsole><tab id="mytab"name="Example"url="my-plugin-admin.jsp"description="Click to manage..."><sidebar id="mysidebar"name="My Plugin"><item id="my-plugin"name="My Plugin Admin"url="my-plugin-admin.jsp"description="Click to administer settings for my plugin"/> </sidebar></tab></adminconsole></plugin>保存退出。
openfire插件大全
Openfire中有效的插件(商业插件)可能对IM开发有帮助插件可以给服务器增加新的功能。
已经安装的插件会在下表中显示。
当插件已经下载后可能需要一段时间用于安装。
当插件安装成功后会在列表中显示。
开放源代码插件描述版本作者FileSize安装Asterisk-IM Openfire Plugin Integration forAsteriskandOpenfire.1.4.0Jive Software 426.0KClient Control Controlsclientsallowed toconnectandavailablefeatures1.2.0Jive Software 162.2KClustering Plugin ClusteringsupportforOpenfire.1.2.3Jive Software 59.2KContent Filter Scansmessagepacketsfordefinedpatterns1.7.0Conor Hayes 24.7KDB Access Providesadministrators with asimpledirectaccessinterfaceto their1.1.0Daniel Henninger 8.1 K开放源代码插件描述本作者Size 装Openfire DB.Debugger Plugin PrintsXMLtraffic tothe stdout(raw andinterpretedXML)1.3.0Jive Software 11.7KEmail Listener Listens foremails andsendsalerts tospecificusers.1.1.0Jive Software 18.1KFastpath Service Supportformanagedqueuedchatrequests,such as asupportteammight use.4.3.1Jive Software 1.4MBFastpath Webchat Web basedchat clientforFastpath.4.0.0Jive Software 2.1MBGoJara ProtoXEP-xxxx:RemoteRosterManagementsupport2.1.5Holger Bergunde / DanielHenninger / Axel-F. Brand297.2KJingle Nodes Plugin Providessupport0.1.0Jingle Nodes (Rodrigo Martins) 60.8K开放源代码插件描述本作者Size 装for Jingle NodesJitsi Video Bridge IntegratesJitsi VideoBridgeintoOpenfire.1.3.0 and 24.4MBJust married Allowsadmins torename orcopy users1.1.0Holger Bergunde 361.6KKraken IM Gateway Providesgatewayconnectivity to theotherpublicinstantmessagingnetworks1.2.0Daniel Henninger 4.8MBLoad Statistic Logs loadstatisticsto a file1.2.0Jive Software 9.9 KMUC Service MUCadministration overRESTInterface0.2.1Roman Soldatow 2.4MBMonitoring Service Monitorsconversations andstatisticsof theserver.1.4.2Jive Software 4.6MBMotD (Message of the Day) Allowsadmins tohave a1.1.0Ryan Graham 15.8K开放源代码插件描述本作者Size 装message sent to users each time they log in.Packet Filter Rules toenforceethicalcommunication3.2.0Nate Putnam 92.8KPresence Service Exposespresenceinformation throughHTTP.1.6.0Jive Software 25.8KRayo Plugin ProvidessupportforXEP-03270.0.2Ignite Realtime Community 19.8MBRegistration Performsvariousactionswhenevera new useraccount iscreated.1.6.0Ryan Graham 43.9KSIP Phone Plugin Providessupportfor SIPaccountmanagement1.1.0Ignite Realtime 565.9KSTUN server plugin AddsSTUNfunctionality toOpenfire1.1.0Ignite Realtime 95.7K开放源代码插件描述本作者Size 装Subscription Automaticallyaccepts orrejectssubsription requests1.3.0Ryan Graham 18.0KUser Creation Createsusers andpopulatesrosters.1.2.0Jive Software 15.5KUser Import Export Enablesimportand exportof userdata2.4.0Ryan Graham 658.9KUser Service Allowsadministration ofusers viaHTTPrequests.1.4.3Justin Hunt 21.1K商业插件。
openfire二次开发
源码部署及编译1.将openfire源码解压2.将解压后的源码拷贝到Eclipse的工作空间中3.把源码openfire_src文件中build中有个eclipse文件夹,一个settings文件夹和classpath,project两个文件,将他们都复制到和build同级,并从其他项目中拷“.classpath"和".project",这两个文件,都是带点的!然后将eclipse文件夹中拷贝出来classpath,project 两个文件中内容分别替换掉对应.classpath,.project中的内容,就可以把classpath,project 两个文件删除掉了。
4.在Eclipse中导入openfire_src工程此时,会有这样的错误:这是由于缺少jar包引起的:将移除,在build的lib中,将没有build path的jar包Add To Build Path5.完成上部操作后,会有下面的错误:添加jar包,Add To Build Path 此时会有下面的错误实现借口中的方法即可将build—>lib下的jar包build path 6.编译7.运行选中项目,右键—>Run As—>Run Configuratios点击Search,输入ServerStarter选中Arguments选项卡,在VM arguments中填入-DopenfireHome="${workspace_loc:openfire_src}/target/openfire" ****千万注意DopenfireHome前面有个“-”选中Classpath选项卡,选中User Entries,点击右边的Advanced按钮选择Add Folder添加src/i18n 确定选择Add Folder添加resources/i18n 确定选择右侧的Advanced…–>选择Add Folderbuild/lib/dist 确定选择右侧的Advanced…–>选择Add Foldersrc/resources/jar 确定点击Apply,Run集群说明:如果使用源码做集群,则需要将src/plugins/clustering/src/java整个包删除,否则与hazelcast有冲突1.所有集群的域必须相同2.安装Hazelcast Clustering Plugin3.进入plugins—>hazelcast—>classes打开hazelcast-cache-config.xml文件,修改<network>下的代码为:<port auto-increment="true">5701</port><join><multicast enabled="false" /><tcp-ip enabled="true"><member>192.168.1.5</member><member>192.168.1.16</member><member>192.168.1.17</member></tcp-ip><aws enabled="false"/></join>或者:<join><multicast enabled="false" /><tcp-ip enabled="true"><member>192.168.1.5:5701</member><member>192.168.1.16:5701</member><member>192.168.1.17:5701</member></tcp-ip><aws enabled="false"/></join>4.重启服务器,点击Clustering查看集群中的节点重置openfire:将conf下的openfire.xml文件中的<setup>true</setup>删掉,重新进入http://localhost:9090进行配置即可Nginx负载均衡首先将pcre-8.34.tar.gz、zlib-1.2.8.tar.gz、nginx-1.7.3.tar.gz、nginx_tcp_proxy_module-master.zip 上传到linux系统中安装make:yum –y install gcc automake autoconf libtool make安装g++:yum install gcc gcc-c++安装pcre库将下载的pcre库解压,移动到usr/local/src目录中(这个目录可以随便指定)cd pcre-8.34./configuremakemake install安装zlib库将下载的zlib库解压,移动到usr/local/src目录中(这个目录可以随便指定)cd zlib-1.2.8./configuremakemake install安装openssl:yum –y install openssl openssl-develnginx默认只支持http负载均衡,为了让nginx支持tcp负载均衡,还需要https:///yaoweibin/nginx_tcp_proxy_module这个项目。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
作用:初始化时在控制台打印测试消息。
开发环境:winxp/myeclipse6.5/jdk1.5&1.6/mysql5.0/openfire3.6.3 QQ群:28588322 (openfire专题研究小组)开发步骤:1. 布署openfire3.6.3源码(请参考openfire3.6.3导入eclipse项目实现方法) 结构如下:2. src/plugins目录下新建文件夹itvi。
并按下图的目录结构新建对应的文件。
plugin.xml文件代码如下:<?xml version="1.0" encoding="UTF-8"?><plugin><class>org.jivesoftware.openfire.plugin.Itvi</class><name>Itvi</name><description>Broadcasts messages to users.</description> <author>openfireteam</author><version>1.7.0</version><date>2/19/2009</date><url></url><minServerVersion>3.6.3</minServerVersion></plugin>Itvi.java文件代码如下:package org.jivesoftware.openfire.plugin;import org.dom4j.Element;import org.jivesoftware.openfire.IQHandlerInfo;import org.xmpp.packet.*;import org.jivesoftware.openfire.handler.IQHandler;import org.jivesoftware.openfire.auth.UnauthorizedException;/*** 处理客户端发来的IQ,并回送结果IQ** @author Phoenix** Mar 14, 2008 4:55:33 PM** version 0.1*/import org.dom4j.DocumentHelper;import org.dom4j.Element;import org.dom4j.QName;import org.jivesoftware.openfire.XMPPServer;import org.jivesoftware.openfire.container.Plugin;import org.jivesoftware.openfire.container.PluginManager; import org.jivesoftware.openfire.disco.IQDiscoInfoHandler; import org.jivesoftware.openfire.disco.IQDiscoItemsHandler; import org.jivesoftware.openfire.forms.DataForm;import org.jivesoftware.openfire.forms.FormField;import org.jivesoftware.openfire.forms.spi.XDataFormImpl; import org.jivesoftware.openfire.forms.spi.XFormFieldImpl; import org.jivesoftware.openfire.resultsetmanager.ResultSet; import org.jivesoftware.openfire.resultsetmanager.ResultSetImpl; import er;import erManager;import erNotFoundException; import org.jivesoftware.util.*;import ponent;import ponentException;import ponentManager;import ponentManagerFactory;import org.xmpp.packet.IQ;import org.xmpp.packet.IQ.Type;import org.xmpp.packet.JID;import org.xmpp.packet.Packet;import org.xmpp.packet.PacketError;import org.xmpp.packet.PacketError.Condition;import java.io.File;import java.util.*;import java.util.Map.Entry;public class Itvi implements Plugin{private XMPPServer server;/** (non-Javadoc)** @see org.jivesoftware.openfire.container.Plugin#destroyPlugin()*/public void destroyPlugin(){}/** (non-Javadoc)** @seeorg.jivesoftware.openfire.container.Plugin#initializePlugin(org.jivesoftware.openfir e.container.PluginManager,* java.io.File)*/public void initializePlugin(PluginManager manager, File pluginDirectory){server = XMPPServer.getInstance();server.getIQRouter().addHandler(new ItviIQHander()); //System.out.println("测试插件启动成功");}}ItviIQHander.java文件代码如下:package org.jivesoftware.openfire.plugin;import org.dom4j.Element;import org.jivesoftware.openfire.IQHandlerInfo;import org.xmpp.packet.*;import org.jivesoftware.openfire.handler.IQHandler;import org.jivesoftware.openfire.auth.UnauthorizedException;/*** 处理客户端发来的IQ,并回送结果IQ** @author Phoenix** Mar 14, 2008 4:55:33 PM** version 0.1*/public class ItviIQHander extends IQHandler{private static final String MODULE_NAME = "group tree handler";private static final String NAME_SPACE = "com:im:group";private IQHandlerInfo info;public ItviIQHander(){super(MODULE_NAME);//info = new IQHandlerInfo("gruops", NAME_SPACE);info = new IQHandlerInfo("query", "jabber:iq:roster");//这里我们对”联系人”的IQ进入监控}/** (non-Javadoc)** @see org.jivesoftware.openfire.handler.IQHandler#getInfo()*/@Overridepublic IQHandlerInfo getInfo(){return info;}/** (non-Javadoc)** @seeorg.jivesoftware.openfire.handler.IQHandler#handleIQ(org.xmpp.packet.IQ) */@Overridepublic IQ handleIQ(IQ packet) throws UnauthorizedException{IQ reply = IQ.createResultIQ(packet);Element groups = packet.getChildElement();//1if (true){System.out.println("非法的请求类型111111");}if (!IQ.Type.get.equals(packet.getType())){System.out.println("非法的请求类型");reply.setChildElement(groups.createCopy());System.out.println("返回的最终XML-SetError前"+reply.toXML());reply.setError(PacketError.Condition.bad_request);System.out.println("返回的最终XML-SetError后"+reply.toXML());return reply;}//String userName =StringUtils.substringBefore(packet.getFrom().toString(),"@");//GroupManager.getInstance().initElement(groups,userName); //reply.setChildElement(groups.createCopy());//2//System.out.println("返回的最终XML" reply.toXML());return reply;}}3.打包插件a.第一次打包需配置ant工具。