OpenFire简介

【即时通信】openfire安装和配置讲解 这里选择spark_2_8_3.exe,它自带了一个jre运行环境,因为spark_2_8_3_online.exe默认是32位jre运行环境,64位机器需要指定一个32位jre,不推荐这种方式安装。登录的时候需要设置一下服务器信息,另外,如果登录失败,报certificate_unkown,需要设置一下。一、下载openfire,解压就可以openfire启动服务。在登录spark之前,我们需要在openfire console界面创建用户,我这里创建的用户有smack,hadoop,openfire。 阅读详情

XMPP

Extensible Messaging and Presence Protocol,简单的来讲,它就是一个发送接收处理消息的协议,但是这个协议发送的消息,既不是二进制的东东也不是字符串,而是XML。正是因为使用了XML作为消息传递的中介,Extensible 才谈的上,不是么?

IM

Instant Messenger,及时通信软件,就是大家使用的QQ、MSN Messenger和Gtalk等等。其中Gtalk 就是基于XMPP 协议的一个实现,其他的则不是。当前IM 几乎作为每个上网者必然使用的工具,在国外的大型企业中有一些企业级的IM应用,但是其商业价值还没完全发挥出来。设想既然XMPP 协议是一个公开的协议,那么每个企业都可以利用它来开发适合本身企业工作,提高自身生产效率的IM;甚至,你还可以在网络游戏中集成这种通信软件,不但让你可以边游戏边聊天,也可以开发出适合游戏本身的IM 应用,比如说一些游戏关键场景提醒功能,团队语音交流等等都可以基于IM来实现。

Spark Smack 和 Openfire

开源界总是有许多有趣的东东,这三个合起来就是一个完整的XMPP IM 实现。包括服务器端——Openfire,客户端——Spark,XMPP 传输协议的实现——Smack(记住,XMPP是一个协议,协议是需要实现的,Smack起到的就是这样的一个作用)。三者都是基于Java 语言的实现。

Spark 提供了客户端一个基本的实现,并提出了一个很好的插件架构,这对于开发者来说不能不说是一个福音。我强烈建议基于插件方式来实现你新增加的功能,而不是去改它的源代码,这样有利于你项目架构,把原始项目的影响降到最低。

Openfire 是基于XMPP 协议的IM 的服务器端的一个实现,虽然当两个用户连接后,可以通过点对点的方式来发送消息,但是用户还是需要连接到服务器来获取一些连接信息和通信信息的,所以服务器端是必须要实现的。Openfire 也提供了一些基本功能,但真的很基本的!庆幸的是,它也提供插件的扩展,像Spark 一样,同样强烈建议使用插件扩展的方式来增加新的功能,而不是修改人家的源代码。

Smack 是一个XMPP 协议的Java 实现,提供一套可扩展的API,不过有些时候,你还是不得不使用自己定制发送的XML 文件内容的方式来实现自己的功能

企业案例-聚友中国即时通讯-PC端+WEB端+android端+ios端+平板端+云端多平台互通、方便集成各类应用

 

下图展示了三者之间的关系: 

 图片

 

 

 

从图上可以了解到,client 端和server端都可以通过插件的方式来进行扩展,smack是二者传递数据的媒介。

Apache MINA

Openfire的通信处理基于Apache MINA框架实现。Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序。它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API。

  Apache MINA 也称为:

  ● NIO 框架库

  ● 客户端服务器框架库

  ● 一个网络套接字库

  MINA虽然简单但是仍然提供了全功能的网络应用程序框架:

  ● 为不同的传输类型提供了统一的API:

  ○ 通过Java NIO提供TCP/IP 和 UDP/IP支持

  ○ 通过RXTX提供串口通讯(RS232)

  ○ In-VM管道通讯

  ○ 你能实现你自己的API!

  ● 过滤器作为一个扩展特性; 类似Servlet过滤器

  ● 低级和高级的API:

  ○ 低级: 使用字节缓存(ByteBuffers)

  ○ 高级: 使用用户定义的消息对象(objects)和编码(codecs)

  ● 高度定制化线程模型:

  ○ 单线程

  ○ 一个线程池

  ○ 一个以上的线程池(也就是SEDA)

  ● 使用Java 5 SSL引擎提供沙盒(Out-of-the-box) SSL • TLS • StartTLS支持

  ● 超载保护和传输流量控制

  ● 利用模拟对象进行单元测试

  ● JMX管理能力

  ● 通过StreamIoHandler提供基于流的I/O支持

  ● 和知名的容器(例如PicoContainer、Spring)集成

  ● 从Netty平滑的迁移到MINA, Netty是MINA的前辈。

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

XXStarter

系统启动类,如org.jivesoftware.openfire.starter.ServerStarter,调用其start()方法可启动系统应用。

XXListener

业务的最终处理类。

 

所有的业务都是在Listener类中实现的

 

XXDispatcher

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

 

XXPlugin

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

 

XXProvider

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

 

XXHandler

    实际处理类,以ConnectionHandler为例,在org.jivesoftware.openfire.spi. ConnectionManagerImpl类的startClientSSLListeners(String localIPAddress)方法中,有这样一段代码:

