??xml version="1.0" encoding="utf-8" standalone="yes"?>久久亚洲AV成人无码电影,亚洲人成电影在线天堂,日韩精品亚洲人成在线观看 http://www.tkk7.com/duanzhimin528/category/45564.htmlLife is a voyage, not a destination.zh-cnThu, 02 Sep 2010 12:48:21 GMTThu, 02 Sep 2010 12:48:21 GMT60openfire3.6.3插g开发方?/title><link>http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326146.html</link><dc:creator>DZM.528</dc:creator><author>DZM.528</author><pubDate>Wed, 14 Jul 2010 14:53:00 GMT</pubDate><guid>http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326146.html</guid><wfw:comment>http://www.tkk7.com/duanzhimin528/comments/326146.html</wfw:comment><comments>http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326146.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/duanzhimin528/comments/commentRss/326146.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/duanzhimin528/services/trackbacks/326146.html</trackback:ping><description><![CDATA[     摘要: openfire3.6.3插g开发方法说明:(x) 作用:初始化时在控制台打印试消息?开发环境:(x)winxp/myeclipse6.5/jdk1.5&1.6/mysql5.0/openfire3.6.3 QQ:(x)28588322 (openfire专题研究组) 开发步骤:(x) 1. 布vopenfire3.6.3源码Q请参考openfire3.6.3导入ec...  <a href='http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326146.html'>阅读全文</a><img src ="http://www.tkk7.com/duanzhimin528/aggbug/326146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/duanzhimin528/" target="_blank">DZM.528</a> 2010-07-14 22:53 <a href="http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Openfire插g开发h员指?/title><link>http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326138.html</link><dc:creator>DZM.528</dc:creator><author>DZM.528</author><pubDate>Wed, 14 Jul 2010 14:06:00 GMT</pubDate><guid>http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326138.html</guid><wfw:comment>http://www.tkk7.com/duanzhimin528/comments/326138.html</wfw:comment><comments>http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/duanzhimin528/comments/commentRss/326138.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/duanzhimin528/services/trackbacks/326138.html</trackback:ping><description><![CDATA[     摘要: 插g是增强Openfire功能。这份文件是一个开发h员创建插件指南?nbsp; <a href='http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326138.html'>阅读全文</a><img src ="http://www.tkk7.com/duanzhimin528/aggbug/326138.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/duanzhimin528/" target="_blank">DZM.528</a> 2010-07-14 22:06 <a href="http://www.tkk7.com/duanzhimin528/archive/2010/07/14/326138.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开发你自己的XMPP IM l?- Openfire 插g开?/title><link>http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325911.html</link><dc:creator>DZM.528</dc:creator><author>DZM.528</author><pubDate>Mon, 12 Jul 2010 15:05:00 GMT</pubDate><guid>http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325911.html</guid><wfw:comment>http://www.tkk7.com/duanzhimin528/comments/325911.html</wfw:comment><comments>http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/duanzhimin528/comments/commentRss/325911.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/duanzhimin528/services/trackbacks/325911.html</trackback:ping><description><![CDATA[ <a target="_blank" style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 160, 233);"> </a> <span id="1616111" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="1161116" class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Georgia,serif,宋体; font-size: 12px; line-height: 19px; text-align: left;"> <div id="6111166" class="postBody" style="margin: 10px 0px; padding: 0px 0px 0px 20px; word-wrap: break-word;"> <p> <span id="6116666" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="1611661" class="Apple-style-span" style="color: rgb(101, 101, 101); font-family: Verdana,Arial,Helvetica,sans-serif; font-size: 14px; line-height: 28px; text-align: left;">此篇文章为?/span> </span> <span id="6116161" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="6116111" class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Georgia,serif,宋体; font-size: 12px; line-height: 19px; text-align: left;"> <span id="6116116" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="1161116" class="Apple-style-span" style="color: rgb(101, 101, 101); font-family: Verdana,Arial,Helvetica,sans-serif; font-size: 14px; line-height: 28px; text-align: left;"> </span> </span> <font size="3"> <b> <span id="1611111" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="1111111" class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Georgia,serif,宋体; font-size: 12px; line-height: 19px; text-align: left;">开 发你自己的XMPP IM l?- Openfire 插g开?/span> </span> </b> </font> </span> </span> <span id="6616161" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="1161111" class="Apple-style-span" style="color: rgb(101, 101, 101); font-family: Verdana,Arial,Helvetica,sans-serif; font-size: 14px; line-height: 28px; text-align: left;">》的转发Q原文章地址: </span> </span> <span id="6666111" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="1116611" class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Georgia,serif,宋体; font-size: 12px; line-height: 21px; text-align: center;"> <a style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 160, 233);">http://phoenixtoday.blogbus.com/logs/20285574.html</a> </span> </span> <font size="3"> <b> <span id="6111611" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="6166166" class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Georgia,serif,宋体; font-size: 12px; line-height: 19px; text-align: left;"> </span> </span> </b> </font> </p> <span style="margin: 0px; padding: 0px;">l箋上一的内容Q本文章介l开发Openfire 的插?/span> <span style="margin: 0px; padding: 0px;"> <span style="margin: 0px; padding: 0px;"> <span style="margin: 0px; padding: 0px;"> <span style="margin: 0px; padding: 0px;"> <span style="margin: 0px; padding: 0px;"> <br style="margin: 0px; padding: 0px;" /> </span> </span> </span> </span> </span> <br style="margin: 0px; padding: 0px;" />q篇文章拖了(jin)很久?jin),呵呵Q真是千g唤始出来呀。Openfire 服务器端是支持插件开发的Q开发过E可能会(x)涉及(qing)到数据库的操作,本篇文章专注于Openfire 插g的部分,Ҏ(gu)务器端涉?qing)到数据库的开发只做简单介l?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />Openfire 是一个用Java 实现的XMPP 服务器,客户端可以通过IQ 的方式与其进行通信Q其实就是XMLQ,客户端和服务器之间的通信是依靠底层Smack 库提供的各种功能来完成的。其实利用插件方式来扩展Openfire 服务器端主要有两U扩展方式,一U是Ҏ(gu)务器控制台页面进行扩展(不是本文的主要内容)(j)Q其实就是遵循Openfire 面的布局方式Q进行相应的面扩展和功能扩展;另一U是寚w信功能q行扩展。本文主要针对后者进行具体的描述<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />本篇文章的结构如下:(x)<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />1、创建plugin.xmlQ这是整个插件最关键的文档)(j)<br style="margin: 0px; padding: 0px;" />2、创建服务器插g实例Q实现Plugin 接口的一个类q有一批IQHandlerQ?br style="margin: 0px; padding: 0px;" />3、打包插ӞOpenfire 插g也有自己的打包方式)(j)和部|插?br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"><span style="margin: 0px; padding: 0px; background-color: rgb(255, 255, 255);"><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"><span style="margin: 0px; padding: 0px; background-color: rgb(255, 255, 255);"><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"><br style="margin: 0px; padding: 0px;" /></span></span></span></span></span>好滴Q实刀实枪的来动手做吧<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />1、创建plugin.xml<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />初次开发Openfire 和Spark 插g的时候,很容易把二者搞P千万记得Q这里是Openfire 的plugin.xml 不是W二文章说的那个啦Q?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"><?xml version="1.0" encoding="UTF-8"?></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"><plugin></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <!-- Main plugin class  q里是最重要?-></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <class>com.im.server.plugin.GroupTreePlugin</class></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <!-- Plugin meta-data --></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <name>GroupTreePlugin</name></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <description>This is the group plugin.</description></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <author>Phoenix</author></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <version>1.0</version></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <date>14/03/2008</date></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <url>http://localhost:9001/openfire/plugins.jsp</url></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <minServerVersion>3.4.1</minServerVersion></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <licenseType>gpl</licenseType></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <!-- Admin console entries --></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <adminconsole></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        <!-- More on this below --></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    </adminconsole></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"></plugin></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />最重要的那一行我已经标记出来啦,是你这个插件的初始化和垃圾清理c,例子中是在com.im.server.plugin 包中的GroupTreePlugin c,下文?x)对q个c进行详l描q。其余的都是描述信息Q只要你提供?jin)正的描述信息Q一般都不会(x)出错。徏议初ơ开发者,在写完plugin.xml 文g后,写一个简单的Plugin 实例Qƈ打印Z些信息,如果重新启动Openfire 信息成功昄Q恭喜你Q你已经q出一大步?jin)?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />2、实现Plugin cdIQHandler<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />Plugin cM要v到的作用是初始化和释放资源,在初始化的过E中Q最重要的的注册一批IQHandlerQIQHander 的作用有点类gSpark 中的IQProviderQ其实就是解析XML 文g之后Q生成一些有用的实例Q以供处理。下面分别给Z个Plugin cȝ实例和IQProvider 的实?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />GroupTreePlugin c?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">/**</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * 服务器端插gc?/span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> *<span id="6611111" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * @author Phoenix</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> *<span id="1611666" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * Mar 14, 2008 11:03:11 AM</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> *<span id="6111111" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * version 0.1</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> */</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">public class GroupTreePlugin implements Plugin</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">{</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    private XMPPServer server;</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    /*</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * (non-Javadoc)</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     *<span id="1161661" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * @see org.jivesoftware.openfire.container.Plugin#destroyPlugin()</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     */</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    public void destroyPlugin()</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    {</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    }</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    /*</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * (non-Javadoc)</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     *<span id="6161166" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * @see org.jivesoftware.openfire.container.Plugin#initializePlugin(org.jivesoftware.openfire.container.PluginManager,</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     *      java.io.File)</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     */</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    public void initializePlugin(PluginManager manager, File pluginDirectory)</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    {</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        PluginLog.trace("注册组?wi)IQ处理?);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        server = XMPPServer.getInstance();</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">       <span id="1116111" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        server.getIQRouter().addHandler(new GroupTreeIQHander()); //1</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        server.getIQRouter().addHandler(new UserInfoIQHandler());</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        server.getIQRouter().addHandler(new DelUserIQHandler());</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        server.getIQRouter().addHandler(new CreateUserIQHandler());</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        server.getIQRouter().addHandler(new AddGroupUserIQHandler());</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        server.getIQRouter().addHandler(new SetRoleIQHandler());</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    }</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">}</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />上例所C,在初始化中先扑ֈIQRouterQ然后通过IQRouter 注册一批IQHandlerQ这些IQHander ?x)自动监听相应命名空间的IQQ然后进行处理;׃q个Plugin 不需要做资源释放的工作,所以在destroyPlugin() Ҏ(gu)中没有Q何内宏V具体的IQHander cd?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />GroupTreeIQHander<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">/**</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * 处理客户端发来的IQQƈ回送结果IQ</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> *<span id="1611116" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * @author Phoenix</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> *<span id="1111111" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * Mar 14, 2008 4:55:33 PM</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> *<span id="1166611" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> * version 0.1</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"> */</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">public class GroupTreeIQHander extends IQHandler</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">{</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    private static final String MODULE_NAME = "group tree handler";</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    private static final String NAME_SPACE = "com:im:group";</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    private IQHandlerInfo info;</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    public GroupTreeIQHander()</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    {</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        super(MODULE_NAME);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        info = new IQHandlerInfo("gruops", NAME_SPACE);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    }</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    /*</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * (non-Javadoc)</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     *<span id="1166661" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * @see org.jivesoftware.openfire.handler.IQHandler#getInfo()</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     */</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    @Override</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    public IQHandlerInfo getInfo()</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    {</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        return info;</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    }</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    /*</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * (non-Javadoc)</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     *<span id="1116611" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     * @see org.jivesoftware.openfire.handler.IQHandler#handleIQ(org.xmpp.packet.IQ)</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">     */</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    @Override</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    public IQ handleIQ(IQ packet) throws UnauthorizedException</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    {</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        IQ reply = IQ.createResultIQ(packet);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        Element groups = packet.getChildElement();//1</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">       <span id="6111616" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        if (!IQ.Type.get.equals(packet.getType()))</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        {</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            System.out.println("非法的请求类?);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            reply.setChildElement(groups.createCopy());</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            reply.setError(PacketError.Condition.bad_request);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            return reply;</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        }</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">       <span id="6161611" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        String userName = StringUtils.substringBefore(packet.getFrom().toString(),"@");</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        GroupManager.getInstance().initElement(groups,userName);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">       <span id="1111666" class="Apple-converted-space"> </span></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        reply.setChildElement(groups.createCopy());//2</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        System.out.println("q回的最lXML" + reply.toXML());</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        return reply;</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    }</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">}</span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />可以看到主要有两个方法,一个是getInfo() q个Ҏ(gu)的目的是提供要解析的命名I间Q在本例中,q个IQHandler Ҏ(gu)个命名空间ؓ(f)"com:im:group" 的实例进行处理;q有一个最重要的方法:(x)handleIQ() 该方法对包含指定命名I间的XML q行解析Q然后返回一个解析好的IQ。其实我认ؓ(f)Q这个IQHandler 和IQ 的关pd是Controller 和Model 的关p(如果你了(jin)解MVC 的话Q那么你一定知道我再说什么)(j)Q只不过q里q没有指定什么ViewQ你完全可以把IQ 当成Model c进行理解。在q里Q我用了(jin)GroupManager q行?jin)XML 的处理,因ؓ(f)我返回的IQ 内容中要从数据库d所有群l信息,所以{交给GroupManager q行处理Q你完全可以在这个方法中q行具体的XML 处理Q在q里Q解析和创徏新的XML 主要用到的是JDOMQ如果你对Java 解析XML 有所?jin)解Q那真的太好?jin)!Q。程?/1 处主要是获取创徏q回的IQQƈ获取原来IQ 的子元素Q用于创建我们返回的IQQ;E序//2 处很关键Q如果你不调用createCopy Ҏ(gu)Q程序会(x)出错Q程序会(x)死锁q是什么,忘记咧,不好以西Q?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />q就是程序的M部分Q我在这里有一个徏议,能不用Openfire 原始的程序函敎ͼ׃要用它们。我的提取数据库方式都是自己写的BeanQ这h利于你自己对E序的掌控,其实更有利于快速开发(q世道不是啥都讲I敏捷么Q哇哈哈Q?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />3、打包插?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />打包依然遵@二次打包的原则(如果你不?jin)解啥叫要二ơ打包,L(fng)上一)(j)<br style="margin: 0px; padding: 0px;" />q是我的ant 文gQ由于Eclipse 帮我做了(jin)build {很多工作,实际我的ant 工作是在打包,q放入插件目录下的plugin 文g夹下<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"><?xml version="1.0" encoding="UTF-8"?></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"><project name="IM" default="release" basedir="."></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <property name="openfire.path"</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        value="E:/workspace/europa/openfire_src/target/openfire" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <property name="classes.dir" value="classes" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <property name="lib.dir" value="lib" /></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <target name="jar"></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        <jar jarfile="${lib.dir}/grouptreeplugin.jar" basedir="${classes.dir}" ></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            <fileset dir="."></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="*.jar"/></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            </fileset></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        </jar></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        <jar jarfile="${openfire.path}/plugins/groupTreePlugin.jar"></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            <fileset dir="."></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="lib/*.jar" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="plugin.xml" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="logo_small.gif" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="logo_large.gif" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="readme.html" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="changelog.html" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">                <include name="build.xml" /></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">            </fileset></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">        </jar></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    </target></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    <target name="release" depends="jar"></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);">    </target></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(192, 192, 192);"></project></span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />好了(jin)Q至此XMPP+Spark+Openfire 的插件开发三部曲dl束?jin),希望你们对这个开发流E有?jin)系l的?jin)解?br style="margin: 0px; padding: 0px;" /><br /></div> </span> </span> <img src ="http://www.tkk7.com/duanzhimin528/aggbug/325911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/duanzhimin528/" target="_blank">DZM.528</a> 2010-07-12 23:05 <a href="http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开发你自己的XMPP IM l?- Spark 插g开?/title><link>http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325910.html</link><dc:creator>DZM.528</dc:creator><author>DZM.528</author><pubDate>Mon, 12 Jul 2010 14:56:00 GMT</pubDate><guid>http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325910.html</guid><wfw:comment>http://www.tkk7.com/duanzhimin528/comments/325910.html</wfw:comment><comments>http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/duanzhimin528/comments/commentRss/325910.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/duanzhimin528/services/trackbacks/325910.html</trackback:ping><description><![CDATA[ <span id="1111616" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="1661161" class="Apple-style-span" style="color: rgb(101, 101, 101); font-family: Verdana,Arial,Helvetica,sans-serif; font-size: 14px; line-height: 28px; text-align: left;">     此篇文章为《开发你自己的XMPP IM l?- Spark 插g开发》的转发Q原文章地址: </span> </span> <span id="1161616" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="6161111" class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Georgia,serif,宋体; font-size: 12px; line-height: 21px; text-align: center;"> <a style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 160, 233);">http://phoenixtoday.blogbus.com/logs/17878527.html</a> </span> </span> <br /> <span id="1616616" class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> <span id="6111661" class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Georgia,serif,宋体; font-size: 12px; line-height: 19px; text-align: left;"> <div id="1666116" class="postBody" style="margin: 10px 0px; padding: 0px 0px 0px 20px; word-wrap: break-word;">l箋3?8日介l基于XMPP IM开发的那篇BlogQ今天主要ȝ一下如何基于Spark 的插件架构来新增客户端的功能Q这里列丑և一个获取服务器端群l信息的实际例子Q实现后的效果如下图所C:(x)<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><div class="6616611" id="z4te" style="margin: 0px; padding: 1em 0pt; text-align: left;"><img id="vtx:" src="http://docs.google.com/File?id=dcvntvfs_158gr47zmfr_b" alt="" style="margin: 0px; padding: 0px; width: 307px; height: 514px;" /></div><br style="margin: 0px; padding: 0px;" />Spark 是一个基于XMPP 协议Q用Java 实现的IM 客户端。它提供?jin)一些APIQ可以采用插件机制进行扩展,上图中,“部门”部分就是用插件机制扩展出来的新功能。要惛_C的扩展,首先要了(jin)?Spark API的架构,其中最关键的是要了(jin)解它的工厂类Q这些工厂类可以获得Spark 提供的诸如XMPPConnection、ChatContainer {实例,从而你可以实现获取服务器的信息Q与另外的Client 通信{功能。最核心(j)的类是SparkManagerQ这个类是一pd工厂cȝ工厂c(呵呵Q还真拗口)(j)。它的getChatManager()<font id="yu0-" style="margin: 0px; padding: 0px;" color="#000000">、getSessionManager ()、getMainWindow() 、getConnection() {方法分别可以获得聊天管理器、会(x)话管理器、主H口、与服务器的q接{等非常有用的实例。基本上可以说SparkManager 是你与Spark 打交道的衔接口。其实,每一个Manager 都用了(jin)单例模式Q你也可以不通过SparkManager 来获取它们,但笔者徏议你从单一的入口着手,q样有利于代码的开发和l护?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />接下来描qC下插件的开发流E:(x)<br style="margin: 0px; padding: 0px;" />1、创建插仉|文?plugin.xml<br style="margin: 0px; padding: 0px;" />2、实C自己的Plugin cȝ实现Q如果你需要实现自p定格式的XML 发送、接收和处理Q那么你需要在q里注册你的IQProviderQ关于IQProvider 你可以查询Smack APIQ简单的来讲是处理你自定义的IQ 处理器。)(j)<br style="margin: 0px; padding: 0px;" />3、打包你的插ӞSpark 有自q打包机制Q我研究?jin)半天才发现其中的玄机,后面介绍Q?br style="margin: 0px; padding: 0px;" />4、部|你的插Ӟ其实3?两步可以p合在一P当然要利用Ant 啦)(j)<br style="margin: 0px; padding: 0px;" /></font><br style="margin: 0px; padding: 0px;" />好滴Q下面结合一个实际的例子讲述上面的四个步?br style="margin: 0px; padding: 0px;" />1、plugin.xml<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"><plugin></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <name>Enterprise IM Client</name></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <version>1.0</version></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <author>Phoenix</author></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <homePage>http://phoenixtoday.blogbus.com</homePage></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <email>phoenixtoday@gmail.com</email></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <description>Enterprise Client Plug-in</description></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">   <span id="1111111" class="Apple-converted-space"> </span><font id="ueej" style="margin: 0px; padding: 0px;" color="#ff0000"><!-- 关键是这里,q里要定义你的Plugin c?--></font></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <class>com.im.plugin.IMPlugin</class></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <!-- q里定义你用的Spark 最低版?--></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <minSparkVersion>2.5.0</minSparkVersion></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <os>Windows</os></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"></plugin><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(255, 255, 255);">q是一?plugin.xml 文g的内容,插g体系?x)自动调用你在此文g中定义的Plugin c,从而完成你自己扩展的功能。最关键的部分我用红色标识出来了(jin)Q要声明你的插g扩展c,采用完整的命名空间方式(包括包名Q,其余的部分结合我的注释, 大家应该都能理解Q就不做详细的描qC(jin)。要注意的是plugin.xml 文g要放在项目的根目录下Q这是严D定好的?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />2、Plugin cȝ实现<br style="margin: 0px; padding: 0px;" />你的c首先要实现Spark 提供的Plugin 接口Q然后实现它的一些方法。其中最主要的是实现initialize() 发放Q在q里注册你的的IQProvider<span id="6161166" class="Apple-converted-space"> </span><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">ProviderManager providerManager = ProviderManager.getInstance();</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">providerManager.addIQProvider("groups", "com:im:group", //1</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">                new GroupTreeIQProvider());</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">System.out.println("注册GroupTree IQ 提供?);</span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">requestGroupTree();<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(255, 255, 255);">上述的代码,在该类 是我实现的IMPlugin.initialize() Ҏ(gu)中的一段Q大概的含义是,先获取ProviderManagerQ这个貌g能从SparkManager 直接获取Q,然后注册一个GroupTreeIQProviderQ自己创建的Q这是一个IQProvider 的具体实玎ͼ它用于解析像下面q样的一个XML 文gQ?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"><?xml version="1.0" encoding="UTF-8"?></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"><iq type='result' to='domain@server.com' from='phoenixtoday@gmail.com' id='request_1'></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    <groups xmlns='com:im:group'></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">        <group></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <groupId>1</groupId></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <name>西安交通大?lt;/name></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <upGroup>ROOT</upGroup></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <isLeaf>0</isLeaf></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <description>xjtu</description></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <user></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">                 <userGroupId>1</userGroupId></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">                 <userName>phoenix_test</userName></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">                 <role>normal</role></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             </user></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">        </group></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">        <group></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <groupId>2</groupId></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <name>?sh)信学?lt;/name></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <upGroup>1</upGroup></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <isLeaf>1</isLeaf></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">             <description>xjtu info</description></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">        </group></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);">    </groups></span><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(204, 204, 204);"></iq><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(255, 255, 255);">可以看到Q在注册 IQProvider 的时候(代码中标注的1部分Q,需要你提供名称和命名空_(d)我的XML 文g中的iq 下的W一个子节点?lt;groups> 所以我的名U就写“groups”,命名I间对应于groups 节点的xmlns(XML Name Space)所以是“com:im:group”,其实IQProvider 中最关键的方法是parseIQ(XmlPullParser parser) 该方法就是解析XMLQ完成你的功能,q返回一个相应的IQ 实例Q这里可以把IQ 看做一个回馈的Model c)(j)。说到底实现ZXMPP 协议的IM 是解析XML 文gQ而这正是客户端的IQProvider 和服务器端的IQHandlerQ下一文章会(x)涉及(qing)刎ͼ(j)所做的事情?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />3、打包你的插?br style="margin: 0px; padding: 0px;" />现在该有的功能都实现?jin),那么是打包了(jin)。这最好利用Ant 来完成,因ؓ(f)每次你都要打包,要部|Ԍ如果U手动的话,那也太不敏捷?jin),大大影响开发效率?br style="margin: 0px; padding: 0px;" /></span><br style="margin: 0px; padding: 0px;" /><?xml version="1.0" encoding="UTF-8"?><br style="margin: 0px; padding: 0px;" /><project name="IM" default="release" basedir="."><br style="margin: 0px; padding: 0px;" />    <property name="src.dir" value="src" /><br style="margin: 0px; padding: 0px;" />    <property name="dest.dir" value="bin" /><br style="margin: 0px; padding: 0px;" />    <property name="lib.dir" value="lib" /><br style="margin: 0px; padding: 0px;" />    <property name="im.path"<br style="margin: 0px; padding: 0px;" />        value="E:/workspace/europa/spark_new/doc/spark/target/build" /><br style="margin: 0px; padding: 0px;" />    <target name="clean"><br style="margin: 0px; padding: 0px;" />        <!-- <span id="6116611" class="Apple-converted-space"> </span><br style="margin: 0px; padding: 0px;" />            <delete dir="${dest.dir}" /><br style="margin: 0px; padding: 0px;" />           <span id="1116666" class="Apple-converted-space"> </span><br style="margin: 0px; padding: 0px;" />            <delete dir="${lib.dir}" /><br style="margin: 0px; padding: 0px;" />        --><br style="margin: 0px; padding: 0px;" />    </target><br style="margin: 0px; padding: 0px;" />    <target name="init" depends="clean"><br style="margin: 0px; padding: 0px;" />        <!-- <span id="1611611" class="Apple-converted-space"> </span><br style="margin: 0px; padding: 0px;" />            <mkdir dir="${dest.dir}" /><br style="margin: 0px; padding: 0px;" />           <span id="1111161" class="Apple-converted-space"> </span><br style="margin: 0px; padding: 0px;" />            <mkdir dir="${lib.dir}" /><br style="margin: 0px; padding: 0px;" />        --><br style="margin: 0px; padding: 0px;" />    </target><br style="margin: 0px; padding: 0px;" />    <target name="build" depends="init"><br style="margin: 0px; padding: 0px;" />        <!--<br style="margin: 0px; padding: 0px;" />            <javac srcdir="${src.dir}" destdir="${dest.dir}" /><br style="margin: 0px; padding: 0px;" />        --><br style="margin: 0px; padding: 0px;" />    </target><br style="margin: 0px; padding: 0px;" />   <span id="1666116" class="Apple-converted-space"> </span><font id="wc9i" style="margin: 0px; padding: 0px;" color="#ff0000"><!-- 最重要的是q里Q打两次?--></font><br style="margin: 0px; padding: 0px;" />    <target name="jar" depends="build"><br style="margin: 0px; padding: 0px;" />        <jar jarfile="${lib.dir}/eim.jar" basedir="${dest.dir}" /><br style="margin: 0px; padding: 0px;" />        <jar jarfile="${im.path}/plugins/eim.jar"><br style="margin: 0px; padding: 0px;" />            <fileset dir="."><br style="margin: 0px; padding: 0px;" />                <include name="lib/*.jar" /><br style="margin: 0px; padding: 0px;" />            </fileset><br style="margin: 0px; padding: 0px;" />            <fileset dir="."><br style="margin: 0px; padding: 0px;" />                <include name="plugin.xml" /><br style="margin: 0px; padding: 0px;" />            </fileset><br style="margin: 0px; padding: 0px;" />        </jar><br style="margin: 0px; padding: 0px;" />    </target><br style="margin: 0px; padding: 0px;" />    <target name="release" depends="jar"><br style="margin: 0px; padding: 0px;" />        <!-- <span id="1166661" class="Apple-converted-space"> </span><br style="margin: 0px; padding: 0px;" />            <exec executable="cmd.exe"<br style="margin: 0px; padding: 0px;" />            failonerror="true"><br style="margin: 0px; padding: 0px;" />            <arg line="/c e:"/><br style="margin: 0px; padding: 0px;" />            <arg line="/c cd workspace\europa\spark_new\doc\spark\target\build\bin"/><br style="margin: 0px; padding: 0px;" />            <arg line="/c startup.bat"/><br style="margin: 0px; padding: 0px;" />            </exec><br style="margin: 0px; padding: 0px;" />        --><br style="margin: 0px; padding: 0px;" />    </target><br style="margin: 0px; padding: 0px;" /></project><br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; background-color: rgb(255, 255, 255);">q是我的q个目?build.xml 文g中的内容。因为Eclipse 其实帮我自动完成?jin)编译的dQ所以我也就省去?jin)这写编译的步骤Q最重要的是大家要看到“jar?部分QSpark 打包的神U之处也在此,打两ơ包首先把你的项目打包到本项目lib 文g夹下Q比如说你的目目录是MyPlugin 那么Q你将你的cL包到MyPlugin/lib 目录下,然后再次的打包,所有的lib 文g夹下的内Ҏ(gu)包v来,记得q次要包含plugin.xml。也是_(d)最后Spark 插g体系?x)读取你的项目下的lib 文g夹下的内宏V这里我也有个疑问,我本来想每次打包后自动执行bat 文gQ启动插Ӟ看看效果Qؓ(f)啥死都调用不?jin)呢Q那D代码在最后面Q注释掉?jin),谁能帮我解决Q我请他吃饭_(d)<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />4、最后就是发布了(jin)<br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />其实我的发布很简单,是这个打包好的jar 文g拷到Spark 本n的plugins 目录下,每次启动Spark 的时候,它会(x)自动调用自定义的插g的。我q里用Ant W二ơjar 的时候,p动拷贝过M(jin)Q这里用的是l对路径Q所以你不能直接拯q滴呦Q是不是很丑陋呀Q这DA(ch)nt 代码Q?br style="margin: 0px; padding: 0px;" /><br style="margin: 0px; padding: 0px;" />基本上客L(fng)的实现原理就是这L(fng)Q只是有些地斚w要特别注意,q有是应该利用像Ant q样的工具大大简化开发步骤,加快开发效率。还有就是,我徏议你在开发自q插g的时候,多利用MVC 模式Q尤其是在IQProvider 解析后,生成的部分可以实例化ModelQ然后你可以~写自己的Manager q行q些Model 的处理。多写LogQ当然Log4j 貌似不太起作用,那就System.out.println() ?</span></span></span></span></span></span></div> </span> </span> <img src ="http://www.tkk7.com/duanzhimin528/aggbug/325910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/duanzhimin528/" target="_blank">DZM.528</a> 2010-07-12 22:56 <a href="http://www.tkk7.com/duanzhimin528/archive/2010/07/12/325910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开发你自己的XMPP IMhttp://www.tkk7.com/duanzhimin528/archive/2010/07/12/325909.htmlDZM.528DZM.528Mon, 12 Jul 2010 14:54:00 GMThttp://www.tkk7.com/duanzhimin528/archive/2010/07/12/325909.htmlhttp://www.tkk7.com/duanzhimin528/comments/325909.htmlhttp://www.tkk7.com/duanzhimin528/archive/2010/07/12/325909.html#Feedback0http://www.tkk7.com/duanzhimin528/comments/commentRss/325909.htmlhttp://www.tkk7.com/duanzhimin528/services/trackbacks/325909.html

