spark+openfire 源代码部署
openfire源码分析
openfire源码分析启动流程Socket接⼝Socket通信使⽤Mina框架实现,是XMPP协议的处理⼊⼝,具体为:消息接收后由不同的节处理器处理:StanzaHandler基础消息类型,之后进⾏消息路由:最后通过路由表进⾏路由:Http接⼝Http接⼝⽤于Web端的管理以及Web客户端的通信,使⽤jetty实现。
通过XMPServer启动ConectionManager来管理链接启动,包括SSL,HTTP,TCP等。
消息处理流程消息发送消息的发送通过NIOConnection.deliver(Packet packet)实现。
模块功能列表启动模块RoutingTableImpl/*** Routing table that stores routes to client sessions, outgoing server sessions* and components. As soon as a user authenticates with the server its client session* will be added to the routing table. Whenever the client session becomes available* or unavailable the routing table will be updated too.<p>** When running inside of a cluster the routing table will also keep references to routes* hosted in other cluster nodes. A {@link RemotePacketRouter} will be use to route packets* to routes hosted in other cluster nodes.<p>** Failure to route a packet will end up sending {@link IQRouter#routingFailed(JID, Packet)},* {@link MessageRouter#routingFailed(JID, Packet)} or {@link PresenceRouter#routingFailed(JID, Packet)} * depending on the packet type that tried to be sent.** @author Gaston Dombiak*/AuditManager/*** Manages and directs server message auditing behavior. Turning on* all auditing options can produce copious amounts of data and* significantly slow the server as it saves the data to persistent storage.<p>** Auditing currently saves audit data to a raw XML file* which can later be processed and mined for information.** @author Iain Shigeoka*/RostManager/*** A simple service that allows components to retrieve a roster based solely on the ID * of the owner. Users have convenience methods for obtaining a roster associated with * the owner. However there are many components that need to retrieve the roster* based solely on the generic ID owner key. This interface defines a service that can * do that. This allows classes that generically manage resource for resource owners * (such as presence updates) to generically offer their services without knowing or* caring if the roster owner is a user, chatbot, etc.** @author Iain Shigeoka*/PluginManager/*** Loads and manages plugins. The <tt>plugins</tt> directory is monitored for any* new plugins, and they are dynamically loaded.** <p>An instance of this class can be obtained using:</p>** <tt>XMPPServer.getInstance().getPluginManager()</tt>** @author Matt Tucker* @see Plugin* @see org.jivesoftware.openfire.XMPPServer#getPluginManager()*/核⼼模块PresenceManagerImpl/*** The presence manager tracks on a global basis who's online. The presence* monitor watches and reports on what users are present on the server, and* in other jabber domains that it knows about. The presence manager does* not know about invisible users (they are invisible).** @author Iain Shigeoka*/SessionManager/*** Manages the sessions associated with an account. The information* maintained by the Session manager is entirely transient and does* not need to be preserved between server restarts.** @author Derek DeMoro*/PacketRouterImpl/*** A router that handles incoming packets. Packets will be routed to their* corresponding handler. A router is much like a forwarded with some logic* to figute out who is the target for each packet.** @author Gaston Dombiak*/IQRouter/*** Routes iq packets throughout the server. Routing is based on the recipient* and sender addresses. The typical packet will often be routed twice, once* from the sender to some internal server component for handling or processing, * and then back to the router to be delivered to it's final destination.** @author Iain Shigeoka*/MessageRouter/*** <p>Route message packets throughout the server.</p>* <p>Routing is based on the recipient and sender addresses. The typical* packet will often be routed twice, once from the sender to some internal* server component for handling or processing, and then back to the router* to be delivered to it's final destination.</p>** @author Iain Shigeoka*/PresenceRouter/*** <p>Route presence packets throughout the server.</p>* <p>Routing is based on the recipient and sender addresses. The typical* packet will often be routed twice, once from the sender to some internal* server component for handling or processing, and then back to the router* to be delivered to it's final destination.</p>** @author Iain Shigeoka*/MulticastRouter将⼀个包路由到多个⽬的地址,包括远程地址,但只获取深度为1的地址。
openfire插件编译及部署
Openfire插件编译及部署插件编译1、编译参数配置打开eclipse或者Myeclipse,点击菜单栏里的run选项,在其下拉菜单中选择External Tools按钮,在它的下一级菜单中点击External Tools Configuration即可进入配置页面。
如图1所示。
图1图2所示为配置页面。
图2选择左侧导航栏中的Ant Build选项,点击新建按钮来新建一个编译配置。
如图3所示。
图3接下来就可以来配置插件的编译参数了。
首先,在Name框中为该编制配置项命名以示区别,如图4所示:图4其次,打开Main选项卡,点击在Buildfile框下面Browse Workspace按钮,来选择用来编译插件的Build文件,它的目录是openfire/build/build.xml。
如图5所示。
图5完成后框内显示数据为“${workspace_loc:/openfire/build/build.xml}”,如图6所示。
图6再填写Arguments框,内容格式为“-Dplugin=XXXX”,其中“XXXX”是我们要编译的插件名。
完成后如图7所示。
图7打开Targets勾选plugin,若编译所有插件就勾选plugins,完成后如图8所示。
图8再打开Common选项卡,设置编译的编码格式一般为UTF_8格式。
完成后如图9所示。
图9最后点击按钮保存设置,点击就可对插件进行编译。
2、检查编译结果当控制台出现编译成功的结果时,即代表编译已经完成,如图10所示。
图10在openfire/target/plugins目录,出现对应的插件jar文件,就代表编译成功了!如图11所示。
图11最后,将编译好的插件jar文件复制出来,以备上传导服务器。
插件部署首先,访问openfire服务器的管理控制台,URL是http://服务器IP:9090。
输入管理员用户名和密码。
如图12所示。
图12登录进入后,选择“插件”网页中机会显示服务器目前所安装的所有插件,如图13所示。
openfire环境搭建
Openfire环境搭建Linux:ubuntu 12.10Win:Windows 7版本:Openfire 3.9.1 Spark 2.6.3 Java统一使用6u45这个版本1Openfire服务器部署(非源码)1.1 Win下:1、安装jdk2、在openfire官网igniterealtime中下载win版的openfire,下载完成后,如果你下载的是exe文件,执行你的安装文件,进行安装。
这里我是zip的文件。
解压后,复制openfire目录到C:\Program Files\目录下;一定要在C:\Program Files\目录下的;这样openfire就安装完成了。
3、启动openfire服务器,并配置它。
在C:\Program Files\openfire\bin目录下有一个电灯泡的openfire.exe文件,双击执行,启动完成后可以看到4、点击Launch Admin按钮进入http://127.0.0.1:9090/setup/index.jsp页面,配置openfire服务器5、后面是选择语言,配置服务器域名。
选择数据库,这里可以选择openfire自带的数据库,即嵌入的数据库。
选择特性配置,默认即可。
管理员邮件,可跳过。
完成安装。
6、进入http://127.0.0.1:9090/login.jsp页面后,输入admin、密码admin登陆进入7、进入后可以看到:1.2 Ubuntu下:1、先去甲骨文官网下载安装jdk(选择Linux x64 或者Linux x86对应链接,注意不要选择rpm.bin的,选择.bin,6u45对应的是jdk-6u45-linux-i586.bin),也不要使用ubuntu自带的openjdk2、安装全程需要root权限,首先获取root权限sudo –s5、然后就是要告诉系统,我们使用的sun的JDK,而非OpenJDK了(注意下面的2行命令--install后面一共四个参数分别是链接名称路径优先级,我们只要修改对应的6、openfire官网下载Linux版的openfire:openfire_3.9.1_all.deb(这个直接双击通过ubuntu软件中心安装),经过以上软件已经完成安装,此时需要修改一下openfire的启动文件如果openfire没有启动,可以通过/etc/init.d/openfire start启动服务。
【原创】spark源代码部署及编译生成
Erin和你一起学openfire(1)——spark源码部署及编译生成作者:Erin@SSE@HUST联系方式:1024265190@本文适合于有一定JAVA开发基础的同学看,如果你尚不会配置JDK、尚不会myeclipse的基本操作,你应该先学会了这两项之后再来。
其实也不是太难,baidu几篇文章看看,网上介绍一大堆。
好的,下面开始给大家讲解spark源代码部署及编译生成。
默认大家已经在自己的机子上装好了myeclipse,因为后边的才是重头戏,着重要讲的是后边一部分。
一、SVN下载spark源代码目前为止,官网上只提供SVN方式的下载。
所以我们只好下载了SVN工具(如Tortoise SVN)之后再下载源码。
1)在自己电脑上新建一个用来存放源码的文件夹,如E:\spark。
2)在E:\apark右键,然后选择【SVN checkout…】,弹出如下图所示的对话框。
填入spark的SVN地址,即在【URL of repository】栏填入/svn/repos/spark/trunk,然后点击【OK】按钮。
3)等待半小时左右,下载完毕。
可以看到我们本机上的文件夹下:备注:当然,如果你不想用SVN方式下载的话,可以给我发邮件1024265190@,我可以把已经下载好的原版代码发到你的邮箱。
嘿嘿~共同学习。
二、创建spark项目1)在Myeclipse 6.6中new一个Java Project,命名为spark,如下图:2)然后点”NEXT>”,需要改一下默认的项目设置。
将下图中的Default output folder修改一下:这是因为Myeclipse和ant用不同的方式编译源代码造成的,myeclipse一般将编译生成的.class放在bin文件夹中,而ant一般将.class文件放在target文件夹中。
我们后边会用ant将工程build,但是我们run的时候用的是myeclipse,myeclipse会在上图设置的Default output folder中去寻找.class文件。
openfire源代码研究
Openfire源码研究Openfire源码目录结构1.build目录:build目录下收录的是生成安装文件(例如:rpm)所要的一些文件,例如JRE等。
2.resources目录:resources目录下收录的是一些为实现国际化(i18n)和本地化的一些编码文件(例如:英文,中文,法文,德文等)。
3.documentation目录:documentation目录下收录的是一些关于Openfire安装和配置的信息,但最终要的是这里有Openfire开发的Javadoc。
4.src目录:顾名思义这个src文件夹就是我们想要的Openfire源代码了,这下面又有许多文件夹,我们只要Java文件夹就好,这里面实现的Openfire的核心功能,通过它就可以调试Openfire了。
命名规则Openfire中常见的类名后缀命名包括Starter、Plugin、Listener、Dispatcher、Handler、Manager、Provider,通常情况下,这些命名类包括如下意义:XXStarter系统启动类,如org.jivesoftware.openfire.starter.ServerStarter,调用其start()方法可启动系统应用。
XXListener业务的最终处理类。
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()方法。
Openfire_spark_安装手册
Openfire+Spark安装手册王保政QQ:29803446Msn:baozhengw999@关键字:快速开发平台openjweb 增删改查即时通信2009-8-29目录第一章JA VA领域的IM解决方案 (3)第二章安装OPENFIRE3.6.4 (3)2.1配置机器的域名 (3)2.2安装OPENFIRE (3)2.2.1 安装 (3)2.2.2 运行数据库脚本 (4)2.2.3 数据库驱动jar包 (6)2.2.4 openfire初始化配置 (6)2.3设置用户 (12)第三章安装SPARK客户端 (13)第四章配置MSN网关 (15)4.1服务端配置MSN网关 (15)第五章RED5视频配置 (18)5.1部署RED5.WAR (18)5.2 SPARK客户端配置视频插件 (19)第六章使用SMACK开发即时通信功能 (22)第一章Java领域的IM解决方案Java领域的即时通信的解决方案可以考虑openfire+spark+smack。
当然也有其他的选择。
Openfire是基于Jabber协议(XMPP)实现的即时通信服务器端版本,目前建议使用3.6.4版本,这个版本是当前最新的版本,而且网上可以找到下载的源代码。
即时通信客户端可使用spark2.5.8,这个版本是目前最新的release版本,经过测试发现上一版本在视频支持,msn网关支持上可能有问题,所以选择openfire3.6.4+spark2.5.8是最合适的选择。
Smack是即时通信客户端编程库,目前我已测通通过jsp使用smack的API向openfire 注册用户发送消息,并且可以通过监听器获得此用户的应答消息。
通过smack向msn用户和QQ用户,gtalk用户发送消息应该也可以实现,关于向gtalk 用户发送消息的例子较多。
这个留待以后研究。
至少目前可以通过程序向spark发消息了。
对于局域网内部应用足以解决系统与用户交互的问题,甚至可以做自动应答机器人。
openfirespark二次开发服务插件
openfirespark二次开发服务插件==================== 废话begin============================最近老大让我为研发平台增加即时通讯功能。
告诉我用comet 在web端实现即时通讯。
最初狂搜集资料。
不能让自己方向错了。
这是很重要的。
不过还是难免的周折了一番。
测试了一个comet4j的聊天小例子。
用它前后端开发成本太大、对服务器也太大压力放弃了。
最终决定使用openfire +jsjac.js + JabberHTTPBind 然后实现老大要求的web 及时通讯功能。
很庆幸找到了hoojo大哥的demo 很不幸,他为了让大家复制代码,自己练习。
不提供jar包js下载。
(虽然好心但是足足浪费了我两天时间)一个jsjac.js库版本有问题。
很费劲的看源码。
哎。
然后、拿这个小demo 先交差。
顺便展示了spark 和web 聊天窗口,交互即时聊天。
顺便构想了一下,修改openfire用户表。
让用户来自系统。
组织则用自带的。
(当然这是预想。
其实openfire已经帮我们想过了。
)接着、全局搜索了openfire源码中包含ofuser表sql的类。
只有两个类。
很庆幸。
改了之后,改造用户密码加密认证方式。
当然这样做是错误的。
直到我发现类名字似乎有些不对的时候。
DefaultUserProvider 哈哈、嘲讽啊。
不出所料有一个实现类JDBCUuserProvider 。
直接配置就可以搞定、但是加密sha256加密过程和我平台不一样。
改造后就顺利搞定。
接着、到了插件开发过程。
这个过程很烦人。
网上很多帖子很多人去讲这个开发过程。
或许是两三年前的贴了。
很多过时了。
只能有一点帮助。
更多的是走向了错误的道路。
磕磕碰碰。
最终还是只能从源码中寻求出路。
这个过程整整浪费了我两星期时间。
很痛苦。
所以。
我会针对最新代码聊聊,spark 开发一个组织架构树插件。
展示出用户。
并可以与之聊天。
openfire编译和运行
Openfire源码部署以及编译运行一、Openfire源码下载1)可以去官方网站:官网地址/projects/openfire/。
2)也可以利用eclispe自带的SVN插件导入,再次就过多介绍,官网上写的很清楚。
二、源码部署编译将源码解压到硬盘上。
如图:建立一个Java Project,并且项目名称一定要写成“Openfire”,否则会出错。
选中Create project from existing source项;在Directory中输入源码的路径(此值与第一个图的地址是相同的)具体操作如下图源码导入之后如下图所示,此时openfire是不可以运行的,还需要编译和配置。
1)接下来进行服务器编译配置,点击图标下拉菜单,选择“External ToolsConfigration”选项。
如下图:编译配置项命名,再次我就命名为openfire,也可以自己随意填写。
译代码的文件,他是一个叫做build.xml的配置文件。
如下图所示:果再选择“Targets”选项卡,勾选openfire选项然后选择“Common”选项卡,勾选“External Tools”,这样在以后编译时就不需要重复配置了,还要选择好适当的编码格式,一般情况下选择“UTF-8”,最点击“Apply”和run来运行编译程序。
等待最后控制台出现编译成功字样,编译就完成了。
如图:注意:有时候控制台再出现“BUILD SUCCRSSFUL”还会出现“警告”、“错误”等字样。
对“警告”我们可以忽视,但是对于出现的“错误”,我们要及时修改,一般的错误就是找不到类或方法和汉字乱码,这时你要看看他所需要的jar包是否齐全,某些java文件是否与编译是设置的一至。
三、Openfire运行配置点击运行按钮下拉菜单选择“Run Configration”进入如下页面:在“Main”选项卡的的“Probject”中,选择当前项目,如图:这个是整个openfire服务器的总入口,负责启动openfire服务器。
Openfire+Spark+Spark Web安装配置
Openfire+Spark+Spark Web安装配置一.安装环境操作系统:Windows XP Prefessional SP2服务器软件:Openfire 3.4.2Openfire Enterprise 3.4.2客户端软件:Spark 2.5.7Spark Fastpath Webchat 3.4.1JDK:J2SE 5.0 (1.5.0_03)二.安装Jabber服务器软件2.1 软件下载Jabber官网地址:/常用Jabber服务器软件:/software/servers.shtml本文以Openfire(Wildfire)为服务器,一款基于GPL协议开源软件,支持各种操作系统,软件需要java环境支持,不过软件本身自带了环境包,你可以根据你的需要下载不同的版本。
下载地址:/downloads/index.jsp#openfire Windows无java环境版本地址:/downloadServlet?filename=openfire/openfire_3_4_ 2.zip最新版本:Openfire 3.4.22.2Windows版本安装将openfire_3_2_2.zip解压缩到D:\。
特别要注意,openfire的全路径中不能有中文字符,最好主机名也是标准点的英文名称。
直接运行安装文件,D:\Openfire\bin\openfire.exe2.3openfire服务器配置浏览器地址栏中输入http://localhost:9090/即可开始即时通讯服务器配置。
(1)语言选择:中文简体(2)服务器设置:选择域及端口,建议默认(3)数据库设置:选“标准数据库”(4)标准数据库设置:将oracle驱动放在openfire的lib目录下。
在数据库驱动选项栏选择Oracle。
数据库URL填入你的数据库地址,端口和数据库名称,以及用户名和密码(需要在安装前创建),最大连接数,最小连接数和连接超时时间可自行调整。
openfire开发环境搭建
说明: 开发环境(IDE):openfire -3.7.1 +
eclipse-4.2.0
+
jdk-1.7
1. 将 openfire 的源文件拷到 Eclipse 的工作空间中,以源文件名称创建 openfire 的 java 项目
2. 项目有错误是因为 jar 包没有加进来,右键点击项目选择 Properties,java build path-->Libraries 选 卡,Add Jars,选择 openfire 项目 build/lib 下所有的 jar 包,添加
1
3. 此时 project 有错误,下载三个 jar 包:coherence.jar,coherence-work.jar,tangosol.jar,保存在任意文 件夹 4. 在 eclipse 的 Package Explorer 中选中前面建立的 project,右键—>Properties-->java build path-->Libraries 选卡, Add External Jars,选中下载的三个包,完成 5. 此时仍旧有错。源代码中部分 class 继承自 abstract 类,但 abstract 方法没有全部实现,需手动改 正 6. 复制 src/i18n/openfire_i18n_en.properties 和 src/resources/jar/admin-sidebar.xml 两个文件,到项目 下的 bin 目录。 7. 开始用 ant 编译源文件。切换到 ant 视图:菜单栏 ->show view->ant 8. 在 ant 中选 add buildfiles 按钮,在 project 中选 build/build.xml,然后用 ant 编译,直 到编译成功 如果编译出错,是因为 ant 版本不对(太高了)。在 build.xml 中找到下面语段
openfire+spark+s...
openfire+spark+s...openfire+spark+smack 即时通讯(问题篇一)离线消息获取不到,openfiresmack即时通信功能已经开发完毕,现在还木有时间整理,打算后期抽时间整理后发一下源码跟教程。
现在记录一下遇到的问题,首先是获取离线消息。
OfflineMessageManager是官方获取离线消息的,但是直接获取,是获取不到任何消息的,需要先设置离线,然后获取后,再上线。
功能代码如下。
1、离线// 初始化public XMPPConnection init(LoginConfig loginConfig) {Connection.DEBUG_ENABLED = false;ProviderManager pm = ProviderManager.getInstance();configure(pm);connectionConfig = new ConnectionConfiguration(loginConfig.getXmppHost(), loginConfig.getXmppPort(),loginConfig.getXmppServiceName());connectionConfig.setSASLAuthenticationEnabled(false);// 不使用SASL验证,设置为falseconnectionConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.e nabled);// 允许自动连接connectionConfig.setReconnectionAllowed(false);connectionConfig.setSendPresence(false);// 设置离线// 收到好友邀请后manual表示需要经过同意,accept_all表示不经同意自动为好友Roster.setDefaultSubscriptionMode(Roster.SubscriptionMod e.manual);connection = new XMPPConnection(connectionConfig);return connection;}2、获取消息OfflineMessageManager offlineManager = new OfflineMessageManager(connection);try {Log.i("离线消息数量: ", "" + offlineManager.getMessageCount());Iterator<org.jivesoftware.smack.packet.Message> it = offlineManager.getMessages();while (it.hasNext()) {org.jivesoftware.smack.packet.Message message = it.next();Log.i("收到离线消息", "Received from 【" + message.getFrom()+ "】 message: " + message.getBody());if (message != null && message.getBody() != null&& !message.getBody().equals("null")) {IMMessage msg = new IMMessage();String time = (String) message.getProperty(IMMessage.KEY_TIME);msg.setTime(time == null ? DateUtil.getCurDateStr() : time);msg.setContent(message.getBody());if (Message.Type.error == message.getType()) {msg.setType(IMMessage.ERROR);} else {msg.setType(IMMessage.SUCCESS);}String from = message.getFrom().split("/")[0];msg.setFromSubJid(from);// 生成通知NoticeManager noticeManager = NoticeManager.getInstance(context);Notice notice = new Notice();notice.setTitle("新信息");notice.setNoticeType(Notice.CHAT_MSG);notice.setContent(message.getBody());notice.setFrom(from);notice.setStatus(Notice.UNREAD);notice.setNoticeTime(time == null ? DateUtil.getCurDateStr() : time);// 历史记录IMMessage newMessage = new IMMessage(); newMessage.setMsgType(0);newMessage.setFromSubJid(from);newMessage.setContent(message.getBody()); newMessage.setTime(time == null ? DateUtil.getCurDateStr() : time);MessageManager.getInstance(context).saveIMMessage( newMessage);long noticeId = noticeManager.saveNotice(notice);if (noticeId != -1) {Intent intent = new Intent(Constant.NEW_MESSAGE_ACTION);intent.putExtra(IMMessage.IMMESSAGE_KEY, msg);intent.putExtra("noticeId", noticeId);context.sendBroadcast(intent);activitySupport.setNotiType(R.drawable.ic_launcher,context.getResources().getString(R.string.new_message),notice.getContent(), ChatActivity.class, from);}}}offlineManager.deleteMessages();// 通知服务器删除离线消息} catch (Exception e) {e.printStackTrace();}3、设置上线:Presence presence = new Presence(Presence.Type.available);connection.sendPacket(presence);spark,openfire老师一名,真心教能否具体到问题,比如你在搭建即时通信平台时遇到了什么麻烦?!假如没有问题,从头学的话,我建议你去spark官方读文档,下代码,看样例。
openfire+sparkweb在线聊天
openfire+sparkweb在线聊天其中openfire为最为关键的点,但搭建相对来说还是比较简单的网站上有很对例子。
我就简要的说明下吧。
(我是在linux下搭建的openfire)openfire的搭建1.下载地址为:2.在linux端需要解压解压命令为:tar -xzvf openfire_3_8_2.tar.gz3.解压后就可以直接启动 (openfire/bin/openfire start)4.配置管理页面(搭建中,难点在于这里),管理页面为http://域名或ip:9090.如我在ip为192.168.8.2上搭建了openfire那么访问的管理配置页面就应该为:http://192.168.8.2:9090在初始设置中,其中有两个注意点说明下:(1).数据库设置,分为标准数据库连接和嵌入的数据库两种方式,其中"嵌入的数据库"为内置数据,无需过多的设置."标准数据库连接" 是指外置数据库,在数据库中注意应该创建一个名为openfire的database然后在该database中导入解压后的sql(目录为) openfire/resources/database/ openfire_mysql.sql .我建议使用标准数据库连接,方便二次开发和功能扩展(2).在"管理员账户"中的设置就是你以后登录管理配置页面的帐号和密码5.测试,需要在官网下spark() 如果你能创建用户就基本可以说明你openfire搭建成功了sparkweb相关吐槽一番,在网站上有很多资料都有说到red5.war这个字眼,但是当我下载这个war包的时候,总是不对,没错.少了一个文件.下载我自己打了一个war包供大家下载,不过需要大家提供点分数。
下载地址:/detail/shendixiong/6380643在上面的地址中下载了一个red5.war文件,然后将该文件放入到tomcat下的webapps下.启动tomcat 就会自动解压war .也就多了一个red5的目录!如果没有就证明失败了!如下图:然后就可以我访问为:就好了。
openfire源码部署开发
一.Openfire源码布署与打包【转载】/779468/1579422009-05-14 16:33:27标签:源码Openfire打包[推送到技术圈]版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明。
否则将追究法律责任。
/779468/157942今天心血来潮下载了Openfire的最新源码3.6.4重新布署,结果失败。
折腾了几十分钟才搞定,于是记录此过一)准备工作开发工具:MyEclipse 6.6源码下载:官网地址/projects/openfire/,偶下的3.6.4。
二)解压源码将源码解压到硬盘上。
如图:三)创建工程1、启动MyEclipse2、[File]-->[Switch Workspace]-->[Other...]3、在Workspace输入框中选择先前源码的解压路径。
如图(注意此处与上图的区别):4、MyEclipse重启后新建一个Java Project5、在对话框的Project name中输入工程名;选中Create project from existing source项;在Direc 路径(此值与第一个图的地址是相同的)。
如图:6、点击Finish,MyEclipse会将源码列出。
如图:四)编译1、[Window]-->[Show View]-->[Ant]2、在Ant视窗中点右键,选择[Add Buildfiles...]。
如图3、在打开的对话框中选择Openfire/build/build.xml后点[OK]按钮。
如图:4、展开Openfire XMPP Server树,在openfire上点键;[Run As]-->[Ant Build]开始编译。
如图:编译完成后会在Console视窗中提示BUILD SUCCESSFUL表示openfire编译成功。
5、按上面相同的方法编译plugins。
sparkopenfireconference修改使群组编程持久的。类似qq群(1)糊涂虫
sparkopenfireconference修改使群组编程持久的。
类似qq群(1)糊涂虫conference spark默认的是临时的,就是用户点击后才能加入到群组里面,关闭后从群组里退出。
要修改spark的这个功能,提供以下思路(原创)一、spark用户在登陆的时候,在openfire 进行SessionEventListener,通过插件的形式进行监听,在sessionCreated的时候进行,登陆用户的joinRoom ,从数据库取出他所在的groupname 然后进行joinroom。
作法; 在openfire写一个插件,插件主要代码如下:private JID serverAddress;privateJoinGroupsSessionEventListener listener =new JoinGroupsSessionEventListener();private XMPPServer server;private MultiUserChatServiceImplmucService;private classJoinGroupsSessionEventListenerimplements SessionEventListener {public void sessionCreated(Sessionsession) {System.out.println("a client connect!");JID userJid=session.getAddress();JoinGroups(userJid);}public void sessionDestroyed(Session session) {//ignoreJID userJid=session.getAddress();LeaveGroups(userJid);}public void resourceBound(Session session) {// Do nothing.}public void anonymousSessionCreated(Session session) {//ignore}public void anonymousSessionDestroyed(Session session) {//ignore}}@Overridepublic void initializePlugin(PluginManager manager, File pluginDirectory) {// TODO Auto-generated method stubserver=XMPPServer.getInstance();//mucService=server.getMultiUserCh atManager().getMultiUserChatService(ser) serverAddress = new JID(XMPPServer.getInstance().getServerIn fo().getXMPPDomain());SessionEventDispatcher.addListener(li stener);System.out.println("join groups plugin is running!");}public void LeaveGroups(JID userJid) { System.out.println(userJid.toBareJID() +" is leaving the room!");List<String>roomIds=MUCPersistenceManager.getRo omIDsByUserJid(userJid.toBareJID());for(String roomId:roomIds){System.out.println("roomid:"+roomId);org.jivesoftware.openfire.muc.spi.Roo mInforminf=MUCPersistenceManager.getRoomInfoByRoomId(roomId);String serviceID=rminf.getServiceID();mucService=(MultiUserChatServiceIm pl)server.getMultiUserChatManager().get MultiUserChatService(Long.parseLong(rm inf.getServiceID()));System.out.println("serviceid:"+serviceID);String roomName=rminf.getName();System.out.println("room name:"+roomName);LocalMUCRoomroom=(LocalMUCRoom)mucService.getC hatRoom(roomName);//从数据库中查询他的姓名作为昵称(得自己实现)String nickname = MUCPersistenceManager.getNickNameBy JId(userJid.toBareJID());if(nickname == null){if(userJid.getNode() != null){nickname = userJid.getNode();}else{nickname = userJid.getResource();}}// The user leaves the room 用户离开群try {if(!room.hasOccupant(nickname))return;LocalMUCRole role=(LocalMUCRole) room.getOccupant(nickname);room.leaveRoom(role);System.out.println("leaved!");} catch (UserNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void JoinGroups(JID userJid) {System.out.println(userJid.toBareJID() +" is joining the room!");try{List<String>roomIds=MUCPersistenceManager.getRoomIDsByUserJid(userJid.toBareJID());for(String roomId:roomIds){System.out.println("roomid:"+roomId);org.jivesoftware.openfire.muc.spi.Roo mInforminf=MUCPersistenceManager.getRoom InfoByRoomId(roomId);String serviceID=rminf.getServiceID();mucService=(MultiUserChatServiceIm pl)server.getMultiUserChatManager().get MultiUserChatService(Long.parseLong(rm inf.getServiceID()));System.out.println("serviceid:"+serviceID);String roomName=rminf.getName();System.out.println("room name:"+roomName);LocalMUCRoomroom=(LocalMUCRoom)mucService.getC hatRoom(roomName);//从数据库中查询他的姓名作为昵称(得自己实现)String nickname = MUCPersistenceManager.getNickNameBy JId(userJid.toBareJID());if(nickname == null){if(userJid.getNode() != null){nickname = userJid.getNode();}else{nickname = userJid.getResource();}}HistoryRequest historyRequest = null;String password = null;//构建成员进入群的PresencePresence presence = new Presence();presence.setTo(room.getJID().toBareJI D() + "/" + nickname);presence.setFrom(userJid);PacketExtension extension = new PacketExtension("x", "");presence.addExtension(extension);PacketRouterpr=server.getPacketRouter();LocalMUCUser user=new LocalMUCUser(mucService, pr, userJid);// The user joins the room 用户进入群try {LocalMUCRole role = room.joinRoom(nickname,password,historyRequest,user,presence);System.out.println("joined!");user.addRole(roomName, role);} catch (UnauthorizedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UserAlreadyExistsException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (RoomLockedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ForbiddenException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (RegistrationRequiredException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ConflictException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ServiceUnavailableException e){// TODO Auto-generated catch blocke.printStackTrace();} catch (NotAcceptableException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}catch(Exception e){e.printStackTrace();}}@Overridepublic void destroyPlugin() {// TODO Auto-generated method stubSessionEventDispatcher.removeListen er(listener);listener = null;serverAddress = null;server=null;mucService=null;}在MUCPersistenceManager 这个类里添加如下方法,用于上面的使用// 石坚 20120609public static List<String> getRoomIDsByUserJid(String userJid) { Connection con = null;PreparedStatement pstmt = null;ResultSet rs = null;List<String> roomIDs=new ArrayList<String>();try {con = DbConnectionManager.getConnection();pstmt = con.prepareStatement(LOAD_ROOMIDS_B Y_JID);pstmt.setString(1, userJid);rs = pstmt.executeQuery();while(rs.next()) {String roomId = rs.getString("roomID");roomIDs.add(roomId);}}catch (SQLException sqle) {Log.error(sqle.getMessage(), sqle);}finally {DbConnectionManager.closeConnecti on(rs, pstmt, con);}return roomIDs;}public static String getRoomNameByRoomId(String roomId) { Connection con = null;PreparedStatement pstmt = null;ResultSet rs = null;String roomName=null;try {con = DbConnectionManager.getConnection();pstmt = con.prepareStatement(LOAD_ROOMNAM E_BY_ROOMID);pstmt.setString(1, roomId);rs = pstmt.executeQuery();if(rs.next()) {roomName= rs.getString("name");}}catch (SQLException sqle) {Log.error(sqle.getMessage(), sqle);}finally {DbConnectionManager.closeConnecti on(rs, pstmt, con);}}public static String getServiceIdByRoomId(String roomId) { Connection con = null;PreparedStatement pstmt = null;ResultSet rs = null;String serviceID=null;try {con = DbConnectionManager.getConnection();pstmt = con.prepareStatement(LOAD_SERVICEID_ BY_ROOMID);pstmt.setString(1, roomId);rs = pstmt.executeQuery();if(rs.next()) {serviceID= rs.getString("serviceID");}}catch (SQLException sqle) {Log.error(sqle.getMessage(), sqle);}finally {DbConnectionManager.closeConnecti on(rs, pstmt, con);}}public static String getNickNameByJId(String userJid) {Connection con = null;PreparedStatement pstmt = null;ResultSet rs = null;String nick=null;try {con = DbConnectionManager.getConnection();pstmt = con.prepareStatement(LOAD_NICKNAME_ BY_JID);pstmt.setString(1, userJid);rs = pstmt.executeQuery();if(rs.next()) {nick= rs.getString("nickname");}}catch (SQLException sqle) {Log.error(sqle.getMessage(), sqle);}finally {DbConnectionManager.closeConnecti on(rs, pstmt, con);}return nick;}public static RoomInfo getRoomInfoByRoomId(String roomId) { Connection con = null;PreparedStatement pstmt = null;ResultSet rs = null;RoomInfo rminf=null;try {con = DbConnectionManager.getConnection();pstmt = con.prepareStatement(LOAD_ROOMINFO _BY_ROOMID);pstmt.setString(1, roomId);rs = pstmt.executeQuery();if(rs.next()) {String serviceID= rs.getString("serviceID");String name= rs.getString("name");String naturalName= rs.getString("naturalName");Stringdescription=rs.getString("description");rminf=new RoomInfo(serviceID, name, naturalName, description);}}catch (SQLException sqle) {Log.error(sqle.getMessage(), sqle);}finally {DbConnectionManager.closeConnecti on(rs, pstmt, con);}return rminf;}public static List<String> getMembersByRoomId(String roomId) { // TODO Auto-generated method stubList<String> members=new ArrayList<String>();Connection con = null;PreparedStatement pstmt = null;ResultSet rs = null;try {con = DbConnectionManager.getConnection();pstmt = con.prepareStatement(LOAD_JIDS_BY_RO OMID);pstmt.setString(1, roomId);rs = pstmt.executeQuery();while(rs.next()) {String jid= rs.getString("jid");members.add(jid);}}catch (SQLException sqle) {Log.error(sqle.getMessage(), sqle);}finally {DbConnectionManager.closeConnection(rs, pstmt, con);}return members;}// end二、用户登陆了群,在进行打开chatroom的时候,spark默认的是显示的在线的用户,要进行修改。
openfire源码部署心得
一.部署1解压openfire源码放到workspace下.建立一个java project,名字与解压后源码文件夹名字一样,这样就可以把openfire源码导入到eclipse中2.使用ant进行编译。
在openfire项目导入进来之后,点击Window -> Show View -> Ant然后就会显示出Ant的窗口,在Ant 视图中,单击右键,在弹出的快捷菜单中选择Add Buildfiles在弹出的对话框中,展开openfire_src/build文件夹,选择build目录下的build.xml接下来双击执行openfire[default] (带一个三角符号的那个)在控制台中显示“BUILD SUCCESSFUL” 那么就表示编译成功,3.设置启动项目点击openfire_src项目,在菜单栏中选择Run->Open Run Dialog (Or Run->Run Configurations)弹出一个对话框,在左侧菜单中右键点击Java Application,选择New创建启动配置在Run窗口的Main选项卡中, 修改最上面Name文本框中的值,改成包含要启动的类的工程名openfire_src(没什么用,就是一个标识,随便起名字。
)在Run窗口的Main选项卡中,project框中填写:openfire_srcMain class 填写:org.jivesoftware.openfire.starter.ServerStarter点击Apply应用。
点击进入Arguments选项卡,在上面那个框(VM arguments:)中填写-DopenfireHome="${workspace_loc:openfire_src}/target/openfire"其中${workspace_loc:openfire_src} 中的 openfire_src 要根据你的项目名来进行同步修改。
Openfire+Spark
Openfire服务器的优点:
1、内部集成web服务器,可用于设计web管 理程序 2、插件机制,方便扩展 3、单台服务器就可大容量支持上万用户 4、安装和使用都非常简单
Spark客户端的介绍
Spark也是一个开源,跨平台IM客户端。 它的特性支持聊天,语音,视频,会议, 文件收发,截屏,连接msn等功能和强大安 全性能。 如果企业内部部署IM使用 Openfire+Spark是最佳的组合。 Spark 的核心则是Smack 。
数据库端
在数据库中建立一些用户的基本信息,如个人资料、邮箱等。
客户端程序
客户端程序基于Eclipse平台进行开发,界面的设计用 SWT来实现,借助于开源Smack的API运用Java语言实现 体的功能。 客户端主要功能是,提供友好的用户操作界面并显示系统 处理结果。客户端需要根据用户的要求,向服务器发送各种类 型的请求,然后等待服务器的响应。具体功能如下: 用户管理登录、注销、使用者本人的个人信息及好友的个 人信息管理等。 通信功能点对点文字通信、群组文字通信及密码管理、语 音呼叫、视频连接等。 文件管理文件传送、数字签名加密等。 其他动态广告等。
及时通讯系统
该系统是基于XMPP协议和Openfire的开发。 客户端与客户端之间的信息传递则必须要 经过服务端。 服务器则直接与数据库连接 机构如图:
系统功能及其实现
服务器端程序
服务器端采用Openfire进行业务处理。 运行的流程为:服务器运行后,开启服务,服务器开始侦听 用户请求。如有信息发送过来,首先,返回确认信息,然后,建立 一个线程,处理接收到的数据。在线程里,按照接收到数据的类 别,进行相应的处理,如有需要,向用户发送所处理的结果(成功 或失败的消息),处理后,线程就束了。采用这样的流程,可以 实时接受每个用户的请求,不会因为处理一个用户的请求,而 忽略了其他用户。
Openfire集群部署不完全手册
Openfire集群部署不完全手册在csdn和javaeye阅读了无数的技术博客,每一篇都让本人受益匪浅,当然时间久了,很多也都忘了,呵呵。
于是从现在开始自己也尝试着写技术博客,把自己工作与生活遇到的点滴分享给大家,也希望大家阅读了我的博客也能有点滴的收获,那都是对本人最大的鼓励,哈哈!第一次写技术博客,其实不知从何入手,果然如我所想,想把一件技术事件表述清楚是一件很困难的事情。
作为典型的码奴,性格孤僻、不善言辞、老实吧唧一直是我们的通病,但其实很多码奴都怀抱着Coding Changes the World的梦想;可惜在天朝,很多人包括本人,暂时也只能把Coding做为一种纯生存技能,也俗称“搬砖”….好像跑题了……扯淡的话先不多说,现在正式开始了,哈哈!相信很多具有即时通讯功能的项目在架构时,都会了解到Openfire,当然很多有米的公司是直接使用一些服务商提供的即时通讯系统,如环信等。
简简单单来了解下Openfire,Openfire就是实现了XMPP通讯协议的开源即时通讯系统,基于java实现,部署简单,稳定高效,社区活跃,集群方案较成熟、基于插件的扩展性也是相当令人称赞,项目的维护者是相当得负责任,现在也是不断地更新版本中。
咋一说,赶紧去Openfire的官网瞄一眼,版本已经更新到4.0.1了!天啊噜,版本帝,您可别太快啊,公司的项目跟不上您的升级步伐啊….好吧,我们还在用着旧版本…现在开始我们的正题吧,一起来实现Openfire的集群部署。
Openfire集群部署方案使用Openfire的集群插件Hazelcast Clustering Plugin完成openfire的集群部署;并使用Nginx作为整个openfire集群的负责均衡服务器。
集群部署服务器信息我们这次部署的服务器信息如下,这几台服务器都是在同一个局域网下。
当然我没这么多物理机器了,CentOS6.5的服务器都是我安装的虚拟机,你懂得…我们将把两台Openfire的服务器做一个集群;当前还部署了一台前端的负载均衡服务器。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
spark+openfire二次开发(一)
文章分类:Java编程
1.准备工作:
到官网上下载Openfire 3.6.4,并通过svn下载openfire、Spark和SparkWeb 的源代码
官网地址如下:
/downloads/index.jsp
注意官网上最新的Spark版本是2.5.8,其jdk环境最好使用1.6的版本。
2.环境搭建——spark源码安装配置
双击openfire_3_6_4.exe进行openfire的安装,安装过程很简单,不介绍了。
本例的开发环境是基于Eclipse的。
1)选择File——New——Project——Java Project。
输入项目工程名spark
Contents中选择"Create project from existiing source",然后把spark 文件所在的文件夹加进去..
点击Finish。
2)生成Spark:
点击Window::Show View::Ant
右击Ant面板,选择Add Buildfiles
展开spark::build文件夹,选择build.xml,点击"OK"
在Ant面板,展开Spark,双击"release",等一段时间,会提示"Build Successful"。
3)运行Spark:
点击Run::Open Debug Dialog...,出现"Run"窗口
选择"Java Application",右键点击"New"按钮.
在"Main"标签页,将New_configuration换成Spark.
点击Project::Browse按钮,选择Spark,再点OK.
点击Main class::Search按钮,选择main所在的类
uncher.Startup再点击OK
建议勾选Stop in main.
点击Classpath标签页,选择User Entries ,使得Advanced..按钮变的可用.点击Advanced按钮.在弹出来的Advanced Options窗口,选择Add Folders,再点OK,在Folder Selection窗口选择spark::src::resources 文件夹,点击OK 选择Common标签页,勾选Debug,Run前面的框
点击Apply,再点击Close
4)在run下选择spark,运行成功!
spark+openfire二次开发(二)
1.openfire源码部署
将下来的openfire_src_3_6_4.tar.gz解压后得到openfire_src文件夹,重命名为openfire。
其源码部署方式请参照spark+openfire二次开发(一)中spark源码的部署方式。
2.openfire运行配置
1)点击Run::Open Debug Dialog...,出现"Run"窗口
2)选择"Java Application",右键点击"New"按钮.
3)在"Main"标签页,将New_configuration换成openfire.
4)点击Project::Browse按钮,选择openfire,再点OK.
5)点击Main class::Search按钮,选择main所在的类ServerStarter再点击OK,建议勾选Stop in main.
6)Arguments页面。
在VM arguments中加下内容
-DopenfireHome="${workspace_loc:Openfire}/target/openfire"。
7)点击Classpath标签页,选择User Entries ,使得Advanced..按钮变的可用.点击Advanced按钮.在弹出来的Advanced Options窗口,选择Add Folders,再点OK,在Folder Selection窗口选择Openfire/src/i18n文件夹,同样的方式选择Openfire/src/resources/jar文件夹,点击OK。
8)选择Common标签页,勾选Debug,Run前面的框
9)点击Apply,再点击Close
3.编译
1)将Openfire/src/i18n文件夹下的openfire_i18n_en.properties文件及Openfire/src/resources/jar文件夹下的admin-sidebar.xml文件拷贝到src\bin目录下,打开ANT面板,选择openfire【default】任务执行。
4.运行
运行openfire,控制台界面出现如下信息:
Openfire 3.6.4 [Mar 15, 2010 8:49:33 AM]
Admin console listening at http://127.0.0.1:9090
在浏览器中打开上面显示的地址,可进行openfire的管理配置。
spark+openfire二次开发(三)
文章分类:Java编程
spark的插件主要用来增强客户端的功能,下文主要介绍一下spark插件的开发过程。
1.最终完成效果如下:
增加一个My Plugin菜单,点击后显示hello面板。
2.开发流程
1)插件结构
插件的jar包结构如下示:
Java代码
1.example.jar
2. |- plugin.xml 插件定义文件
3. |- libs/ 包含所有运行此插件所需的classes文件
定义你的plugin.xml文件。
spark会自动读取插件jar中的plugin.xml文件,进行插件加载工作。
示例文件如下:
Java代码
1.<!-- Define your plugins -->
2.<plugin>
3. <name>Examples Plugin</name>
4. <version>1.0</version>
5. <author>Derek DeMoro</author>
6. <homePage></homePage>
7. <email>derek@</email>
8. <description>Shows some simple ways to create plugins.</des
cription>
9. <!--插件的接口实现类-->
10. <class>com.jivesoftware.spark.examples.ExamplePlugin</class
>
11. <minSparkVersion>2.5.0</minSparkVersion>
12.</plugin>
2)开发你的插件
插件源码目录结构
Java代码
1.example
2. |- src 源代码
3. |- lib 支持此插件的额外jar文件
4. |- resources 图片等资源文件
5. |- build 编译文件
6. |-build.xml ant打包插件的配置文件
插件的实现类,你的类首先要实现Spark 提供的Plugin 接口,然后实现它的一些方法。
Java代码
1.package org.jivesoftware.spark.examples;
2.
3.import org.jivesoftware.spark.plugin.Plugin;
4.
5./**
6. * 通过实现方法的不同,来显示不同的插件功能
7. */
8.public class ExamplePlugin implements Plugin {
9.
10. /**
11. * 插件安装后,初始化插件
12. */
13. public void initialize() {
14. System.out.println("Welcome To Spark");
15.
16. }
17.
18. /**
19. *spark关闭的时候调用,来实现信息持久化或释放资源
20. */
21. public void shutdown() {
22.
23. }
24.
25. /**
26. * 当用户请求关闭spark时,如果可以关闭返回真
27. */
28. public boolean canShutDown() {
29. return true;
30. }
31.
32. /**
33. * 插件卸载的时候调用,清除磁盘上的资源,如文件,图像等以及插
件安装时留下的所有组件
34. */
35. public void uninstall(){
36. // Remove all resources belonging to this plugin.
37. }
38.}
openfire spark 源代码下载地址
/downloads/index.jsp。