sslSocketAcceptor.bind(new InetSocketAddress(bindInterface, port), new ClientConnectionHandler(serverName));其中bind方法的第二个参数是新创建的一个ClientConnectionHandler的实例,而它就是ConnectionHandler的一个子类。

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

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

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

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

四、     ofproperty中的各条记录,该表中包括两个字段name和propvalue,分别代表配置项名和配置项值。

 

    系统启动时调用ServerStarter类中的start()方法,通过反射加载org.jivesoftware.openfire.XMPPServer类文件,创建实例时调用其构造函数,在其构造函数中调用其start()方法实际启动服务应用程序。Start()方法中首先调用verifyDataSource()方法验证并确保数据库可以访问,然后会调用                loadModules();initModules();startModules();方法来对Module接口的实现类的各子类进行操作,依次完成模块的加载、初始化和启动操作。loadModules()方法中会调用loadModule(String module)方法通过反射加载各模块类,参数字符串module为对应的模块核心处理类的类名,如AdHocCommandHandler。现以AdHocCommandHandler为例对接下来的处理流程进行说明。通过loadModule创建AdHocCommandHandler类实例时调用其构造函数,在构造函数中初始化了其私有AdHocCommandManager对象。在initModules()时调用AdHocCommandHandler实例的initialize(XMPPServer server)方法对其私有属性对象进行初始化。然后调用start()方法,调用addDefaultCommands方法添加命令并启动命令(通过调用startCommand(AdHocCommand command)方法实现)。

消息监听服务

SSL等监听服务的调度在ConnectionManagerImpl类中实现。ConnectionManagerImpl.createClientSSLListeners()方法启动SSL监听

 

消息封装

信息处理采用XML节的方式传递信息,消息封装通常采用IQ、Message、Presence。

Openfire消息包接受处理流程

 

Openfire的数据库处理采用直接调用JDBC 的方式。核心类为org.jivesoftware.database.DbConnectionManager。数据库的处理与业务处理耦合,没有划分出专门的业务逻辑层。

ConnectionProvider

       此类为数据库提供者接口,如需连接mysql、hsqldb等数据库,需首先实现些接口,

处理方式

    通常直接调用XXManager中的实例方法,XXManager中又调用的是对应的接口XXProvider的方法,实际操作在该接口的实现类中实现。实现类是动态绑定的(默认的实现类通常命名规则为DefaultXXProvider),在运行时根据ofproperty表中对应配置项值选择。下面以添加用户组为例进行说明。

    首先获得GroupManager的一个实例,在调用其构造函数时调用initProvider()方法,在该方法中获取数据库中配置项的值,若不为空则根据该值通过反射机制获取GroupProvider接口的实现类实例对象;若为空则以DefaultGroupProvider作为GroupProvider接口的实现类并创建实例对象,然后调用GroupProvider. createGroup(String name)方法完成业务操作。

 

常用类

org.jivesoftware.database.DbConnectionManager

    连接管理类

 

org.jivesoftware.util.JiveGlobals

    通常用于操作ofproperty表中记录

 

openfire数据结构

数据库表

以下是一个说明每个表格的Openfire数据库架构。黄色行表示主键。

·         ofGroup

·         ofGroupProp

·         ofGroupUser

·         ofID

·         ofOffline

·         ofPresence

·         ofPrivate

·         ofUser

·         ofUserProp

·         ofUserFlag

·         ofRoster

·         ofRosterGroups

·         ofPrivacyList

·         ofVCard

·         ofVersion

·         ofProperty

·         ofExtComponentConf

·         ofRemoteServerConf

·         ofSecurityAuditLog

·         ofMucService

·         ofMucServiceProp

·         ofMucRoom

·         ofMucRoomProp

·         ofMucAffiliation

·         ofMucMember

·         ofMucConversationLog

·         ofPubsubNode

·         ofPubsubNodeJIDs

·         ofPubsubNodeGroups

·         ofPubsubAffiliation

·         ofPubsubItem

·         ofPubsubSubscription

·         ofPubsubDefaultConf

ofGroup (用户组的数据)

列名 类型 长度 描述
groupName VARCHAR 50 组名称(主键)
description VARCHAR 255 组描述

 

ofGroupProp (名称值协会为一组)

列名 类型 长度 描述
groupName VARCHAR 50 组名称(主键)
name VARCHAR 100 组属性名称(主键)
propValue VARCHAR 4000 组,属性值

 

ofGroupUser (组成员)

列名 类型 长度 描述
groupName VARCHAR 50 组名称(主键)
username VARCHAR 100 用户名,(主键)
administrator NUMBER n/a 是否为管理员(布尔)(主键)

 

ofID (用于唯一ID序列生成)

列名 类型 长度 描述
idType NUMBER n/a 证件类型(例如,组,用户名册)(主键)
id NUMBER n/a 下一个可用块编号的(用于数据库独立编号)

 

ofOffline (离线邮件存储)

列名 类型 长度 更改
username VARCHAR 32 用户名(主键)
messageID NUMBER n/a 存储信息的编号(主键)
creationDate VARCHAR 15 日期信息存储
messageSize NUMBER n/a 邮件的大小以字节为单位
stanza TEXT n/a 消息文本

 

