开发XMPP IM

Openfire 是一个用Java 实现的XMPP 服务器,客户端可以通过IQ的方式与其进行通信(其实就是XML),客户端和服务器之间的通信是依靠底层Smack 库提供的各种功能来完成的。其实利用插件方式来扩展Openfire 服务器端主要有两种扩展方式,一种是对服务器控制台页面进行扩展(不是本文的主要内容),即遵循Openfire 页面的布局方式,进行相应的页面扩展和功能扩展另一种是对通信功能进行扩展。本文主要针对后者进行具体的描述。

本篇文章的结构如下:

1、创建plugin.xml(这是整个插件最关键的文档)。
    2、创建服务器插件实例(实现Plugin 接口的一个类还有一批IQHandler)。
    3、打包插件(Openfire 插件也有自己的打包方式)和部署插件。

1、创建plugin.xml

初次开发Openfire 和Spark 插件的时候,很容易把二者搞混,千万记得,这里是Openfire 的plugin.xml 不是第二篇文章说的那个啦!

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <plugin>
 3     <!-- Main plugin class  这里是最重要滴-->
 4     <class>com.im.server.plugin.GroupTreePlugin</class>
 5
 6     <!-- Plugin meta-data -->
 7     <name>GroupTreePlugin</name>
 8     <description>This is the group plugin.</description>
 9     <author>Phoenix</author>
10
11     <version>1.0</version>
12     <date>14/03/2008</date>
13     <url>http://localhost:9001/openfire/plugins.jsp</url>
14     <minServerVersion>3.4.1</minServerVersion>
15     <licenseType>gpl</licenseType>
16
17     <!-- Admin console entries -->
18     <adminconsole>
19         <!-- More on this below -->
20     </adminconsole>
21 </plugin>

最重要的那一行我已经标记出来啦,就是你这个插件的初始化垃圾清理类,例子中是在com.im.server.plugin 包中的GroupTreePlugin 类,下文会对这个类进行详细描述。其余的都是描述信息,只要你提供了正确的描述信息,一般都不会出错。建议初次开发者,在写完plugin.xml 文件后,写一个简单的Plugin 实例,并打印出一些信息,如果重新启动Openfire 信息成功显示,恭喜你,你已经迈出一大步了!

2、实现Plugin 类和IQHandler

Plugin 类主要起到的作用是初始化和释放资源,在初始化的过程中,最重要的的注册一批IQHandler,IQHander 的作用有点类似于Spark 中的IQProvider,其实就是解析XML 文件之后,生成一些有用的实例,以供处理。下面分别给出一个Plugin 类的实例和IQProvider 的实例:

GroupTreePlugin 类

 1 /**
 2  * 服务器端插件类
 3  *
 4  * @author Phoenix
 5  *
 6  * Mar 14, 2008 11:03:11 AM
 7  *
 8  * version 0.1
 9  */
10 public class GroupTreePlugin implements Plugin
11 {
12     private XMPPServer server;
13
14     /*
15      * (non-Javadoc)
16      *
17      * @see org.jivesoftware.openfire.container.Plugin#destroyPlugin()
18      */
19     public void destroyPlugin()
20     {
21
22     }
23
24     /*
25      * (non-Javadoc)
26      *
27      * @see org.jivesoftware.openfire.container.Plugin#initializePlugin(org.jivesoftware.openfire.container.PluginManager,
28      *      java.io.File)
29      */
30     public void initializePlugin(PluginManager manager, File pluginDirectory)
31     {
32         PluginLog.trace("注册群组树IQ处理器");
33         server = XMPPServer.getInstance();
34
35         server.getIQRouter().addHandler(new GroupTreeIQHander()); //1
36         server.getIQRouter().addHandler(new UserInfoIQHandler());
37         server.getIQRouter().addHandler(new DelUserIQHandler());
38         server.getIQRouter().addHandler(new CreateUserIQHandler());
39         server.getIQRouter().addHandler(new AddGroupUserIQHandler());
40         server.getIQRouter().addHandler(new SetRoleIQHandler());
41     }
42 }

上例所示,在初始化中先找到IQRouter,然后通过IQRouter 注册一批IQHandler,这些IQHander 会自动监听相应命名空间的IQ,然后进行处理;由于这个Plugin 不需要做资源释放的工作,所以在destroyPlugin() 方法中没有任何内容。具体的IQHander 类如下:

GroupTreeIQHander 类

 1 /**
 2  * 处理客户端发来的IQ,并回送结果IQ
 3  *
 4  * @author Phoenix
 5  *
 6  * Mar 14, 2008 4:55:33 PM
 7  *
 8  * version 0.1
 9  */