此篇文章为《开发你自己的XMPP IM》的转发Q原文章地址:http://phoenixtoday.blogbus.com/logs/17246727.html

最q没在Blog 上露脸,为撒c?应师兄的hQ帮他研I一个XMPP IM 软g的开发。反正最q也没什么大事,每天都想写写代码l练手,帮忙呗。研I了(jin)一通觉得还挺有,自己q几天查国内外的资料Q发现国内关于这斚w间的软g 资料太少?jin),想在这里写几篇关于此类IM 软g开发的文章。不q别看东西小Q涉?qing)的模块可不?/p>

所以我基本上分Z文章来介绍此类软g的开发:(x)

W一是关于XMPP 协议是啥QIM 是啥以及(qing)一个比较有名的开源实玎ͼ该开源实现包括三个部分(Spark、Smack和OpenfireQ;

W二讲如何开发基于Spark 的客L(fng)IM 插g部分Q?/p>

W三讲如何开发基于Openfire 服务器端的插仉分?/p>

好了(jin)Q进入正题吧?/p>

 

什么是XMPPQ?/strong>
Extensible Messaging and Presence ProtocolQ简单的来讲Q它?yu)是一个发送接收处理消息的协议Q但是这个协议发送的消息Q既不是二进制的东东也不是字W串Q而是XML。正是因Z??jin)XML作ؓ(f)消息传递的中介QExtensible 才谈的上Q不是么Q嘿ѝ再详尽的东西,我也׃多介l了(jin)Q大家可以去癑ֺ癄里查看下Q链接在q里