ofPresence (离线的存在)

列名 类型 长度 更改
username VARCHAR 64 用户名(主键)
offlinePresence TEXT n/a 存在的信息设置为用户注销
offlineDate CHAR 15 信息存储日期

 

ofPrivate (私人数据存储)

列名 类型 长度 描述
username VARCHAR 32 用户名(主键)
name VARCHAR 100 姓名私营项(主键)
namespace VARCHAR 200 名字空间私营项(主键)
privateData TEXT n/a 价值的私人数据

 

ofUser (用户数据)

列名 类型 长度 描述
username VARCHAR 32 用户名(主键)
plainPassword VARCHAR 32 纯文字密码数据
encryptedPassword VARCHAR 255 加密的密码数据(默认)
name VARCHAR 100 名字
email VARCHAR 100 电邮地址
creationDate VARCHAR 15 创建日期
modificationDate VARCHAR 15 最后更新日期

 

ofUserProp (名称值协会针对用户)

列名 类型 长度 描述
username VARCHAR 32 用户名(主键)
name VARCHAR 100 用户属性名称(主键)
propValue VARCHAR 4000 用户属性值

 

ofUserFlag (用户类型标识(如残疾人))

列名 类型 长度 描述
username VARCHAR 64 用户名(主键)
name VARCHAR 100 用户属性名称(主键)
startTime CHAR 15 国旗的时候,开始被有效(无效的'现在',)
endTime CHAR 15 当时国旗是结束有效(无效的'永远',)

 

ofRoster (好友列表)

列名 类型 长度 描述
rosterID NUMBER n/a 编号,名册,(主键)
username VARCHAR 32 用户名
jid TEXT n/a 地址名册入境
sub NUMBER n/a 认购地位入境
ask NUMBER n/a 卖出地位入境
recv NUMBER n/a 检举表明进入名册收到请求
nick VARCHAR 255 昵称分配给这个名册入境

 

ofRosterGroups (组的好友名单中的条目)

列名 类型 长度 描述
rosterID NUMBER n/a 名册编号(主键)
rank NUMBER n/a 立场项(主键)
groupName VARCHAR 255 用户定义的名称,这个名册组

 

ofPrivacyList (用户隐私清单)

列名 类型 长度 描述
username VARCHAR 32 用户名(主键)
name VARCHAR 100 姓名保密清单(主键)
isDefault NUMBER n/a 检举指出,如果这是默认隐私的用户名单
list TEXT n/a XML表示的隐私清单

 

ofVCard (电子名片的联系信息)

列名 类型 长度 描述
username VARCHAR 32 用户名(主键)
vcard TEXT n/a 价值的vCard入境

 

ofVersion (包含产品版本信息)

列名 类型 长度 描述
name VARCHAR 50 名称的项目,版本信息正在跟踪的(主键)
version INTEGER n/a 版本号

 

ofProperty (服务器属性)

列名 类型 长度 描述
name VARCHAR 100 属性名称(主键)
propValue TEXT n/a 进入值

 

ofExtComponentConf (外部元件配置)

列名 类型 长度 描述
subdomain VARCHAR 255 子的外部元件(主键)
secret VARCHAR 255 共享,密钥,的外部元件
permission VARCHAR 10 许可,表明如果组件是可以连接到服务器

 

ofRemoteServerConf (远程服务器配置)

列名 类型 长度 描述
xmppDomain VARCHAR 255 域的外部元件(主键)
remotePort NUMBER n/a 港口的远程服务器连接到
permission VARCHAR 10 许可,表明如果远程服务器可以连接到服务器

 

ofSecurityAuditLog (伐木安全事件)

列名 类型 长度 描述
msgID NUMBER n/a 编号审计信息(主键)
username VARCHAR 64 使用者谁执行的行动
entryStamp NUMBER n/a 时间戳,当事件发生
summary VARCHAR 255 总结了发生在事件
node VARCHAR 255 节点事件发生
details TEXT n/a 详细的细节,所发生的

 

ofMucService (甲Groupchat服务)

列名 类型 长度 描述
serviceID NUMBER n/a 编号的服务(收录)
subdomain VARCHAR 255 子服务(主键)
description VARCHAR 255 服务说明
isHidden NUMBER n/a 1,如果隐藏的管理界面名单,0正常

 

ofMucServiceProp (名称值协会的Groupchat服务)

列名 类型 长度 描述
serviceID NUMBER n/a 编号的服务(主键)
name VARCHAR 100 属性名称(主键)
propValue TEXT n/a 属性值

 

ofMucRoom ( Groupchat室内资料)

