openfire开源IM服务器知识分享+社交app实战

1、      概述

  1. Openfire最主要的功能是实现XMPP服务器,简单来讲,openfire为咱们提供一个固定的地址,咱们只须要向openfire服务器发送标准的XMPP信息(即XML文件流),那么openfire服务器应当给予咱们回应,这里的openfire服务器也能够看作一个容器,咱们在聊天时,须要在这个服务器上注册一个会话,在会话存在的时间,咱们能够实现即时聊天的一些经常使用功能,好比创建本身的组,添加好友,聊天,以及传送文件等等,同时,openfire服务器也须要实现本身的管理界面,这样openfire服务器也扮演一个web容器的角色
  2. Openfire是开源的实时协做服务器(RTC),它是基于公开协议XMPP(也成为Jabber)消息的。
  3. 使用它轻易的构建高效率的即时通讯服务器。
  4. Openfire的核心功能能够归纳为:链接管理、消息解析、消息路由、消息发送。
  5. Openfire具备跨平台的能力,Openfire与客户端采用的是C/S架构,一个服务器要负责为链接在其上的客户端提供服务。
  6. Openfire客户端有spark, pidgin, Miranda IM, iChat等,用户若是本身开发客户端,能够采用遵循GPL的开源Client端API--Smack。
  7. Openfire服务器端支持插件开发,若是开发者须要添加新的服务,能够开发出本身的插件后,安装至服务器,就能够提供服务,如查找联系人服务就是以插件的形式提供的。

2、      体系架构



 

3、      功能模块



 

  1. Pubsub:Publish/Subscribe,这使得xmpp实体可以在pubsub服务上建立nodes(topics),而且发布信息。一个事件通知将广播到全部订阅了这个节点的实体上。
  2. Pep:(Personal Eventing Protocol)使用XMPP publish-subscribe协议广播状态改变事件、及时消息和出席账户到其余用户。
  3. Stun:为p2p会话提供地址发现服务,如:媒体传输和UDP包的收发。
  4. Router:内部的路由,把相应的包路由给相应的处理器。
  5. Muc:(Multi-User Chat)用户能够交换文本信息在room或者channel上下文中,版主或者管理员有权踢除用户和禁止用户。
  6. 全部Module都须要实现Module接口,该接口中定义了模块生命周期中须要调用的方法



 

 

 

4、      数据模型

  1. 数据库表设计:详见:

http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/database-guide.html#ofGroup#ofGrouphtml

  1. Openfire的数据库处理采用直接调用JDBC 的方式。核心类为org.jivesoftware.database.DbConnectionManager。数据库的处理与业务处理耦合,没有划分出专门的业务逻辑层。
  2. 3.      ConnectionProvider此类为数据库提供者接口,如需链接mysql、hsqldb等数据库,需首先实现些接口,一般直接调用XXManager中的实例方法,XXManager中又调用的是对应的接口XXProvider的方法,实际操做在该接口的实现类中实现。实现类是动态绑定的(默认的实现类一般命名规则为DefaultXXProvider),在运行时根据ofproperty表中对应配置项值选
  3. org.jivesoftware.database.DbConnectionManager,链接管理类
  4. org.jivesoftware.util.JiveGlobals,一般用于操做ofproperty表中记录
  5. 1.         XMPP协议

5、      通讯机制

1)      XMPP(Extensible Messageing and Presence Protocol:可扩展消息处理现场协议)是目前主流的四种IM(IM:instant messaging,即时消息)协议之一,其余三种分别为:即时信息和空间协议(IMPP)、空间和即时信息协议(PRIM)、针对即时通信和空间平衡扩充的进程开始协议SIP(SIMPLE)。node

2)      XMPP的前身是Jabber,一个开源形式组织产生的网络即时通讯协议。mysql

3)      核心的XML流传输协议 ,基于XML FreeEIM流传输的即时通信扩展应用,XMPP的扩展协议Jingle使得其支持语音和视频web