什么是IM Q?/span>

Instant MessengerQ及(qing)旉信软gQ就是大家用的QQ、MSN Messenger和Gtalk{等。其中Gtalk 是ZXMPP 协议的一个实玎ͼ其他的则不是。当前IM 几乎作ؓ(f)每个上网者必然用的工具Q在国外的大型企业中有一些企业的IM应用Q但是其商业价D没完全发挥出来。设x然XMPP 协议是一个公开的协议,那么每个企业都可以利用它来开发适合本n企业工作Q提高自w生产效率的IMQ甚臻I你还可以在网l游戏中集成q种通信软gQ不但让?可以Ҏ(gu)戏边聊天Q也可以开发出适合游戏本n的IM 应用Q比如说一些游戏关键场景提醒功能,团队语音交流{等都可以基于IM来实现。说?jin)这么多Q就是一个意思,其商业h(hun)Dq比你想的高Q?/p>

Spark Smack ?Openfire

开源界L有许多有的东东Q这三个合v来就是一个完整的XMPP IM 实现。包括服务器端——OpenfireQ客L(fng)——SparkQXMPP 传输协议的实现——SmackQ记住,XMPP是一个协议,协议是需要实现的QSmack起到的就是这L(fng)一个作用)(j)。三者都是基于Java 语言的实玎ͼ因此对于熟?zhn)Java 的开发者来说不是很?br style="margin: 0px; padding: 0px;" />