列名 类型 长度 描述
roomID NUMBER n/a 编号的房间(主键)
creationDate VARCHAR 15 创建日期
modificationDate VARCHAR 15 最后更新日期
name VARCHAR 50 姓名房间用作公共编号
naturalName VARCHAR 255 天然名称室
description VARCHAR 255 客房描述
canChangeSubject NUMBER n/a 检举指出是否可以改变参与者的主题
maxUsers NUMBER n/a 马克斯一些房间居住者
canChangeSubject NUMBER n/a 检举指出是否与会者可以改变的主题或不
publicRoom NUMBER n/a 检举指示是否室将在目录中列出或不
moderated NUMBER n/a 检举指示是否室主持或不
membersOnly NUMBER n/a 检举指出是否房间是会员制或不
canInvite NUMBER n/a 检举指出是否占用可以邀请其他用户
roomPassword VARCHAR 50 密码数据加入室
canDiscoverJID NUMBER n/a 检举指出是否真正JID的居住者是公共或不
logEnabled NUMBER n/a 检举指出是否房间谈话记录或不
subject VARCHAR 100 最后为人所知的主题房间
rolesToBroadcast NUMBER n/a 二元代表的作用,以广播
useReservedNick NUMBER n/a 检举指出是否用户只能加入室使用其保留昵称
canChangeNick NUMBER n/a 检举指出是否可以改变其占用的空间昵称
canRegister NUMBER n/a 检举显示用户是否被允许登记室

 

ofMucRoomProp (名称值协会的Groupchat房间)

列名 类型 长度 描述
roomID NUMBER n/a 编号的房间(主键)
name VARCHAR 100 属性名称(主键)
propValue VARCHAR 4000 属性值

 

ofMucAffiliation (归属的空间用户)

列名 类型 长度 描述
roomID NUMBER n/a 编号的房间(主键)
jid TEXT n/a 用户JID,(主键)
affiliation NUMBER n/a 一些代表所属一级

 

ofMucMember (室成员资料)

列名 类型 长度 描述
roomID NUMBER n/a 编号的房间(主键)
jid TEXT n/a 用户JID,(主键)
nickname VARCHAR 255 保留昵称的会员

 

ofMucConversationLog (室会话日志)

列名 类型 长度 描述
roomID NUMBER n/a 编号的空间
sender TEXT n/a JID的用户发送邮件的房间
nickname VARCHAR 255 昵称使用时由用户发出的信息
logTime VARCHAR 15 日期的消息时,被送到房间
subject VARCHAR 50 新的主题改变的信息
body TEXT n/a 消息正文

 

ofPubsubNode (节点pubsub服务)

列名 类型 长度 描述
serviceID VARCHAR 100 编号托管服务节点(主键)
nodeID VARCHAR 100 编号的节点(主键)
leaf NUMBER n/a 检举表明节点是否是叶或收集节点
creationDate VARCHAR 15 创建日期
modificationDate VARCHAR 15 最后更新日期
parent VARCHAR 100 编号的父节点(如果有的话)
deliverPayloads NUMBER n/a 检举指出是否有效载荷中包含的通知
maxPayloadSize NUMBER n/a 最大规模的有效载荷的字节
persistItems NUMBER n/a 检举表明节点是否将持续出版项目
maxItems NUMBER n/a 最大的项目数量将持续
notifyConfigChanges NUMBER n/a 检举指出是否发送通知时,该节点的配置发生了变化
notifyDelete NUMBER n/a 检举指出是否发送通知时,该节点将被删除
notifyRetract NUMBER n/a 检举指出是否发送通知时,发布的项目将被删除
presenceBased NUMBER n/a 检举指出是否发送通知只有用户才
sendItemSubscribe NUMBER n/a 检举指出是否向去年出版项目,以新用户
publisherModel VARCHAR 15 Publisher中使用的模式的节点
subscriptionEnabled NUMBER n/a 检举指出是否允许订阅
configSubscription NUMBER n/a 检举指出是否新的订户必须设定为活跃
accessModel VARCHAR 10 访问模型所使用的节点
payloadType VARCHAR 100 类型的有效载荷数据将提供在节点
bodyXSLT VARCHAR 100 网址的一个XSLT转换有效载荷的格式为一个邮件正文
dataformXSLT VARCHAR 100 网址的一个XSLT转化的有效载荷格式的数据形式结果
creator VARCHAR 1024 JID的实体建立了节点
description VARCHAR 255 说明节点
language VARCHAR 255 默认语言的节点
name VARCHAR 50 名称节点
replyPolicy VARCHAR 15 政策界定业主或出版商是否应得到答复项目
associationPolicy VARCHAR 15 政策规定谁可以联系叶节点的集合
maxLeafNodes NUMBER n/a 马克斯一些叶节点,一个节点可能会收集

 

ofPubsubNodeJIDs ( JIDs与节点)

列名 类型 长度 描述
serviceID VARCHAR 100 编号托管服务节点(主键)
nodeID VARCHAR 100 编号的节点(主键)
jid VARCHAR 1024 JID实体(主键)
associationType VARCHAR 20 协会类型的节点

 

ofPubsubNodeGroups (名册集团与节点)

列名 类型 长度 内容
serviceID VARCHAR 100 编号托管服务节点
nodeID VARCHAR 100 编号的节点
rosterGroup VARCHAR 100 名册组节点所有者可以签署和检索项目

 

ofPubsubAffiliation (节点分支机构)

列名 类型 长度 描述
serviceID VARCHAR 100 编号托管服务节点(主键)
nodeID VARCHAR 100 编号的节点(主键)
jid VARCHAR 1024 JID的子公司(主键)
affiliation VARCHAR 10 所属类别

 

ofPubsubItem (项目发布到节点)