4)      XMPP协议在PC和Android分别有对应的协议实现smack和asmack,不用咱们写XML协议解析sql

5)      XMPP的基本网络结构:Client、Server、Gateway,通讯可以在这三者的任意两个之间双向发生。服务器同时承担了客户端信息记录,链接管理和信息的路由功能。网关承担着与异构即时通讯系统的互联互通,异构系统能够包括SMS(短信),MSN,ICQ等。数据库

6)      客户端利用xmpp(基于TCP/IP)访问server,传输的是XML,工做原理是:apache

a)    节点链接到服务器;编程

b)    服务器利用本地目录系统中的证书对其认证;缓存

c)    节点指定目标地址,让服务器告知目标状态;安全

d)    服务器查找、链接并进行相互认证;

e)    节点之间进行交互

7)      XMPP协议的传输是经过XML文件来传输的,而且不是相似于QQ的点对点通信,而是客户端到服务器再到客户端的方式来实现,以上过程的一个简单的XMPP通信流程能够以下:

a)    首先,由客户端链接到服务器,客户端经过IO流发送一段XML文件,在文件中包含了自身的用户名和密码

b)    服务器端接收到客户端的XML文件,从中获取用户名和密码进行验证,若是验证成功,服务器会发送一个XML文件给客户端代表已经登陆成功

c)    登录成功后,客户端能够经过发送一个获取好友名单的XML文件,服务器会将当前用户的好友以XML文件传到客户端

d)    客户端选择一个好友,向其发送信息(实际上是向服务器发送,服务器收到后会转发给对应的好友),好友收到

8)      XMPP地址模式:JID=[ node”@” ] domain [ “/” resource ](如:cyber@cyberobject.com/res),domain:服务器域名,node: 用户名,resource:属于用户的位置或设备。一个用户能够同时以多种资源与同一个XMPP服务器链接

9)      XMPP xml消息格式定义:

<stram>

   <presence>  //此元素肯定用户的状态

      <status/>

   </prensence>

   <message>  //用于两个用户之间发送信息

        <body/>

    </message>

    <iq> //信息/请求,是一个请求-响应机制,管理xmpp服务器上两个用户的转换,容许他们经过相应的xml格式的查询和响应

                     <bind/>

    </iq>

</stream>

10)    XMPP的安全机制:XMPP采用SASL做为身份认证协议,XMPP采用TLS的“START-TLS”扩展来为通讯双方提供加密性和数据完整性服务

11)    XMPP体系架构:XMPP server:其内核是一个XMPP路由器,完成基本组件间的数据包交换和路由。功能:1.会话管理器:负责客户端会话认证,在线状态,用户联系表等;2.数据存储器(XDB):链接数据库系统,保持用户信息、通讯日志等;3.链接器管理器:管理与客户端之间的链接;4.服务器链接器:管理xmpp服务器之间的链接;5.传输器:创建xmpp服务器与非xmpp服务器通讯

12)     

  1. 2.      Apache MINA框架

1)      XMPP协议是基于TCP/IP协议进行传输的,在openfire中,应用了apache的mina框架做为NIO框架,简单的来讲,openfire服务器用mina框架创建一个简单的服务器,能够接收和发送基本的IO流,而后在此基础上把接收到的IO流解析为XML文件,而后在根据XMPP协议对XML文件进行操做

2)      是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序。它提供了一个经过Java NIO在不一样的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API,对通讯功能进行扩展

3)      为不一样的传输类型(TCP/UDP)提供了统一的API

4)      过滤器做为一个扩展特性,相似Servlet过滤器

5)      低级(字节缓存)和高级(用户定义的消息对象和编码)的API

6)      高度定制化线程模型(单线程/线程池)

7)      超载保护和传输流量控制

8)      Openfire的ConnectionHandler类继承了MINA的IoHandlerAdaper,他主要负责链接的建立、销毁,以及接收到XML数据包的投递。ConnectionHandler有三个子类,其中ClientConnectionHandler负责客户端与服务器端的链接,ComponentConnectionHandler负责组件与服务器端的链接,类图以下:



 

  1. 3.      Openfiresocket网络链接