Spark 提供?jin)客L(fng)一个基本的实现Qƈ提出?jin)一个很好的插g架构Q这对于开发者来说不能不说是一个福韟뀂我强烈Z插g方式来实C新增加的功能Q而不是去 改它的源代码Q这h利于你项目架构,把原始项目的影响降到最低,文章以后的部分也是基于这U插件体p进行开发的

Openfire 是基于XMPP 协议的IM 的服务器端的一个实玎ͼ虽然当两个用戯接后Q可以通过点对点的方式来发送消息,但是用户q是需要连接到服务器来获取一些连接信息和通信信息的,所以服?器端是必要实现的。Openfire 也提供了(jin)一些基本功能,但真的很基本的!?jin)幸的是Q它也提供插件的扩展Q像Spark 一P我同样强烈徏议用插件扩展的方式来增加新的功能,而不是修改h家的源代码?br style="margin: 0px; padding: 0px;" />
Smack 是一个XMPP 协议的Java 实现Q提供一套可扩展的APIQ不q有些时候,你还是不得不使用自己定制发送的XML 文g内容的方式来实现自己的功?br style="margin: 0px; padding: 0px;" />
下图展示?jin)三者之间的关系Q?br style="margin: 0px; padding: 0px;" />
点击查看原始寸
从图上可以了(jin)解到Qclient 端和server端都可以通过插g的方式来q行扩展Qsmack是二者传递数据的媒介?br style="margin: 0px; padding: 0px;" />
嗯,今天写到这里吧Q画图花?jin)好久的旉呀。下一介l一下如何开发基于Spark 的插件程序,qȝ一些我自己的一些心(j)得,举一个实际的例子Q需要涉?qing)到的一些XML 文g的解析与生成Q还有Spark、Smack 自己提供的API Q还有ant 的一些基本知?