列名 类型 长度 描述
serviceID VARCHAR 100 编号托管服务节点(主键)
nodeID VARCHAR 100 编号的节点(主键)
id VARCHAR 100 编号的出版项目(独特的每个节点)(主键)
jid VARCHAR 1024 JID出版商
creationDate VARCHAR 15 创建日期
payload TEXT n/a XML的有效载荷包括在出版项目

 

ofPubsubSubscription (订阅节点)

列名 类型 长度 描述
serviceID VARCHAR 100 编号托管服务节点(主键)
nodeID VARCHAR 100 编号的节点(主键)
id VARCHAR 100 编号认购(主键)
jid VARCHAR 1024 地址接收通知
owner VARCHAR 1024 JID的子公司,拥有认购
state VARCHAR 15 国家认购(工作流程中的)
deliver NUMBER n/a 检举指出是否通知或未启用
digest NUMBER n/a 检举表明一个实体是否希望收到通知摘要
digest_frequency NUMBER n/a 最低数目的毫秒之间发出任何两个通知消化
expire VARCHAR 15 日期在租赁认购将结束或已经结束
includeBody NUMBER n/a 检举表明一个实体是否希望收到邮件正文除了有效载荷格式
showValues VARCHAR 30 存在这些国家的实体希望收到通知
subscriptionType VARCHAR 10 无论是用户订阅的项目或节点(收集节点只)
subscriptionDepth NUMBER n/a 收到通知的儿童一定深度(收集节点只)
keyword VARCHAR 200 关键字活动必须符合

 

ofPubsubDefaultConf (默认配置节点)

列名 类型 长度 描述
serviceID VARCHAR 100 编号托管服务节点(主键)
leaf NUMBER n/a 检举指出是否配置属于叶或收集节点(主键)
deliverPayloads NUMBER n/a 检举指出是否有效载荷中包含的通知
maxPayloadSize NUMBER n/a 最大规模的有效载荷的字节
persistItems NUMBER n/a 检举表明节点是否将持续出版项目
maxItems NUMBER n/a 最大的项目数量将持续
notifyConfigChanges NUMBER n/a 检举指出是否发送通知时,该节点的配置发生了变化
notifyDelete NUMBER n/a 检举指出是否发送通知时,该节点将被删除
notifyRetract NUMBER n/a 检举指出是否发送通知时,发布的项目将被删除
presenceBased NUMBER n/a 检举指出是否发送通知只有用户才
sendItemSubscribe NUMBER n/a 检举指出是否向去年出版项目,以新用户
publisherModel VARCHAR 15 Publisher中使用的模式的节点
subscriptionEnabled NUMBER n/a 检举指出是否允许订阅
accessModel VARCHAR 10 访问模型所使用的节点
language VARCHAR 255 默认语言的节点
replyPolicy VARCHAR 15 政策界定业主或出版商是否应得到答复项目
associationPolicy VARCHAR 15 政策规定谁可以联系叶节点的集合
maxLeafNodes NUMBER n/a 马克斯一些叶节点,一个节点可能会收集

 

 

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

       Openfire没有采用现在很流行的技术架构(SSH),只使用JSP+JavaBean,但是它有自己的系统设计,就连日志都是自己做的,没有使用我们熟悉的log4j。

现有的Openfire管理控制台可采用插件方式进行扩展(详见插件开发说明部分介绍),页面采用Jsp方式实现,页面直接调用业务处理逻辑类(通常命名为XXManager)的实例方法,通常通过request对象封装的方式传递页面展现判定变量,常出现本页跳转。每个插件可定义自己的Servlet类和web.xml及web-custom.xml配置文件。

    采用装饰框架方式展现页面,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装饰器进行页面展现。详见“使用dom4j设计Openfire式导航菜单”部分相关介绍。

 

Openfire Plugins加载流程

 

 

官方插件开发说明

所有插件都存放在openfire根下的plugins目录下。当一个插件被以JAR或WAR文件发布时,他自动扩展为一个文件夹。插件目录结构如下所示:

Plugin Structure

myplugin/

 |- plugin.xml      <- 插件定义文件

 |- readme.html     <- 可选的插件自己述文件,它将被显示给最终用户。

 |- changelog.html  <-可选的插件版本日志文件,它将被展现给最终用户。

 |- logo_small.gif  <- 可选的与插件关联的小图标(16x16)文件(也能为png文件)

 |- logo_large.gif  <-可选的与插件关联的大图标(32x32)文件(也能为png文件)

 |- classes/        <- 你的插件需要的资源文件(如properties文件)

 |- database/       <- 可选的你的插件需要的数据库schema文件

 |- i18n/           <- 可选的i18n文件,它们为插件提供国际化支持

 |- lib/            <- 你的插件需要的库(JAR文件)

 |- web             <- 需要集成到管理控制台中的各类资源(如果有的话)

     |- WEB-INF/

         |- web.xml           <- 配置jsp调度的web.xml配置文件

         |- web-custom.xml    <- 可选的用户定义的web.xml文件,用于调度自定义servlets

     |- images/

 

 

若插件需要为Openfire的管理控制台添加内容,则web文件夹必须存在。具体内容详述如下。

 

Plugin.xml文件指定了主插件类,下面是一个例子。

 