10 public class GroupTreeIQHander extends IQHandler
11 {
12     private static final String MODULE_NAME = "group tree handler";
13     private static final String NAME_SPACE = "com:im:group";
14     private IQHandlerInfo info;
15
16     public GroupTreeIQHander()
17     {
18         super(MODULE_NAME);
19         info = new IQHandlerInfo("gruops", NAME_SPACE);
20     }
21
22     /*
23      * (non-Javadoc)
24      *
25      * @see org.jivesoftware.openfire.handler.IQHandler#getInfo()
26      */
27     @Override
28     public IQHandlerInfo getInfo()
29     {
30         return info;
31     }
32
33     /*
34      * (non-Javadoc)
35      *
36      * @see org.jivesoftware.openfire.handler.IQHandler#handleIQ(org.xmpp.packet.IQ)
37      */
38     @Override
39     public IQ handleIQ(IQ packet) throws UnauthorizedException
40     {
41         IQ reply = IQ.createResultIQ(packet);
42         Element groups = packet.getChildElement();//1
43
44         if (!IQ.Type.get.equals(packet.getType()))
45         {
46             System.out.println("非法的请求类型");
47             reply.setChildElement(groups.createCopy());
48             reply.setError(PacketError.Condition.bad_request);
49             return reply;
50         }
51
52         String userName = StringUtils.substringBefore(packet.getFrom().toString(),"@");
53         GroupManager.getInstance().initElement(groups,userName);
54         reply.setChildElement(groups.createCopy());//2
55         System.out.println("返回的最终XML" + reply.toXML());
56         return reply;
57     }
58 }

可以看到主要有两个方法,一个是getInfo() ,这个方法的目的是提供要解析的命名空间,在本例中,这个IQHandler 对每个命名空间为"com:im:group" 的实例进行处理;还有一个最重要的方法:handleIQ() ,该方法对包含指定命名空间的XML 进行解析,然后返回一个解析好的IQ。其实我认为,这个IQHandler 和IQ 的关系就是Controller 和Model 的关系(如果你了解MVC 的话,那么你一定知道我再说什么),只不过这里并没有指定什么View,你完全可以把IQ 当成Model 类进行理解。在这里,我用了GroupManager 进行了XML 的处理,因为我返回的IQ 内容中要从数据库读取所有群组信息,所以转交给GroupManager 进行处理,你完全可以在这个方法中进行具体的XML 处理,在这里,解析和创建新的XML 主要用到的是JDOM(如果你对Java 解析XML 有所了解,那真的太好了!)。程序//1 处主要是获取创建返回的IQ,并获取原来IQ 的子元素(用于创建我们返回的IQ);程序//2 处很关键,如果你不调用createCopy 方法,程序会出错(程序会死锁还是什么,忘记咧,不好以西)。

这就是程序的主体部分,我在这里有一个建议,能不用Openfire 原始的程序函数,就不要用它们。我的提取数据库方式都是自己写的Bean,这样有利于你自己对程序的掌控,其实更有利于快速开发(这世道不是啥都讲究敏捷么,哇哈哈)

3、打包插件

打包依然遵循二次打包的原则(如果你不了解啥叫要二次打包,请看上一篇)。这是我的ant 文件,由于Eclipse 帮我做了build 等很多工作,实际我的ant 工作就是在打包,并放入插件目录下的plugin 文件夹下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project name="IM" default="release" basedir=".">
 3
 4     <property name="openfire.path"
 5         value="E:/workspace/europa/openfire_src/target/openfire" />
 6     <property name="classes.dir" value="classes" />
 7     <property name="lib.dir" value="lib" />
 8
 9     <target name="jar">
10         <jar jarfile="${lib.dir}/grouptreeplugin.jar" basedir="${classes.dir}" >
11             <fileset dir=".">
12                 <include name="*.jar"/>
13             </fileset>
14         </jar>
15         <jar jarfile="${openfire.path}/plugins/groupTreePlugin.jar">
16             <fileset dir=".">
17                 <include name="lib/*.jar" />
18                 <include name="plugin.xml" />
19                 <include name="logo_small.gif" />
20                 <include name="logo_large.gif" />
21                 <include name="readme.html" />
22                 <include name="changelog.html" />
23                 <include name="build.xml" />
24             </fileset>
25         </jar>
26
27     </target>
28
29     <target name="release" depends="jar">
30     </target>
31
32 </project>
时间: 2024-10-05 20:43:54

开发XMPP IM的相关文章

WPF一步步开发XMPP IM客户端:入门