DZM.528 2010-07-12 22:54 发表评论
]]>
UDP打洞Q穿透NAThttp://www.tkk7.com/duanzhimin528/archive/2010/07/12/325882.htmlDZM.528DZM.528Mon, 12 Jul 2010 08:53:00 GMThttp://www.tkk7.com/duanzhimin528/archive/2010/07/12/325882.htmlhttp://www.tkk7.com/duanzhimin528/comments/325882.htmlhttp://www.tkk7.com/duanzhimin528/archive/2010/07/12/325882.html#Feedback0http://www.tkk7.com/duanzhimin528/comments/commentRss/325882.htmlhttp://www.tkk7.com/duanzhimin528/services/trackbacks/325882.html

UDP"打洞"原理

1.       NAT分类

Ҏ(gu)Stun协议(RFC3489),NAT大致分ؓ(f)下面四类

1)      Full Cone

q种NAT内部的机器Aq接q外|机器C?NAT?x)打开一个端?然后外网的Q何发到这个打开的端口的UDP数据报都可以到达A.不管是不是C发过来的.

例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88

A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)

M发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

2)      Restricted Cone

q种NAT内部的机器Aq接q外|的机器C?NAT打开一个端?然后C可以用Q何端口和A通信.其他的外|机器不?

例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88

A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)