Itvi plugin.xml

<?xml version="1.0" encoding="UTF-8"?>

<plugin>

    <!-- Main plugin class -->

    <class>plugin.Itvi</class>

 

    <!-- Plugin meta-data -->

    <name>TestPlugin</name>

    <description>This is an example plugin.</description>

    <author>Jive Software</author>

 

    <version>1.0</version>

    <date>07/01/2006</date>

    <url>http://www.igniterealtime.org/projects/openfire/plugins.jsp</url>

    <minServerVersion>3.0.0</minServerVersion>

    <licenseType>gpl</licenseType>

 

    <!-- Admin console entries -->

    <adminconsole>

        <!-- More on this below -->

        <tab id="mytab" name="Example" url="sample.html" description="Click to manage...">

            <sidebar id="mysidebar" name="My Plugin">

               <item id="my-plugin" name="My Plugin Admin"

                   url="sample.html"

                   description="Click to administer settings for my plugin" />

            </sidebar>

        </tab>

 

    </adminconsole>

</plugin>

 

 

各元数据域能在plugin.xml文件中进行设置:

·         name – 插件名.

·         description – 插件描述.

·         author – 插件作者.

·         version – 插件版本.

·         date – 插件版本生成日期。该日期必须为MM/dd/yyyy格式, 如07/01/2006.

·         url – 关于该插件的更多详细信息可以从该地址获取.

·         minServerVersion – 为运行该插件所需的最低的Openfire软件版本(Openfire 2.1.2及后续版本支持该选项).如果服务器版本低于需要的最低版本,插件将不会启动.

·         databaseKey – 如果插件需要它自己的数据库表,必须将databaseKey元素设置为一个schema key name(通常与插件同名). 然后需将所有需支持数据库类型的数据库schema 文件放到插件的database文件夹下. 例如,给一个关键字“foo”,那么schema文件需命名为"foo_mysql.sql", "foo_oracle.sql"等.我们建议你在命名你的表时加上前缀"of" (openfire),以避免与其他可能使用同一数据库的其他应用系统需要的表产生冲突.关于版本的描述信息需添加到ofVersion表中,以对应的key做标识,这样可以跟踪schema版本信息,如:

INSERT INTO ofVersion (name, version) VALUES (&apos;foo&apos;, 0);

·         databaseVersion – 数据库schema版本(如果定义了数据库schema)。有数据库schema的新插件的版本从0开始编号。如果以后的插件版本需要更新schema,这些更新能通过在database/upgrade目录下为各版本创建子目录的方式来定义。例如目录database/upgrade/1和database/upgrade/2将包括如 "foo_mysql.sql"和"foo_oracle.sql" 这样的包含各版本相应的数据库改变信息的脚本.这些脚本中均需要更新ofVersion表的信息,如:

UPDATE ofVersion set version=1 where name=&apos;foo&apos;;

·         parentPlugin – 父插件名 ("foo.jar"插件相应的为"foo").当一个插件有一个父插件,将不会创建一个新的class loader,相应地替换为使用父插件的class loader。这使得插件间能更紧密地联合工作。子插件不能脱离父插件独立工作。

·         licenseType – 指定许可类型信息。 有效值包括:

o    "commercial": 插件被发布为商业性插件。

o    "gpl": 插件被发布为遵循GNU Public License (GPL)协议。

o    "apache": 插件被发布为Apache license系列

o    "internal": 插件仅供内部使用,且不能被重新发布。

o    "other": 插件被发布为与其他目录下的版本限制不同。License许可信息需在插件自述文件中进行详细描述。

如果许可类型未设置,默认为other。

为了给最终用户提供插件的额外信息,可以为插件添加一些额外文件(全放置在插件的主目录下):

·         readme.html – 可选的插件自述文件,它的信息将展现给最终用户。

·         changelog.html --可选的插件版本日子文件,它将被展现给最终用户。

·         logo_small.png --可选的与插件关联的小图标(16x16)文件(也能为gif文件)。

·         logo_large.png --可选的与插件关联的大图标(32x32)文件(也能为gif文件)。

插件必须实现Plugin接口,且有一个默认构造函数。Plugin接口包含了初始化和销毁插件的方法。

Sample plugin implementation

package org.example;

 

import org.jivesoftware.openfire.container.Plugin;

import org.jivesoftware.openfire.container.PluginManager;

 

import java.io.File;

 

/**

 * A sample plugin for Openfire.

 */

public class ExamplePlugin implements Plugin {

 

    public void initializePlugin(PluginManager manager, File pluginDirectory) {

        // Your code goes here

 

    }

 

    public void destroyPlugin() {

        // Your code goes here

    }

}

 

Openfire框架学习(1)-----openfire简介 框架简介:Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议。您可以使用它轻易的构建高效率的即时通讯服务器.Openfire安装和使用都非常简单,并利用Web进行管理。单台服务器可支持上万并发用户。由于是采用开放的XMPP协议,您可以使用各种支持XMPP协议的IM客户端软件登陆服务.框架优点•全JAVA语言实现,不依赖任何系统平台;•基完全开源,GP 阅读详情

相关推荐

集成Coherence至Openfire的实践指南