1)      服务器和服务器之间的链接(监听在端口5269)

2)      外部组件和服务器之间的链接(监听在端口5275)

3)      多元(complex)链接(监听在端口5269)

4)      客户端和服务器的链接(监听在端口5222)

5)      和客户端经过TLS/SSL3.0和服务器的链接。(监听在端口5223)

6)      链接都是经过ConnectionManager接口实现管理的,程序中对ConnectionManager接口的实现类是ConnectionManagerImpl,它是做为一个模块(Module)类加载到服务器中的

6、      开发配置

  1. 环境配置:

1)      http://blog.csdn.net/kingsonl/article/details/7730225

2)      http://blog.csdn.net/nomousewch/article/details/6534555

  1. 2.         Openfire源码目录结构

1)      build目录:build目录下收录的是生成安装文件(例如:rpm)所要的一些文件,例如JRE等

2)      resources目录:resources目录下收录的是一些为实现国际化(i18n)和本地化的一些编码文件(例如:英文,中文,法文,德文等)

3)      documentation目录:documentation目录下收录的是一些关于Openfire安装和配置的信息,但最终要的是这里有Openfire开发的Javadoc

4)      src目录:顾名思义这个src文件夹就是咱们想要的Openfire源代码了,这下面又有许多文件夹,咱们只要Java文件夹就好,这里面实现的Openfire的核心功能,经过它就能够调试Openfire了

  1. 3.         命名规则

Openfire中常见的类名后缀命名包括Starter、Plugin、Listener、Dispatcher、Handler、Manager、Provider,一般状况下,这些命名类包括以下意义:

1)      XXStarter系统启动类

2)      XXListener业务的最终处理类

3)      XXDispatcher调度类,其中有不少关键方法,如addListener(),以组合的方式,为类内定义的静态Set<XXListener>实例添加XXListener对象。以便调用dispatchEvent(String property, EventType eventType, Map<String, Object> params)方法遍历处理Set集中的XXListener对象(经过调用XXListener对象的各实际方法完成实际业务)

4)      XXPlugin实现Plugin接口的插件类,需实现initializePlugin(PluginManager manager, File pluginDirectory)方法和destroyPlugin()方法。在其初始化方法中调用Dispatcher实现类的addListener()方法如PropertyEventDispatcher.addListener(this)

5)      XXProvider实现面向接口编程方式的接口类,经过反射机制建立具体实现类的对象,反射类名配置在ofproperty表对应的记录propvalue属性中。若没有相关配置,则调用默认实现类,默认实现类类名命名规则为DefaultXXProvider

6)      XXHandler实际处理类,以ConnectionHandler为例,在org.jivesoftware.openfire.spi. ConnectionManagerImpl类的startClientSSLListeners(String localIPAddress)方法中,有这样一段代码:sslSocketAcceptor.bind(new InetSocketAddress(bindInterface, port), new ClientConnectionHandler(serverName));其中bind方法的第二个参数是新建立的一个ClientConnectionHandler的实例,而它就是ConnectionHandler的一个子类

  1. 4.         系统配置

Openfire的系统配置项采用文件结合数据库表的方式配置,也有部分默认配置项经过Java硬编码方式配置(如org.jivesoftware.openfire. ConnectionManager接口类中定义的DEFAULT_PORT、DEFAULT_SSL_PORT、DEFAULT_COMPONENT_PORT等),Openfire中比较重要的配置位置包括:

1)      src/conf目录下的openfire.xml配置文件。该配置文件为系统核心配置文件。在第一次启动Openfire并经过管理控制台完成安装配置后会往该配置文件中填入相应的配置信息

2)      plugin.xml配置文件。该配置文件为各插件包下的核心配置文件,由它肯定插件核心处理类和相应页面插件的展示等。配置项及含义详见官方插件开发说明部分