M从C发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

 

3)      Port Restricted Cone

q种NAT内部的机器Aq接q外|的机器C?NAT打开一个端?然后C可以用原来的端口和A通信.其他的外|机器不?

例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88

A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)

C(202.88.88.88:2000)发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

 

以上三种NAT通称Cone NAT.我们只能用这UNATq行UDP打洞.

4)      Symmetic

对于q种NAT.q接不同的外部目?原来NAT打开的端口会(x)变化.而Cone NAT不会(x).虽然可以用端口猜?但是成功的概率很?因此攑ּq种NAT的UDP打洞.

2.       UDP hole punching

对于Cone NAT.要采用UDP打洞.需要一个公|机器C来充当”介lh?内网的A,B先分别和C通信.打开各自的NAT端口.Cq个时候知道A,B的公|?IP:Port. 现在A和B想直接连?比如AlB?除非B是Full Cone.否则不能通信.反之亦然.但是我们可以q样.

A要连接B.AlB发一个UDP?同时.A让那个介lhlB发一个命?让B同时lA发一个UDP?q样双方的NAT都会(x)记录Ҏ(gu)的IP,然后׃(x)允许互相通信.

3.       同一个NAT后面的情?br />
如果A,B在同一个NAT后面.如果用上面的技术来q行互连.那么如果NAT支持loopback(是本地到本地的转换),A,B可以q接,但是比较费带宽和NAT.有一U办法是,A,B和介lh通信的时?同时把自qlocal IP也告诉服务器.A,B通信的时?同时发local ip和公|IP.谁先到就用哪个IP.但是local ip有可能不知道发C么地方去?比如A,B在不同的NAT后面但是他们各自的local ipD一?AlB的local IP发的UDP可能发l自己内部网里面的某某某?