在现代的软件应用中,随着业务规模的增长和分布式架构的普及,数据管理变得越来越复杂。Coherence作为一个分布式缓存解决方案,为Java应用提供了一种优雅且强大的数据管理工具。它允许应用程序存储、访问和管理跨多个服务器的数据,实现数据的快速获取和持久化。

weixin_33239721的博客 1006

openfire总结

Openfire学习总结 基本描述 Openfire最主要的功能是实现XMPP服务器,简单来说,openfire为我们提供一个固定的地址,我们只需要向openfire服务器发送标准的XMPP信息(即XML文件流),那么openfire服务器应当给予我们回应,这里的openfire服务器也可以看做一个容器,我们在聊天时,需要在这个服务器上注册一个会话,在会话存...

学为博客 1万+

智能电网中的智能调度与优化算法研究

本文研究智能电网中的智能调度与优化算法,旨在提高电网运行的效率与可靠性,减少能源浪费和设备故障的风险。在智能电网日益复杂化的背景下,传统的调度方法已难以满足高效、稳定的运行要求,因此亟需借助先进的优化算法对电网进行智能调度。本文第一深入分析智能电网调度中的关键问题与挑战,探讨优化算法在智能电网中的应用现状,并分析常见的优化算法,如遗传算法、粒子群算法和模拟退火算法。随后,本文构建智能电网的调度优化数学模型,并对电网负荷、发电模型及约束条件进行详细建模。在算法部分,本文提出改进的粒子群算法和遗传算法,并结合M

weixin_44553616的博客 1888

IM学习-认识Openfire(三)

目录 3.Openfire 3.1 Openfire简介 3.2 Openfire官网 3.3 下载和安装 3.4 Openfire配置 3.4.1 进入配置页面 3.4.2配置语言 3.4.3配置服务器 3.4.4数据库配置 3.4.5 配置管理账号 3.4.6配置结果 3.Openfire 3.1 Openfire简介 Openfire是免费、开源的,基于XMP...

牛八少爷的专栏 3261

AI提示词实战:用EARS语法5步搞定产品需求拆解(附完整案例)

本文详细介绍了如何运用EARS语法将模糊的产品需求进行原子化拆解,转化为清晰、可执行的结构化指令。通过一个完整的自由职业者项目管理工具案例,演示了从原始需求分析到构建增强AI提示词的五步实战流程,帮助产品经理和技术人员实现高效、精准的需求传达与协作。

nokia的博客 1029

单片机多级菜单的简单实现

单片机多级菜单的简单实现 多级菜单的思路 最近想把stm32上的oled显示屏做的好看一些,于是动手写了写一个多级菜单,思路很简单,每个页面用单独的函数封装好,每个功能也是用单独的函数进行封装,用了3个按键,两个切换键,一个确定键。 首先来看看用啥判断页面的(这偷个懒,希望没人打我) //页面标志位 uint8_t s1 = 0; //主页面功能号 uint8_t s2 = 0; //主次页面判断标志位 uint16_t s3 = 1; //次页面功能号 主页面的显示函数,这是个很枯燥的一

qq_43940175的博客 7604

openfire 的配置

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。 您需要 登录 才可以下载或查看,没有帐号?注册  x 一、下载并安装openfire 1.到http://www.igniterealtime.org/downloads/index.jsp下载最新openfire for mac版 比如:Openfire 3.8.1,下载后的文件:openfire_3_8

2769

告别SendKeys!用DD驱动级模拟在Windows 10/11上实现真·后台键鼠操作(Python实战)

本文详细介绍了如何使用DD驱动级模拟技术在Windows 10/11上实现真后台键鼠操作,解决传统方法如pyautogui和SendKeys的局限性。通过Python实战案例,展示了驱动级模拟在游戏自动化、RPA等场景中的高效应用,包括环境配置、核心API解析及高级优化技巧。

weixin_42519985的博客 798

openfire简介

一、是什么?     Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议。Openfire安装和使用都非常简单,并利用Web进行管理。单台服务器可支持上万并发用户。由于是采用开放的XMPP协议,您可以使用各种支持XMPP协议的IM客户端软件登陆服务。如果你想轻易地构建高效率的即时通信服务器,那就选择它吧! 二、做什么?          我

刘玉杰 点滴之笔 7656

摄像头模组选型避坑指南:如何根据Sensor和Lens参数匹配最佳组合

本文深入解析摄像头模组选型中Sensor与Lens的核心参数匹配要点。重点阐述了主光线角(CRA)匹配对边缘画质的关键影响,并提供了传感器尺寸、像素尺寸、焦距、光圈等参数的协同选型策略与实战避坑指南,帮助工程师在手机、安防、车载等不同应用场景下实现性能与成本的最佳平衡。

ee345的博客 617

矢量网络分析仪VNA的校准之SOLT方法

作者:杭州冥鸿电子科技有限公司 邮箱:huanglong@deepelec.com S参数的测量方法有两种,一种是基于扫频测量的原理(VNA),另外一种是基于快沿阶跃响应的原理(TDR)。 下图是VNA的原理框图,主要包括以下部分: (1)激励信号源:提供感兴趣的频率范围内的入射信号; (2)信号分离装置:含功分器和定向耦合器,分离出入射,反射和传输信号; (3)接收机:...

