Openfire的API接口操作

hazhangha 贡献于2013-05-06

作者 Yihu zhang  创建于2013-05-02 09:44:00   修改者Yihu zhang  修改于2013-05-06 07:36:00字数4188

文档摘要:简介:作为一款较为成熟的开源服务器软件,Openfire为了用户二次开发的扩展,提供了良好的插件支持模式。对于Openfire功能扩展,一般情况下可直接使用开发插件的方式实现,并且在大多数情况下,开发出来的插件是可以跨版本使用的,这就为向Openfire中添加功能提供了很好的支持。
关键词:

 简介:作 为 一 款 较 为 成 熟 的 开 源 服 务 器 软 件 , Openfire 为 了 用 户二次开 发 的 扩 展 , 提 供 了 良 好 的 插 件 支 持 模 式 。 对 于 Openfire功能扩展, 一般情况下可直接使用开发插件的方式实现, 并且在大多数情况下, 开发出来的插件是可以跨版本使用的, 这就为向 Openfire 中添加功能提供了很好的支持。 1、 插件开发分析 1.1新插件要在 Openfire\src\plugins\ 中声明该插件 新建一个该插件的文件夹, 一般情况下所必须的文件有: (1) lib 文件夹: 存放所需类库。 (2) src 文件夹: 存放相关源文件。 (3) database 文 件 夹 : 位 于 sec 文 件 夹 下 , 如 果 插 件 需要数 据 库 的 库 表 结 构 操 作 , 例 如 新 建 表 、 新 建 字 段 等 , 将 SQL文 件 放 于 此 文 件 夹 下 , 该 文 件 夹 下 的 SQL 文 件 会 在 插 件 加 载时运行, 完成所需数据库的相关操作。 (4) i18n 文 件 夹 : 存 放 国 际 化 文 件 , 即 相 关 的 文 字 显 示Openfire 的 相 关 显 示 文 字 都 在 i18n 中 后 缀 名 为 properties 的 文件中定义, 在程序中直接引用相关定义, 完成语言转换时的显示工作。 (5) Web 文 件 夹 : 存 放 该 插 件 的 显 示 界 面 。 包 括 images图片库、 style 样式表等相关文件夹以及该插件的 JSP 文件。 (6) plugins.xml 文件: 声明 该 插 件 的 文 件 。 包 括 如 表 1 所示内容。 表1: ※类文件名。 完整名称, 包括其包名 名称 简要说明, 显示于插件页面 作者 版本 日期 ※最低服务器版本 数据库密码, 经常不使用 数据库版本 显示位置, 其中的 url 指向点 击 后 显 示 的 界 面 ; Name 指明显示名称; description 指明鼠标悬停显示。 (7) 其 他 文 件 : changelog.html 版 本 信 息 、 readme.html 说 明、 logo_large.gif\logo_small.gif 图标等。 1.2 在 pulgins.xml 文 件 中 描 述 的处 建立 该 插 件 Java文件 建立该 Java 文件, 在一般情况下需继承 3 个接口: (1) Plugin: 包 含 必 须 实 现 的 initializePlugin 和 destroy-Plugin 两 个 接 口 , initializePlugin 插 件 建 立 , destroyPlugin 插 件 销毁。 (2) PropertyEventListener: 服 务 器 监 听 接 口 , 没 有 此 接 口 无法响应客户端 的请求。 一般不需要与客户端有交互的插件没 有继承此接口。 (3) Component: 管理收发的接口。 该 Java 文件将完成插件的主要 工 作 。 Openfire 已 经 封 装 好 了 XMPP 协 议 , 因 此 交 互 上 只 需 考 虑 封 装 的 内 容 , 封 装 后 的 传 输 由 XMPP 协 议 完 成 , 除 非 想 放 弃 XMPP 协 议 而 改 用 其 他 53 实用第一 协 议 。 当 然 , 也 可 以 建 立 其 他 的 Java 文 件 来 辅 助 其 完 成 相 应 功能。 1.3 在编写该 Java 文件时需要注意的几个地方: (1) 实 现 processPacket 接 口 时 , 需 要 组 装 一 个 packet 并 通 过 componentManager.sendPacket 发 送 出 去 , 该 组 装 通 过 智慧密集 handleIQRequest 来 完 成 , 而 handleIQRequest 中 只 需 完 成 对 插 件 自 身 命 名 空 间 的 编 写 , 其 余 的 XMPP 标 准 协 议 的 部 分 不 需 考虑。 (2) 该 Java 文 件 如 果 实 现 交 互 式 的 功 能 , 则 面 向 客 户 的 显示界面由 plugins.xml 中定义 的 url (jsp 文 件 ) 完 成 , 功 能 部 分 由 该 Java 文 件 完 成 , 如 果 实 现 的 不 是 交 互 式 的 功 能 , 可 以 直接在该 Java 文件中完成, 无需显示。 (3) 命名空间需要自己新建。 如 Search 插件 SearchPlubin.java 文件第 268 行 if (namespace.equals (NAMESPACE_JAB- BER_IQ_SEARCH)) { replyPacket = handleSearchRequest(iq); } 以上的 NAMESPACE_JABBER_IQ_SEARCH。最后, 将相关的文件制作成 Openfire 插件需要的 jar 文件, 通 过 Openfire 提 供 的 插 件 上 传 到 服 务 器 , 或 者 直 接 拷 贝 该 jar 文件到 Openfire 安装目录的 plugins 文件夹下。 1.4 插件开发 这里以自己开发的 “组织机构管理” 插件为例, 简要介绍 插 件 开 发 的 实 现 。 开 发 环 境 为 Openfire3_6_4+JDK1.6.0+ MyE- clipse5.1.0 (下同)。 首先, 准备需要的文 件 , 经 分 析 , 插 件 要 进行人机交互, 需要提供中文的交互界面, 并且需要对数据库 进行某些修改或添加。 根据上文对插件开发的分析, 需要提供 上文提到的全部文件。 首 先 建 立 了 一 个 Group 文 件 夹 , 在 其 中 建 立 了 lib、 src 文 件 夹 , src 文 件 夹 中 建 立 database、 i18n、 java、 web 文 件 夹 并 创 建 了 相 应 的 文 件 。 根 据 插 件 功 能 的 需 要 , 编 写 了 Default- GroupTreeProvider、 GroupTreeManager、 GroupTreeNode、 Group- TreeProvider 这 4 个 Java 文 件 来 辅 助 Group3Plugin.java 完 成 相 应功能。 并在 Web 文件夹中建立了人 机 交 互 界 面 group3-form. jsp, 并在 plugin.xml 文件中对其显示位置进行描述: 这样, 插件制作完成, 最后效果如图 所示。 2、 Openfire 源代码修改分析与解决 只要插件能胜任的工作, 建议都使用插件完成, 毕竟一旦 修改源代码, 带来的未知风险随之大大增加。 但是, 再某些特 定的情况下不得不进行源代码的修改时, 尽量进行小的改动达 到目的, 除非已经完全读懂全部的 Openfire 代码。 在修改完成 后要针对改后的服务器进行大量细致的测试, 保证所作改动不 会影响其他功能的正常运行。 2.1 Openfire 源代码修改与分析 首先, 如果出现问题, 应定位该问题出现的代码段, 并确 定 该 代 码 段 所 属 的 jar 包 , 一 旦 进 行 修 改 , 只 需 打 包 该 jar 包 , 并替换到服务器中即可完成相关的修改。 举个例子来说明: 在 使 用 Openfire 服 务 器 进 行 即 时 消 息 系 统 搭 建 的 过 程 中 , 发 现 进 行 UTF-8 编 码 的 中 文 传 输 经 常 会 有 乱 码 出 现 , 并 且 出 现的非常有规律, 每次都是一个字变成了 “??”, 如 “您好, 诚意??请您加入会议。” 并 且 这 些 “??” 不 是 每 次 都 出 现 , 相 同 的 语 句 、 相 同 的 操 作 也 是 时 有 时 无 。 于 是 , 在 调 试 环 境 下 对 Openfire 源 代 码 流 程 进 行 了 跟 踪 , 发 现 问 题 出 现 在 XMLLightweightParser.java 文件中。 public void read(ByteBuffer byteBuffer) throws Exception { invalidateBuffer(); if (buffer.length() > maxBufferSize) { throw new Exception("Stopped parsing never ending stanza"); } CharBuffer charBuffer = encoder.decode (byteBuffer. buf()); char[] buf = charBuffer.array(); int readByte = charBuffer.remaining(); if (readByte == 0) { return; } char lastChar = buf[readByte-1]; if (lastChar >= 0xfff0) { if (Log.isDebugEnabled()) { Log.debug ("Waiting to get complete char: " + String.valueOf(buf)); } byteBuffer.position(byteBuffer.position()-1); readByte--; if (readByte == 0) { return; } } //... } 其中 的 ByteBuffer 传 输 的 UTF-8 的 编 码 , 有 时 会 被 截 断 , 如 果 截 断 点 是 一 个 汉 字 编 码 的 结 尾 , 那 么 不 会 出 现 “??”, 如 果截断点是一个汉字编码的中间部分, 那么截断点到前一个汉 字编码的结尾被翻译成一个 “?”, 截断点到该汉字编码的结尾 被 翻 译 成 另 一 个 “?”, 这 就 是 出 现 一 个 汉 字 变 成 “??” 的 原 因。 于是, 着手修改这部分代码以让其能够更好地完成汉字编 码的转换工作, 解决乱码问题。 2.2 Openfire 源代码修改实现 针 对 XMLLightweightParser.java 进 行 了 相 关 分 析 , 觉 得 只 修 改 read 带 来 的 隐 形 问 题 不 会 很 多 , 于 是 , 着 手 对 其 进 行 改 造。 由于乱码问题是由截断点引起的, 需要将截断点消除掉, 于 是 , 将 原 来 有 ByteBuffer 转 换 成 CharBuffer 的 过 程 改 写 , 做 了 一 个 循 环 , 如 果 存 在 ByteBuffer 不 完 整 ( 即 存 在 截 断 点 ) , 那 么 将 其 放 置 到 一 个 tmp 变 量 中 , 再 将 tmp 与 下 一 个 Byte- Buffer 相 结 合 , 直 到 其 完 整 后 再 转 换 为 CharBuffer, 这 样 转 换 出来的汉字就不会存在 “??” 了。 这样做的好处是, 及解决了 乱 码 的 BUG, 又 不 改 变 原 来 程 序 的 运 行 方 式 , 非 中 文 或 者 完 整的 ByteBuffer 会 直 接 进 行 原 来 的 操 作 , 只 有 出 现 截 断 点 的 不 完整 ByteBuffer 才 会 进 行 编 写 的 代 码 , 拼 凑 成 完 整 的 , 这 大 大 降低了出现隐形问题的可能。 代 码 编 写 完 成 后 , 将 XMLLightweightParser.java 文 件 所 属 的 Openfire.jar 文 件 进 行 重 新 打 包 , 形 成 新 的 Openfire.jar, 并 将 该 jar 包 替 换 到 服 务 器 中 , 经 过 大 量 反 复 的 测 试 , 既 解 决 了汉字乱码问题, 又没有发现任何由于修改引起的错误。 3、 结语 目前, 经过修改和扩展的 Openfire 服务器已在即时消息系统中应用。 经实践检验, 经过插件扩 展 以 及 源 码 修 改 的 Open-fire 服 务 器 能 够 更 好 的 完 成 所 需 定 制 的 各 项 任 务 , 制 作 更 为 个性和精致的即时通信软件, 并且服务器运行稳定可靠, 具有较强的适应性和自主可控性。

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 3 金币 [ 分享文档获得金币 ] 20 人已下载

下载文档