openfire+spark+smack.docx
- 文档编号:30296554
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:11
- 大小:92.91KB
openfire+spark+smack.docx
《openfire+spark+smack.docx》由会员分享,可在线阅读,更多相关《openfire+spark+smack.docx(11页珍藏版)》请在冰豆网上搜索。
openfire+spark+smack
即时通讯软件openfire+spark+smack
开发你自己的XMPPIM-[J2EE]
这几天查国内外的资料,发现国内关于这方面间的软件资料太少了,就想在这里写几篇关于此类IM软件开发的文章。
不过别看东西小,涉及的模块可不少。
所以我基本上分为三篇文章来介绍此类软件的开发:
第一篇是关于XMPP协议是啥,IM是啥以及一个比较有名的开源实现,该开源实现包括三个部分(Spark、Smack和Openfire);
第二篇讲如何开发基于Spark的客户端IM插件部分;
第三篇讲如何开发基于Openfire服务器端的插件部分。
好了,进入正题吧。
什么是XMPP?
ExtensibleMessagingandPresenceProtocol,简单的来讲,它就是一个发送接收处理消息的协议,但是这个协议发送的消息,既不是二进制的东东也不是字符串,而是XML。
正是因为使用了XML作为消息传递的中介,Extensible才谈的上,不是么?
嘿嘿。
再详尽的东西,我也就不多介绍了,大家可以去XX百科里查看下。
什么是IM?
InstantMessenger,及时通信软件,就是大家使用的QQ、MSNMessenger和Gtalk等等。
其中Gtalk就是基于XMPP协议的一个实现,其他的则不是。
当前IM几乎作为每个上网者必然使用的工具,在国外的大型企业中有一些企业级的IM应用,但是其商业价值还没完全发挥出来。
设想既然XMPP协议是一个公开的协议,那么每个企业都可以利用它来开发适合本身企业工作,提高自身生产效率的IM;甚至,你还可以在网络游戏中集成这种通信软件,不但让你可以边游戏边聊天,也可以开发出适合游戏本身的IM应用,比如说一些游戏关键场景提醒功能,团队语音交流等等都可以基于IM来实现。
说了这么多,就是一个意思,其商业价值远远比你想的高!
SparkSmack和Openfire
开源界总是有许多有趣的东东,这三个合起来就是一个完整的XMPPIM实现。
包括服务器端——Openfire,客户端——Spark,XMPP传输协议的实现——Smack(记住,XMPP是一个协议,协议是需要实现的,Smack起到的就是这样的一个作用)。
三者都是基于Java语言的实现,因此对于熟悉Java的开发者来说不是很难
Spark提供了客户端一个基本的实现,并提出了一个很好的插件架构,这对于开发者来说不能不说是一个福音。
我强烈建议基于插件方式来实现你新增加的功能,而不是去改它的源代码,这样有利于你项目架构,把原始项目的影响降到最低,文章以后的部分也是基于这种插件体系进行开发的
Openfire是基于XMPP协议的IM的服务器端的一个实现,虽然当两个用户连接后,可以通过点对点的方式来发送消息,但是用户还是需要连接到服务器来获取一些连接信息和通信信息的,所以服务器端是必须要实现的。
Openfire也提供了一些基本功能,但真的很基本的!
庆幸的是,它也提供插件的扩展,像Spark一样,我同样强烈建议使用插件扩展的方式来增加新的功能,而不是修改人家的源代码。
Smack是一个XMPP协议的Java实现,提供一套可扩展的API,不过有些时候,你还是不得不使用自己定制发送的XML文件内容的方式来实现自己的功能
下图展示了三者之间的关系:
从图上可以了解到,client端和server端都可以通过插件的方式来进行扩展,smack是二者传递数据的媒介。
开发你自己的XMPPIM续-Spark插件开发-[J2EE]
继续3月18日介绍基于XMPPIM开发的那篇Blog,今天主要总结一下如何基于Spark的插件架构来新增客户端的功能,这里列举出一个获取服务器端群组信息的实际例子,实现后的效果如下图所示:
Spark是一个基于XMPP协议,用Java实现的IM客户端。
它提供了一些API,可以采用插件机制进行扩展,上图中,“部门”部分就是使用插件机制扩展出来的新功能。
要想实现你的扩展,首先要了解SparkAPI的架构,其中最关键的是要了解它的工厂类,这些工厂类可以获得Spark提供的诸如XMPPConnection、ChatContainer等实例,从而你可以实现获取服务器的信息,与另外的Client通信等功能。
最核心的类是SparkManager,这个类是一系列工厂类的工厂类(呵呵,还真拗口)。
它的getChatManager()、getSessionManager()、getMainWindow()、getConnection()等方法分别可以获得聊天管理器、会话管理器、主窗口、与服务器的连接等等非常有用的实例。
基本上可以说SparkManager是你与Spark打交道的衔接口。
其实,每一个Manager都使用了单例模式,你也可以不通过SparkManager来获取它们,但笔者建议你从单一的入口着手,这样有利于代码的开发和维护。
接下来描述一下插件的开发流程:
1、创建插件配置文件plugin.xml
2、实现你自己的Plugin类的实现(如果你需要实现自己规定格式的XML发送、接收和处理,那么你需要在这里注册你的IQProvider,关于IQProvider你可以查询SmackAPI,简单的来讲是处理你自定义的IQ处理器。
)
3、打包你的插件(Spark有自己的打包机制,我研究了半天才发现其中的玄机,后面介绍)
4、部署你的插件(其实3、4两步可以糅合在一起,当然要利用Ant啦)
好滴,下面结合一个实际的例子讲述上面的四个步骤
1、plugin.xml
--关键是这里,这里要定义你的Plugin类-->
--这里定义你使用的Spark最低版本-->
这是一个plugin.xml文件的内容,插件体系会自动调用你在此文件中定义的Plugin类,从而完成你自己扩展的功能。
最关键的部分我用红色标识出来了,要声明你的插件扩展类,采用完整的命名空间方式(包括包名),其余的部分结合我的注释,大家应该都能理解,就不做详细的描述了。
要注意的是plugin.xml文件要放在项目的根目录下,这是严格规定好的。
2、Plugin类的实现
你的类首先要实现Spark提供的Plugin接口,然后实现它的一些方法。
其中最主要的是实现initialize()发放,在这里注册你的的IQProvider
ProviderManagerproviderManager=ProviderManager.getInstance();
providerManager.addIQProvider("groups","com:
im:
group",//1
newGroupTreeIQProvider());
System.out.println("注册GroupTreeIQ提供者");
requestGroupTree();
上述的代码,就在该类就是我实现的IMPlugin.initialize()方法中的一小段,大概的含义是,先获取ProviderManager(这个貌似不能从SparkManager直接获取),然后注册一个GroupTreeIQProvider(自己创建的)这是一个IQProvider的具体实现,它用于解析像下面这样的一个XML文件:
xmlversion="1.0"encoding="UTF-8"?
>
im: group'> 可以看到,在注册IQProvider的时候(代码中标注的1部分),需要你提供名称和命名空间,我的XML文件中的iq下的第一个子节点是 im: group”,其实IQProvider中最关键的方法是parseIQ(XmlPullParserparser)该方法就是解析XML,完成你的功能,并返回一个相应的IQ实例(这里可以把IQ看做一个回馈的Model类)。 说到底实现基于XMPP协议的IM就是解析XML文件,而这正是客户端的IQProvider和服务器端的IQHandler(下一篇文章会涉及到)所做的事情。 3、打包你的插件 现在该有的功能都实现了,那么就是打包了。 这最好利用Ant来完成,因为每次你都要打包,要部署,如果纯手动的话,那也太不敏捷了,大大影响开发效率。 xmlversion="1.0"encoding="UTF-8"? > value="E: /workspace/europa/spark_new/doc/spark/target/build"/> -- --> -- --> -- --> --最重要的是这里,打两次包--> publicclassGroupTreePluginimplementsPlugin { privateXMPPServerserver; publicvoiddestroyPlugin() { } publicvoidinitializePlugin(PluginManagermanager,FilepluginDirectory) { PluginLog.trace("注册群组树IQ处理器"); server=XMPPServer.getInstance(); server.getIQRouter().addHandler(newGroupTreeIQHander());//1 server.getIQRouter().addHandler(newUserInfoIQHandler()); server.getIQRouter().addHandler(newDelUserIQHandler()); server.getIQRouter().addHandler(newCreateUserIQHandler()); server.getIQRouter().addHandler(newAddGroupUserIQHandler()); server.getIQRouter().addHandler(newSetRoleIQHandler()); } } 上例所示,在初始化中先找到IQRouter,然后通过IQRouter注册一批IQHandler,这些IQHander会自动监听相应命名空间的IQ,然后进行处理;由于这个Plugin不需要做资源释放的工作,所以在destroyPlugin()方法中没有任何内容。 具体的IQHander类如下 GroupTreeIQHander publicclassGroupTreeIQHanderextendsIQHandler { privatestaticfinalStringMODULE_NAME="grouptreehandler"; privatestaticfinalStringNAME_SPACE="com: im: group"; privateIQHandlerInfoinfo; publicGroupTreeIQHander() { super(MODULE_NAME); info=newIQHandlerInfo("gruops",NAME_SPACE); } @Override publicIQHandlerInfogetInfo() { returninfo; } @Override publicIQhandleIQ(IQpacket)throwsUnauthorizedException { IQreply=IQ.createResultIQ(packet); Elementgroups=packet.getChildElement();//1 if(! IQ.Type.get.equals(packet.getType())) { System.out.println("非法的请求类型"); reply.setChildElement(groups.createCopy()); reply.setError(PacketError.Condition.bad_request); returnreply; } StringuserName=StringUtils.substringBefore(packet.getFrom().toString(),"@"); GroupManager.getInstance().initElement(groups,userName); reply.setChildElement(groups.createCopy());//2 System.out.println("返回的最终XML"+reply.toXML()); returnreply; } } 可以看到主要有两个方法,一个是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文件夹下 xmlversion="1.0"encoding="UTF-8"? > value="E: /workspace/europa/openfire_src/target/openfire"/> 好了,至此XMPP+Spark+Openfire的插件开发三部曲彻底结束了,希望你们对这个开发流程有了系统的了解。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- openfire spark smack