u010018619的博客 2万+

OPenfire简介

1. Openfire Openfire是开源的实时协作服务器(RTC),它是基于公开协议XMPP(也成为Jabber)消息的。Openfire的核心功能可以概括为:连接管理、消息解析、消息路由、消息发送。 1.1 框架 Openfire核心功能由Module组成,上图中的各个模块绝大多数也是基于Module实现的。为了动态的管理这些Module,Openfire使用了自

michael1112的专栏 1466

3D 结构光相机工作原理全解 | 从编码投射到三维重建,原理 + 代码 + 工业实战一站式掌握

本文从3D结构光相机的整体架构出发,层层拆解了编码投射、相位计算、相位解包裹、三维重建的核心原理,补充了工业实战所需的公式推导、代码实现、参数调优、设备选型和案例落地,核心总结如下:相位是3D结构光成像的“灵魂”,其精度、稳定性直接决定3D重建的效果,包裹相位与绝对相位的区分的是工业实战的基础;编码投射的核心是“正弦条纹+格雷码条纹”组合,正弦条纹负责高精度相位提取,格雷码条纹辅助解包裹,适配工业场景的精度与稳定性需求;

getusushu的博客 411

Openfire第一章(Openfire的简介)

最近有一些

秋风扶柳笛的专栏 857

Oracle EBS Interface/API(43) -自定义AP发票状态说明API

在某项目,客户需求获得AP发票的状态说明,例如对账系统或者某些报表。由于标准系统未提供状态说明,需要通过AP发票的标准Form获得相关业务逻辑,然后自定义AP发票状态说明API。

陈显平的专栏-Oracle EBS 605

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Openfire简介

目录 1基础简介2命名规则3系统配置项4系统启动流程5网络处理6数据库处理 展开 编辑本段基础简介 XMPP Extensible Messaging and Presence Protocol,简单的来讲,它就是一个发送接收处理消息的协议,但是这个协议发送的消息,既不是二进制的东东也不是字符串,而是XML。正是因为使用了XML作为消息传递的中介,Extensible 才谈的上,不是

billfanggs的专栏 1453

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

openfire插件开发简介

把openfire的源码导入eclipse 分析如下:

落叶翩翩的优快云博客 1014

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Openfire简介及安装配置

chatlogs jackson-all

lzx1104的专栏 1258

spark+openfire IM开源应用配置方法简介

团队准备做一个IM的二次开发项目,想找一个稳定的、扩展性强的IM开源组件进行开发,找了很久,这方面的很多也不知道那一个比较合适,miranda IM 、Openfire+Spark、phpMychat、pidgin、GNU、等30种,看了许多论坛实在对比不出哪一个好,就决定先拿一个争议最多的Spark配置一下看看,结果配置下来也不算太复杂。   配置的目的为测试体验用户界面、后台管理界面,配置

ITMAOO 1986

创建即时通信服务器的工具 openfire 简介

一、是什么? Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议。Openfire安装和使用都非常简单,并利用Web进行管理。单台服务器可支持上万并发用户。由于是采用开放的XMPP协议,您可以使用各种支持XMPP协议的IM客户端软件登陆服务。如果你想轻易地构建高效率的即时通信服务器,那就选择它吧! 二、做什么? 我们要了解Openfire,首先要了解XMPP协议,因为Openfire是用Java语言编写的,基于XMPP协议、开源...

whatday的专栏 1498

C#访问openfire服务器之一:服务端的安装、客户端的简介

最近在移动端开发中遇到推送消息、即时通信的需求,以前没有注意过这方面的知识,特别花费一段时间捣鼓了一下,初步实现了c#访问openfire服务器,实现即时通信。特此记录一下,方便与我一般的初涉者参考。 首先,即时通信服务分为服务端与客户端两块。 一、服务端 服务端使用openfire直接进行搭建,基本上是一步步向下操作即可。 我使用的是exe版本的安装程序,首先

仙道喵喵的专栏 2289

基于xmpp openfire smack开发之openfire介绍和部署[1]

前言 Java领域的即时通信的解决方案可以考虑openfire+spark+smack。当然也有其他的选择。 Openfire是基于Jabber协议(XMPP)实现的即时通信服务器端版本,目前建议使用3.8.1版本,这个版本是当前最新的版本,而且网上可以找到下载的源代码。 即时通信客户端可使用spark2.6.3,这个版本是目前最新的release版本,经过测试发现上一版本在视频

u011970711的专栏 963

基于xmpp openfire smack开发之openfire介绍和部署[1] .

本文转载http://blog.youkuaiyun.com/shimiso 前言 Java领域的即时通信的解决方案可以考虑openfire+spark+smack。当然也有其他的选择。 Openfire是基于Jabber协议(XMPP)实现的即时通信服务器端版本,目前建议使用3.8.1版本,这个版本是当前最新的版本,而且网上可以找到下载的源代码。 即时通信客户端可使用spark2.6.3,这个版本是...

Donny的专栏 910
上一篇: XMPP协议的原理介绍
下一篇: 百万用户时尚分享网站feed系统扩展实践
dodott
博客等级 码龄22年 60粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值