[起因&目标] 因为工作原因接触openfire服务端和spark客户端开发2年,主要是基于openfire扩展开发了针对企业用途的服务器插件,还开发了各个平台上的客户端,详情可搜索微信公众号:CVTalk 在开发过程中,发现基于Spark开发Java Swing客户端(公司内部命名CVTalk)比较重,用户体验很难做到和微信客户端看齐,皮肤的开发也比较费力,公司里绝大部分是windows的客户端,而且高清分辨率屏幕的用户越来越多,内存占用过多的问题也解决不了,swing客户端越发力不从心. 于

ios开发xmpp仿微信即时聊天工具

最近在做一个项目,需要一个即时聊天工具,先打算有第三方环信(http://www.easemob.com),但是最终老板不允许,要自己开发用自己的服务器,哎!如果有需要的可以去看看这个环信,真的不错.进入今天的主题,其实也是大神们开发的,我在这只是把一些细节理一下让大家你能少走一点弯路,需要的资料和源码这里面都有http://pan.baidu.com/s/1nt5esnn. 详细的介绍看这http://blog.csdn.net/kangx6/article/details/7740135,看

项目开发--------XMPP即时通讯

一.基本框架结构: StroyBoard的基本页面搭建: 二.个功能代码块的是实现 LoginViewController.m文件(登录页面的基本配置) #import "LoginViewController.h" #import "XMPPManager.h" @interface LoginViewController ()<XMPPStreamDelegate> @property (weak, nonatomic) IBOutlet UITex

手机上使用asmack开发xmpp客户端

openfire服务端,smack:     下载地址:http://www.igniterealtime.org/downloads/index.jsp     源代码:http://www.igniterealtime.org/downloads/source.jspandroid客户端库,asmack:    首页:https://github.com/Flowdalic/asmack    源代码及jar包:http://asmack.freakempire.de/服务端搭建指导:htt

2、WPF一步步开发XMPP IM客户端:主窗体设计

UI设计方案: 在设计窗体UI之前,先要了解一些主要的接口和帮助类: 对于主窗的左侧列表,容器内的Item必须实现ILeftItem的接口,比如联系人.系统消息.群等,接口包含点击事件 public interface ILeftItem { void Click(); } 项目的最外围容器是MainWindow,他涵盖了第一级菜单.第二级菜单.内容区等 其中更新菜单是在类UIStatic中: /// <summary> /// 设置第一级"业务"菜单文本 /// <

开源Jabber(XMPP) IM服务器介绍

一.摘要 这是我粗略读了一遍Jabber协议和相关技术文章后的产物,有些地方不一定准确.在文章中引用的一些代码来自www.jabber.org上的文章. 二. 什么是Jabber    Jabber就像ICQ,MSN一样,是一个基于Internet的即时通讯系统,但是同这些即时通讯软件不同的是,它是一个开放的即时通讯系统,也是一 个基于XML Stream 的协议,用于在Internet上的两个实体之间交换信息,现场状态(presence)和其他的结构化信息.你可以自己架设自己的Jabber服务

ios配置xmpp即时聊天-服务器端

一.安装 到MySQL官网上http://dev.mysql.com/downloads/mysql/,下载mysql可安装dmg版本 比如:Mac OS X ver. 10.7 (x86, 64-bit), DMG Archive 下载完的文件为:mysql-5.6.10-osx10.7-x86_64.dmg 1.点击,安装包里的 2.点击安装 安装好后,再系统偏好设置的其他里,会出现如下图标: 3.点击此图标,跳出对话框 点击Start MySQL Server按钮,启动mysql 二.打开

xmpp整理笔记:xmppFramework框架的导入和介绍

一个将要开发xmpp的项目,建议在项目刚创建就导入框架,这样可以避免一些自己操作失误造成不必要的损失. xmpp中最常用的框架就是 xmppFrameWork 往期回顾: xmpp整理笔记:环境的快速配置(附安装包)  http://www.cnblogs.com/dsxniubility/p/4304570.html 如果你不是在董铂然博客园看到本文请 点击查看原文 第一种方法直接拖 1> 拖入文件夹 在网盘链接的xmppFramework文件夹 :http://pan.baidu.com/s

XMPP 基础 (转载)

技术博客 http://www.cnblogs.com/ChenYilong/  新浪微博 http://weibo.com/luohanchenyilong Fullscreen XMPP   基础 技术博客 http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong   即时通讯技术简介  •   即时通讯技术( IM )支持用户在线实时交谈.如果要发送一条信息,用户需 要打开一个小窗口,以便让用户及其朋友