q有一个办法是服务器来判断A,B是否在一个NAT后面.(|络拓朴不同?x)不会(x)有问?)

--------------------------------------------------------------------------------------------------------------------------

From: http://hi.baidu.com/ligh0721/blog/item/0cbbc9384106252b96ddd872.html

前天~程做了(jin)一下UDP打洞的实验,今天特写?jin)一文章ȝ一下?br />
我们知道|络上两个主行通信Q如果其中一C机拥有公|IP那么Q那么进行会(x)话是比较单的Q但是如果两C机是位于不同内网之中的,那么应该如何q行通信呢。一U想法是再找一台公|的服务器,用来转发信息Q但是这有一个问题,是?x)给服务器带来压力,因此我们来谈谈一U用于不同内|中的主Z盔R信的一个解x案——NAT打洞?br />
原理q是比较单的Q我们先?jin)解一下什么是“NAT的洞”。当处于内网中的一C?ClientA/192.168.1.128)向一个公|的服务?(Server)发送数据时Q这时NAT(NAT1)会(x)打开一个(f)时性的端口用于与公|的服务器进行通信Qƈ且会(x)把那个内|主机发送出的IP数据报的头部中源IP地址改ؓ(f)NAT的公|IP(218.7.32.28)Q将TCP或UDP数据报中源端?2347)改ؓ(f)那个临时端口(26756)q样实C(jin)??92.168.1.128:2347”到?18.7.32.28:26756”的源地址源端口的转换。这个数据包到达公网服务器后Q服务器可以根据这个包的头部信息进行回复。当服务器的数据包到达NAT后,NAT在将q个数据发送到内网L192.168.1.128?347端口。那么这?NAT上的26756端口我们q作“洞”。如果这个NAT不是Full Cone NAT的话(其实大多数的NAT实不是q种cd?Q那么我们说q个“洞”是有方向性的。一个洞应该?x)指向一?也可以是多个)公网L的IP地址。比如上面说的例子,在NAT1上打的洞是指向Server的IP地址。来自其他公|主机发向这个洞(也就?18.7.32.28:26756)的数据包?x)被非Full Conecd的NAT所丢弃。所以如果有另一台处于另一内网的主?ClientB/192.168.0.5)?18.7.32.28:26756直接发送数据的话,同样也会(x)被NAT1丢弃?br />
那么如何建立ClientA和ClientB的直接会(x)话呢Q?br />|络环境描述:
内网1NAT:NAT1/218.7.32.28
内网1中一C?ClientA/192.168.1.128
内网2NAT:NAT2/218.7.31.221
内网2中一C?ClientB/192.168.0.5
公网服务?Server

