`
lingqi1818
  • 浏览: 253354 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

openfire简介

 
阅读更多
详细文章请下载附件。。。。。。

Openfire简介




陈科 lingqi1818@gmail.com
2011-9-23



目录
一.Openfire简介 3
二.Xmpp协议介绍 3
三.开发环境搭建 5
四.Openfire架构介绍 8
五.Openfire插件开发 10
六.Openfire开发心得 15



一. Openfire简介


Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议。
Openfire并非简单实现xmpp协议(rfc3920),而是在这之上实现了xmpp-im(rfc-3921),该协议对实施协作的各种场景有较全面的考虑和解决方案,例如用户状态切换,消息订阅和通知等等。

二. Xmpp协议介绍


这里简单介绍一下rfc3920和rfc3921分别解决什么样的问题。
可扩展消息和出席信息协议(XMPP)[rfc3921],这个协议采用XML流实现在任意两个网络终端接近实时的交换结构化信息。XMPP提供一个通用的可扩展的框架来交换XML数据,它主要用来建立即时消息和出席信息应用以实现 RFC 2779 的需求。
如果需要了解具体的xmpp大家可以直接阅读rfc3920.这里直接拿一个标准的xmpp通讯流程来举例说明:
C: <?xml version='1.0'?>
      <stream:stream
          to='example.com'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>
   S: <?xml version='1.0'?>
      <stream:stream
          from='example.com'
          id='someid'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>
   …  encryption, authentication, and resource binding ...
   C:   <message from='juliet@example.com'
                 to='romeo@example.net'
                 xml:lang='en'>
   C:     <body>Art thou not Romeo, and a Montague?</body>
   C:   </message>
   S:   <message from='romeo@example.net'
                 to='juliet@example.com'
                 xml:lang='en'>
   S:     <body>Neither, fair saint, if either thee dislike.</body>
   S:   </message>
C: </stream:stream>
   S: </stream:stream>
这里的C代表客户端,S代表服务器。
这里我们简单翻译一下这个通信过程。
1. 客户端发起一个流请求。
2. 服务端响应客户端,并且在响应中提供了流的特性,例如验证机制,加密机制,压缩机制等等。
3. 略去鉴权过程。
4. 客户端发送消息给此域中的某用户。
5. 服务端收到某用户消息之后响应客户端。
6. 客户端要求结束流。
7. 服务端响应客户端并结束流。
这里还要介绍个概念,JID。Xmpp中的通信过程和消息传递机制都是通过JID来作为标识的。比如这次会话中的from和to.具体的格式大家可以查阅rfc3920这里就不做介绍了。


即时消息和出席信息功能的扩展,定义在 XMPP-IM 协议[rfc3921],该协议主要在xmpp基础上扩展了IM的功能,并且具体介绍了语法和消息类型。本协议从用户角度出发主要需要实现以下几个功能。
• 和其他用户交换消息
• 和其他用户交换出席信息
• 管理和其他用户之间的订阅和被订阅
• 管理联系人列表中的条目(在 XMPP 中这被称为 "roster")
• 屏蔽和特定的其他用户之间的通信(出或入)
以上功能主要是对message, IQ, presence进行了功能扩展。
例如出席信息(presence)
出席信息节的'type'属性是可选的(OPTIONAL). 一个不拥有任何'type'属性的出席信息节用来通知服务器发送者已经在线并且可以进行通信了, 'type' 属性表示缺乏可用性, 请求管理对其他实体的出席信息的订阅, 请求其他实体的当前出席信息, 或发生了和上次发出的出席信息节有关的错误. 如果包含了它, 'type'属性必须(MUST)拥有以下值之一:
• unavailable -- 通知实体将不可通信.
• subscribe -- 发送者希望订阅接收者的出席信息.
• subscribed -- 发送者允许接收者接收他们的出席信息.
• unsubscribe -- 发送者取消订阅另一个实体的出席信息.
• unsubscribed -- 订阅者的请求被拒绝或以前的订阅被取消.
• probe -- 对一个实体当前的出席信息的请求; 只应(SHOULD)由服务器代替一个用户生成.
• error -- 处理或递送之前发送的出席信息节的时候发生了错误.
关于出席信息语义学的详细信息和基于XMPP的即时消息和出席信息应用程序的订阅模式,参考 rfc3921交换出席信息Exchanging Presence Information(第五章) 和 管理订阅Managing Subscriptions(第六章).

关于其他细节有兴趣可以阅读rfc3921.


三. 开发环境搭建


Openfire的开发环境搭建相对简单。
1.首先从官网下载源码包。
wget http://www.igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire_src_3_7_0.tar.gz
2.安装java开发环境以及eclipse.
3.在eclipse中新建java project.

4.不要直接finish,选择next.

5.选择Link additional source to project。然后把源代码文件夹中的openfire_src_3_7_0\openfire_src\src\java目录导入。

6.通过add external jars导入openfire_src_3_7_0\openfire_src\build\lib下的所有jar包。
7.在openfire_src_3_7_0\openfire_src\build目录下运行ant命令即可编译代码。编译出的可执行目录在openfire_src_3_7_0\openfire_src\target\openfire\bin下面。
假如需要以debug方式启动,则执行openfire.bat –debug.默认是suspend=n。你可以修改脚本为suspend=y这样只有当你远程debug连上之后应用代码才开始跑。


四. Openfire架构介绍


首先看一下大致的架构图


这边有几个概念阐述下。
1.xmppServer:openfire服务器的单例类。承担了服务器各个模块的启动和关闭的作用。
2.module:openfire把各个独立功能通过模块的形式来组装,在启动的时候按顺序加载。
3.xxxlistener:假如某些模块或者xmppserver本身有扩展点希望暴露给开发者,那么他也许会提供某种listener。
4.xxxHandler:某些模块可能会有handler的概念,用于帮助你处理真正的业务逻辑。
5.plugin:提供给开发者的扩展点,你可以在有限的条件下开发插件。
注意:上图中特意把connectionManagerImpl单独拿了出来,其他它也是一个module,只不过它是最后被加载,因为它需要其他一些模块的实例,并且最终的网络连接等服务由它来提供。

最后我们来看一下openfire的启动流程


1.用户启动xmppserver
2.xmppserver初始化配置参数等。
3.xmppserver装载,初始化,启动modules
4.xmppserver异步启动plugins.
5.xmppserver fire它的serverlisteners。


五. openfire插件开发


开发一个openfire的插件相对简单,只要实现以下几个步骤就可以了。
1.实现plugin接口。
public interface Plugin {

    /**
     * Initializes the plugin.
     *
     * @param manager the plugin manager.
     * @param pluginDirectory the directory where the plugin is located.
     */
    public void initializePlugin(PluginManager manager, File pluginDirectory);

    /**
     * Destroys the plugin.<p>
     *
     * Implementations of this method must release all resources held
     * by the plugin such as file handles, database or network connections,
     * and references to core Openfire classes. In other words, a
     * garbage collection executed after this method is called must be able
     * to clean up all plugin classes.
     */
public void destroyPlugin();

该接口的2个方法相对简单,一个初始化,一个销毁。
2.打jar包。包里面的目录格式为:
[pluginDir]
*    |-- plugin.xml
*    |-- classes/
*    |-- lib/
Plugin.xml为配置文件
Classes为插件需要的一些resources文件
Lib则是插件的源代码以及源代码依赖的jar包。

举例我开发一个用户状态发生变化后,把状态值插入到redis服务器中的插件。
1.写代码:
package com.netease.openfire.plugin;

import java.io.File;

import org.apache.commons.pool.impl.GenericObjectPool;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.event.SessionEventDispatcher;
import org.jivesoftware.openfire.event.SessionEventListener;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.user.PresenceEventDispatcher;
import org.jivesoftware.openfire.user.PresenceEventListener;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class StatusPlugin implements Plugin, PresenceEventListener,
SessionEventListener {
// private XMPPServer server = XMPPServer.getInstance();
// private PresenceUpdateHandler wpuh;
// private Map<Class, Module> modules;
private static JedisPool pool;
static {
GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
poolConfig.maxActive = 30;
poolConfig.minIdle = 30;
poolConfig.minEvictableIdleTimeMillis = 500;
pool = new JedisPool(poolConfig, "192.168.150.53");
}

@Override
public void initializePlugin(PluginManager manager, File pluginDirectory) {
PresenceEventDispatcher.addListener(this);
System.out.println("add  PresenceEventListener ok !");
SessionEventDispatcher.addListener(this);
System.out.println("add  SessionEventListener ok !");

}

@Override
public void destroyPlugin() {
PresenceEventDispatcher.removeListener(this);
}

private void updateCache(String key, String value) {
Jedis jedis = pool.getResource();
jedis.set(key, value);
pool.returnResource(jedis);
}

@Override
public void availableSession(ClientSession session, Presence presence) {
updateCache(session.getAddress().toFullJID(), presence.getStatus());

}

@Override
public void unavailableSession(ClientSession session, Presence presence) {
updateCache(session.getAddress().toFullJID(), presence.getStatus());

}

@Override
public void presenceChanged(ClientSession session, Presence presence) {
updateCache(session.getAddress().toFullJID(), presence.getStatus());

}

@Override
public void subscribedToPresence(JID subscriberJID, JID authorizerJID) {
// TODO Auto-generated method stub

}

@Override
public void unsubscribedToPresence(JID unsubscriberJID, JID recipientJID) {
// TODO Auto-generated method stub

}

@Override
public void sessionCreated(Session session) {
// TODO Auto-generated method stub

}

@Override
public void sessionDestroyed(Session session) {
updateCache(session.getAddress().toFullJID(),
Presence.Type.unavailable.name());

}

@Override
public void anonymousSessionCreated(Session session) {
// TODO Auto-generated method stub

}

@Override
public void anonymousSessionDestroyed(Session session) {
// TODO Auto-generated method stub

}

@Override
public void resourceBound(Session session) {
// TODO Auto-generated method stub

}
}

2.把源代码打成jar包->status_plugin.jar
3.写plugin.xml配置
<?xml version="1.0" encoding="UTF-8"?>

<plugin>
    <class>com.netease.openfire.plugin.StatusPlugin</class>
    <name>status</name>
    <description>status plugin</description>
    <author>chenke</author>
    <version>0.1</version>
    <date>16/9/2011</date>
    <minServerVersion>3.7.0</minServerVersion>
    <adminconsole/><!- 注意这里既是没有控制台配置,也需要有个单标签 ->
</plugin>

最后按照要求打成插件的jar包。

把status_plugin.jar放入到lib目录中。
4.把打出来的插件jar包放到openfire的plugins目录下即可。
5.重启openfire.





六.Openfire开发心得


这里简单介绍下你可以基于openfire做扩展的几种方式。
本人通过2个星期对openfire的学习和部分功能的扩展。总结出集中扩展方式。
1. 通过开发插件配合xxxlistener。因为plugin能做的事情非常有限,只能拿到pluginmanager和xmppserver的实例。假如你有强力功能要开发,可能不是很好搞定。
2. 通过hacker思想,在启动plugin的时候替换xmppserver的module并且重启xmppserver
3. 在build的时候做手脚,动态字节码增强。

总之,openfire虽然具有模块化的思想,并且留给大家一些扩展点。但是没有统一约定扩展点,并且比较凌乱,需要自己仔细阅读源代码来搞定。并且还不一定能做到。不过大家尽量还是通过第一种方式来开发,是在憋不住,就改源代码吧。。

最后希望大家与我多多交流哈。。。lingqi1818@gmail.com

分享到:
评论
2 楼 witcheryne 2011-10-25  
agapple 写道
你在什么场景下需要使用Openfire?介绍下吧

XMPP协议,一般用于即时通讯..
GTalk, Google Wave 等都用的这个协议...

适用场景: 即时通讯。
1 楼 agapple 2011-10-25  
你在什么场景下需要使用Openfire?介绍下吧

相关推荐

    openfire简介.pdf

    #### 一、Openfire简介 Openfire是一款由NetNease公司开发的实时协作(RTC)服务器,它采用Java语言编写,完全开源,基于XMPP(Jabber)协议。Openfire不仅遵循基本的XMPP协议(RFC3920),更进一步实现了XMPP-IM...

    openfire环境搭建说明

    #### 一、Openfire简介与工具准备 - **Openfire**:Openfire是一款基于XMPP协议的开源即时通讯服务器,它提供了丰富的功能支持,包括消息传递、文件传输、多用户聊天等。对于企业内部通信网络来说,搭建Openfire...

    xmpp简介及openfire使用手册

    **5.1 OpenFire简介** OpenFire是一款开源的XMPP服务器,由Ignite Realtime开发。它提供了丰富的功能,支持多种操作系统,并且易于部署。 **5.2 安装与配置** - **打包OpenFire**:将OpenFire项目导入Eclipse,...

    openfire_src_3_8_2.zip

    一、Openfire简介 Openfire是Ignite Realtime社区开发的一款强大、灵活且高效的实时协作服务器。它支持多种操作系统,如Windows、Linux和Mac OS X,并且提供了易于使用的Web管理界面。Openfire的核心功能包括聊天、...

    OpenFire开发指南

    1. **OpenFire简介** OpenFire是一款免费的服务器软件,它提供了一个高效且易于管理的即时通讯解决方案。XMPP(Extensible Messaging and Presence Protocol)是OpenFire支持的主要协议,这是一种开放标准,广泛...

    Openfire源码部署与开发.doc

    #### 一、Openfire简介 Openfire是一款开源的实时通信服务器,基于XMPP协议。它提供了一个高效、可扩展的消息传递平台,适用于企业级即时通讯应用。Openfire支持多种客户端接入,并且可以通过插件系统进行功能扩展。...

    jitsi 基于 openfire 的 安卓 视频通话 源码

    **Openfire简介** Openfire是一款基于XMPP协议的服务器软件,用Java编写,可以快速地搭建即时通讯网络。它提供了用户管理、群组聊天、文件传输等基本功能,并支持SSL加密,确保通信的安全性。Openfire的可扩展性使其...

    Centos Openfire环境部署

    #### 一、Openfire简介与适用场景 - **Openfire**:是一款开源的即时通讯服务器软件,基于XMPP协议,支持文本消息、语音视频聊天、文件传输等功能。 - **适用场景**:企业内部沟通、在线客服系统、社交应用等。 ##...

    openfire源码部署开发

    #### 一、Openfire简介 Openfire是一款开源的即时通讯服务器,基于XMPP协议栈。它支持多种客户端,并且能够处理大量的并发连接。Openfire以其灵活性、可扩展性和易用性而受到广泛欢迎。 #### 二、部署准备 在开始...

    openfire servlet插件

    #### 一、Openfire简介与应用场景 Openfire是一款开源的即时消息服务器,它基于XMPP(可扩展的消息处理协议)标准,支持跨平台运行,能够提供稳定、高效的企业级通信解决方案。Openfire的核心功能包括用户管理、...

    openfire Java客户端开发文档详解

    一、Openfire简介 Openfire以其高效、稳定和可扩展性闻名,支持多种平台,包括Windows、Linux和Mac OS。它提供了丰富的API和插件机制,使得开发者可以轻松定制功能。在Java客户端开发中,Openfire提供了JStrophe库,...

    文档openfire应用

    ### Openfire简介 Openfire是一款开源、基于XMPP协议的即时通讯服务器。它提供了一个高度可扩展的消息平台,能够支持文本消息、文件传输、群聊等功能,并且可以通过多种插件来增强其功能。 ### 在CentOS上的安装...

    openfire推送

    Openfire推送是基于XMPP协议的一种服务器推送技术,它允许服务器将消息主动发送给客户端,而不需要客户端不断地查询服务器。这种推送方式在即时通讯、消息通知等场景中非常有用。Openfire是一个开源的XMPP服务器,...

    openfir使用手册

    一、OpenFire 简介 OpenFire 是一个基于 XMPP(Jabber)协议的开源实时协作服务器,可以跨平台运行,并且支持部门组织树的管理。OpenFire 安装和使用都非常简单,并利用 Web 进行管理。单台服务器可支持上万并发...

    Openfire源码分析

    ##### 4.1 MINA简介 **MINA**是Apache组织下的一个高性能网络应用开发框架,它提供了基于Java NIO的异步事件驱动API,支持多种传输协议,如TCP/IP、UDP/IP等。MINA的设计旨在帮助开发者轻松构建高性能和高扩展性的...

    openfire语音聊天

    **XMPP简介** XMPP是一种基于XML的开放标准协议,用于即时消息传递和在线状态管理。它的设计目标是灵活、可扩展和标准化,使得开发者可以轻松构建分布式IM系统和实时协作应用。XMPP的核心组件包括Jabber服务器、...

Global site tag (gtag.js) - Google Analytics