3)      web.xml和web-custom.xml配置文件。用于配置servlet和用户自定义servlet(插件页面用,放在插件对应目录下)

4)      ofproperty中的各条记录,该表中包括两个字段name和propvalue,分别表明配置项名和配置项值

  1. 5.         Openfire启动过程

系统启动时调用org.jivesoftware.openfire.starter.ServerStarter类中的start()方法,加载org.jivesoftware.openfire.XMPPServer类,并调用这个类的start(),Start()方法中首先调用verifyDataSource()方法验证并确保数据库能够访问,而后会调用               loadModules();initModules();startModules();方法来对Module接口的实现类的各子类进行操做,依次完成模块的加载、初始化和启动操做。loadModules()方法中会调用loadModule(String module)方法经过反射加载各模块类,参数字符串module为对应的模块核心处理类的类名

  1. 6.         消息处理流程

在Openfire服务器对XMPP的实现中,消息被封装为Packet对象,所以Openfire服务器的核心代码是对客户端Packet对象的监听和处理流程

Packet处理流程:



 

1)      首先,Openfire服务器须要启动一个基于TCP/IP的监听服务,用以接收客户端传过来的XML流文件。这个过程在XMPPServer类的start()方法中进行,这个监听服务是以loadModule(ConnectionManagerImpl.class.getName())来加载,调用ConnectionManagerImpl类的createClientListeners()方法

2)      其中的socketAcceptor是在buildSocektAcceptor()方法中定义的,它是做为一个服务端的接收器,是mina框架为咱们封装好的一个socketserver,在上面这个方法中,咱们为socketAcceptor添加了一个过滤器,XMPPCodeFactory,这个类将过滤xmpp相关请求,加以处理,咱们再看同一个类的另一个方法startClientListener()

3)      其中的socketAcceptor.bind()方法启动了监听服务器,来监听全部发送到服务器5222端口的数据,并用ClientConnetionHandler类来处理,ClinetConnectionHandler继承于ConnectionHandler类,后者实现了mina的IoHandlerAdaptor接口,其中的messageReceived()方法是关键

4)      能够看到收到的信息交由StanzaHandler的process方法中进行XML解析并封装为packet对象,而后再进行下一步的处理,至此,从客户端到服务器端的packet传递结束,以下图所示:



 

 

 

  1. 7.         Spark 登陆过程-安全认证

1)      Spark登陆过程消息截图:



 

2)      Spark登陆过程当中的XMPP消息含义:



 

 

  1. 8.         WEB服务器

1)      Openfire采用内置的jetty做web服务器,在启动AdminConsolePlugin插件时调用startup()方法启动jetty服务器,9090为其明文端口,9091为其加密端口

2)      Openfire没有采用如今很流行的技术架构(SSH),只使用JSP+JavaBean,可是它有本身的系统设计,就连日志都是本身作的,没有使用咱们熟悉的log4j

3)      现有的Openfire管理控制台可采用插件方式进行扩展,页面采用Jsp方式实现,页面直接调用业务处理逻辑类(一般命名为XXManager)的实例方法,一般经过request对象封装的方式传递页面展示断定变量,常出现本页跳转。每一个插件可定义本身的Servlet类和web.xml及web-custom.xml配置文件

4)      页面展示采用装饰框架方式,decorator页面有两个,即src/web/decorators目录下的两个页面main.jsp和setup.jsp。采用自定义的admin标签实现,标签库admin.tld放置在src/web/WEB-INF目录下,标签解析类放置在org.jivesoftware.admin包下,有SidebarTag、SubnavTag、SubSidebarTag、TabsTag四个解析类。在调用loadPlugin()方法进行插件加载时,解析插件的plugin.xml配置文件,将获取的相关信息封装在AdminConsole类的generatedModel对象中,后期经过插件解析类提取该对象中的数据并配合sitemesh装饰器进行页面展示。

社交app实战以下图:

 

沟通联系qq2729404527  微信:code588  

相关文章
相关标签/搜索