首先让ClientA和ClientBd到服务器Server(假如两台L都采?347端口)Q此时NAT1和NAT2?x)分别?f)ClientA?ClientB打开一个指向Server的洞(NAT1?18.7.32.28:26756和NAT2?18.7.31.221:27550)。服务器应改记录q两个客L(fng)的信?关键是那两个z的信息)。当ClientA与ClientB要徏立会(x)话时QClientA首先?347端口向NAT2的洞发送一个数据包Q当然这个数据包?x)被NAT2所丢弃Q但是由于这是从NAT1内部向外部发送数据,所以NAT1为ClientA打开?jin)一个指向NAT2 的洞。而且q个新洞与原来NAT1上指向Server的旧z的是同一个洞(因ؓ(f)是同一个端?6756)Q所以这里可以说q个z具有了(jin)两个方向Q同时指?Server和NAT2。这时ClientA应该通知ServerQ告诉ClientBQ现在可以向NAT1的那个洞 (218.7.32.28:26756)发送数据包?jin)。当ClientB向NAT1的那个洞发送数据以后,NAT2也ؓ(f)ClientB打了(jin)一个指?NAT1的洞Q这是可以说ClientA与ClientB的会(x)话就建立完成?jin),他们可以不依赖Serverq行通信?jin)。如果以后ClientA?ClientBq需要徏立其他会(x)?Q那么这个牵U的“媒人”可以不是ServerQ而可以是ClientA或ClientB?jin)?br />
UDP打洞可以实现不同内网内的Lq行通信Q而且实施性比较高Q一般用于P2P通信。这也就是ؓ(f)什么常?x)看见腾讯QQ在开始传输文件时?x)显C“UDPq接已经建立”了(jin)


DZM.528 2010-07-12 16:53 发表评论
]]>
openfire开发文?/title><link>http://www.tkk7.com/duanzhimin528/archive/2010/07/02/325097.html</link><dc:creator>DZM.528</dc:creator><author>DZM.528</author><pubDate>Fri, 02 Jul 2010 09:58:00 GMT</pubDate><guid>http://www.tkk7.com/duanzhimin528/archive/2010/07/02/325097.html</guid><wfw:comment>http://www.tkk7.com/duanzhimin528/comments/325097.html</wfw:comment><comments>http://www.tkk7.com/duanzhimin528/archive/2010/07/02/325097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/duanzhimin528/comments/commentRss/325097.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/duanzhimin528/services/trackbacks/325097.html</trackback:ping><description><![CDATA[     摘要: openfire开发文? 版本QOpenfire3.5. 摘自QIMx通讯研究     ?   ? 一、初始工?#183;············...  <a href='http://www.tkk7.com/duanzhimin528/archive/2010/07/02/325097.html'>阅读全文</a><img src ="http://www.tkk7.com/duanzhimin528/aggbug/325097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/duanzhimin528/" target="_blank">DZM.528</a> 2010-07-02 17:58 <a href="http://www.tkk7.com/duanzhimin528/archive/2010/07/02/325097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://0755host.com" target="_blank">һӰԺ</a>| <a href="http://laochedao.com" target="_blank">99þѹػ</a>| <a href="http://xp189.com" target="_blank">ɫƵ߹ۿ</a>| <a href="http://1000hu.com" target="_blank">޹˾þۺһ77 </a>| <a href="http://hwjyrck.com" target="_blank">ƷƵ</a>| <a href="http://zbhongtai.com" target="_blank">þҹӰԺѹۿ</a>| <a href="http://wwwy66y6.com" target="_blank">պëƬһ</a>| <a href="http://tao-zhe.com" target="_blank">޾ƷþþþAPP</a>| <a href="http://zjj100.com" target="_blank">޵һҳ߲</a>| <a href="http://baicaijia666.com" target="_blank">޾ƷŮþþ</a>| <a href="http://87fulitv.com" target="_blank">޳777777Ʒ</a>| <a href="http://jundaflex.com" target="_blank">ѿοһ</a>| <a href="http://www-8908.com" target="_blank">߹ۿwwwѿ</a>| <a href="http://dw168cn.com" target="_blank">ƷѸ߹ۿ</a>| <a href="http://www988555.com" target="_blank">avѸ߳ˮ</a>| <a href="http://hqwgg.com" target="_blank">ƷŮһëƬ</a>| <a href="http://4eeyy.com" target="_blank">ɫ͵͵</a>| <a href="http://znboxcdn107.com" target="_blank">ۺŷۺվ</a>| <a href="http://xinyuanmy.com" target="_blank">av뾫Ʒ4</a>| <a href="http://01shanzhai.com" target="_blank">޹Ʒþþþվ</a>| <a href="http://gzweida88.com" target="_blank">һֻ߹ۿ</a>| <a href="http://mosason.com" target="_blank">þþþùAV鶹</a>| <a href="http://wwwabxx.com" target="_blank">޳AƬ߹ۿ</a>| <a href="http://3333seav.com" target="_blank">?V˾Ʒպ</a>| <a href="http://ghdc5.com" target="_blank">պƵ</a>| <a href="http://kaixininvestment.com" target="_blank">ձaaaaaƬƵ</a>| <a href="http://g8zb.com" target="_blank">99reþþƷƷ</a>| <a href="http://tv695.com" target="_blank">Ƭ߷ѹۿ </a>| <a href="http://001mc.com" target="_blank">ƷAVһ </a>| <a href="http://mtripmall.com" target="_blank">þþþѿaԿ</a>| <a href="http://yy7699.com" target="_blank">պŷƵ</a>| <a href="http://my77789.com" target="_blank">ɫƵѿ</a>| <a href="http://472849.com" target="_blank">þþƷվ</a>| <a href="http://szzrjk.com" target="_blank">þþƷר</a>| <a href="http://vod8090.com" target="_blank">պAVһ</a>| <a href="http://htsp777.com" target="_blank">Ʒҹѹۿվ</a>| <a href="http://shguojing.com" target="_blank">þþžѸƵ</a>| <a href="http://newbuybay.com" target="_blank">һƵ</a>| <a href="http://qestest.com" target="_blank">ҹѿƬڵ</a>| <a href="http://5g5t.com" target="_blank">Ƶ߹ۿ</a>| <a href="http://zqsplc.com" target="_blank">ѹۿɫƵվ(ɫ) </a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>