使用Vysper,TomEE和PrimeFaces将XMPP服务器嵌入JSF Web应用程序内部

我有一个需要在完成某些工作时通知用户的应用程序。 它使用JSF和Primefaces,因此可以使用大气 (也称为Push)来实现这种通知。

但是另一个有趣的方法是使用嵌入在Java Web应用程序中的XMPP服务器。 好的,好的,您不必嵌入它,只需运行一个工业级XMPP服务器的实例,例如Openfire和Tigase即可 。 但是,嘿,我们只是在玩些游戏,所以我将向您展示如何使用Vysper进行操作, Vysper是使用Apache Mina开发的概念验证游戏 ,只需几分钟即可轻松完成。

在展示如何做之前,很高兴记住线程和JEE应用程序通常不会混合使用 ,因此我们可以玩,但是我们必须知道我们在做什么。

首先,您将需要这些JAR,其中大多数来自Vysper。 只是几个?

  • aopalliance-1.0.jar
  • commons-codec-1.4.jar
  • commons-collections-3.1.jar
  • commons-io-1.4.jar
  • commons-lang-2.5.jar
  • commons-logging-1.1.jar
  • 并发1.3.4.jar
  • derby-10.2.1.6.jar
  • dnsjava-2.0.8.jar
  • ehcache-core-2.2.0.jar
  • fontbox-0.1.0.jar
  • jackrabbit-api-1.5.0.jar
  • jackrabbit-core-1.5.3.jar
  • jackrabbit-jcr-commons-1.5.3.jar
  • jackrabbit-spi-1.5.0.jar
  • jackrabbit-spi-commons-1.5.0.jar
  • jackrabbit-text-extractors-1.5.0.jar
  • jcl-over-slf4j-1.5.3.jar
  • jcr-1.0.jar
  • jempbox-0.2.0.jar
  • jetty-continuation-7.2.1.v20101111.jar
  • jetty-http-7.2.1.v20101111.jar
  • jetty-io-7.2.1.v20101111.jar
  • jetty-security-7.2.1.v20101111.jar
  • jetty-server-7.2.1.v20101111.jar
  • jetty-servlet-7.2.1.v20101111.jar
  • jetty-util-7.2.1.v20101111.jar
  • jetty-websocket-7.2.1.v20101111.jar
  • log4j-1.2.14.jar
  • lucene-core-2.3.2.jar
  • mina-core-2.0.2.jar
  • nbxml-0.7.jar
  • nekohtml-1.9.7.jar
  • pdfbox-0.7.3.jar
  • poi-3.0.2-FINAL.jar
  • poi-scratchpad-3.0.2-FINAL.jar
  • primefaces-4.0.jar
  • servlet-api-2.5.jar
  • slf4j-api-1.5.3.jar
  • slf4j-log4j12-1.5.3.jar
  • smack-3.1.0.jar
  • smackx-3.1.0.jar
  • spec-compliance-0.7.jar
  • 弹簧-aop-3.0.5.RELEASE.jar
  • 弹簧-asm-3.0.5.RELEASE.jar
  • Spring Bean3.0.5.RELEASE.jar
  • spring-context-3.0.5.RELEASE.jar
  • 弹簧核心-3.0.5.RELEASE.jar
  • spring-expression-3.0.5.RELEASE.jar
  • vysper-core-0.7.jar
  • vysper-websockets-0.7.jar
  • xep0045-muc-0.7.jar
  • xep0060-pubsub-0.7.jar
  • xep0124-xep0206-bosh-0.7.jar
  • xercesImpl-2.8.1.jar
  • xml-apis-1.3.03.jar

现在,从Vysper复制虚假证书,以便您的XMPP服务器可以在“安全”通道下“工作”。 它称为bogus_mina_tls.cert。

我的xhtml看起来像这样:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:f="http://java.sun.com/jsf/core"xmlns:h="http://java.sun.com/jsf/html"xmlns:ui="http://java.sun.com/jsf/facelets"xmlns:p="http://primefaces.org/ui">
<h:head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Messaging Prototype</title><link rel="icon" type="image/png" href="favicon.ico"></link>    
</h:head>
<h:body>    <h:outputStylesheet library="css" name="style.css"  /><p:ajaxStatus style="width:16px;height:16px;" id="ajaxStatusPanel">  <f:facet name="start">  <h:graphicImage value="./ajaxloading.gif" />  </f:facet>  <f:facet name="complete">  <h:outputText value="" />  </f:facet>  </p:ajaxStatus>  <h:form>    <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" /><p:spacer height="10" /><p:panel><h:panelGrid columns="2"><p:commandButton value="Enter" action="#{messagingMB.sendMessage}" /></h:panelGrid></p:panel><p:spacer height="10" /></h:form>
</h:body>
</html>

很简单吧? 托管Bean也很容易。

import java.io.Serializable;import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;import org.jivesoftware.smack.XMPPException;@ManagedBean
@ViewScoped
public class MessagingMB implements Serializable {private static final long    serialVersionUID    = -9092497421080796430L;@EJBprivate JSFUtilEJB jsfUtilEJB;@PostConstructpublic void init() {}public void sendMessage() {try {new BasicClient().test();} catch (XMPPException e) {jsfUtilEJB.addErrorMessage(e,"Could not send");}}
}

当然,EJB:

import javax.ejb.Stateless;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.FacesContext;@Stateless
public class JSFUtilEJB {@SuppressWarnings("unchecked")public <T> T findBean(String beanName) {FacesContext context = FacesContext.getCurrentInstance();return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);}public long addErrorMessage(String msg) {return addMessage(null,FacesMessage.SEVERITY_ERROR,msg);}public long addErrorMessage(Exception e,String summary){return addMessage(e,FacesMessage.SEVERITY_ERROR,summary);}public long addFatalErrorMessage(Exception e,String summary){return addMessage(e,FacesMessage.SEVERITY_FATAL,summary);}public long addInfoMessage(String summary){return addMessage(null,FacesMessage.SEVERITY_INFO,summary);}public long addWarnMessage(Exception e,String summary){return addMessage(e,FacesMessage.SEVERITY_WARN,summary);}public long addErrorMessage(Exception e) {return addMessage(e,FacesMessage.SEVERITY_ERROR,e.getMessage(),e.getClass().getSimpleName());}private long addMessage(Exception e,Severity severity, String summary) {FacesContext context = FacesContext.getCurrentInstance();String clientId = null;long id = -1;if (e != null){id = printStackTrace(e);FacesMessage facesMessage = null;if (e.getCause() instanceof org.apache.openjpa.persistence.EntityExistsException){facesMessage = new FacesMessage(severity,"[Error: #"+id+"] "+summary,"You are trying are to add a new object that already exists or your're trying to violate a unique constraint)" );    }else{facesMessage = new FacesMessage(severity,"[Error: #"+id+"] "+summary,e.getMessage() );}context.addMessage(clientId , facesMessage );}else{FacesMessage facesMessage = new FacesMessage(severity,summary," ");context.addMessage(clientId , facesMessage );}return id;}private long addMessage(Exception e,Severity severity, String summary, String detail) {FacesContext context = FacesContext.getCurrentInstance();String clientId = null;long id = -1;if (e != null){id = printStackTrace(e);        FacesMessage facesMessage = new FacesMessage(severity,"["+id+"] "+summary,detail );context.addMessage(clientId , facesMessage );}else{FacesMessage facesMessage = new FacesMessage(severity,summary,detail );context.addMessage(clientId , facesMessage );}return id;}public long printStackTrace(Exception e){long uniqueId = System.currentTimeMillis();return uniqueId;}}

import java.io.File;
import java.io.Serializable;import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;import org.apache.vysper.mina.TCPEndpoint;
import org.apache.vysper.storage.StorageProviderRegistry;
import org.apache.vysper.storage.inmemory.MemoryStorageProviderRegistry;
import org.apache.vysper.xmpp.addressing.EntityImpl;
import org.apache.vysper.xmpp.authorization.AccountManagement;
import org.apache.vysper.xmpp.server.XMPPServer;@Startup
@Singleton
public class XmppEJB implements Serializable {/*** <br>06/09/2014*/private static final long serialVersionUID = 1L;private boolean started;@PostConstructpublic void init() {try {// choose the storage you want to use//        StorageProviderRegistry providerRegistry = new JcrStorageProviderRegistry();StorageProviderRegistry providerRegistry = new MemoryStorageProviderRegistry();final AccountManagement accountManagement = (AccountManagement) providerRegistry.retrieve(AccountManagement.class);if(!accountManagement.verifyAccountExists(EntityImpl.parse("user1@vysper.org"))) {accountManagement.addUser(EntityImpl.parse("user1@vysper.org"), "password");}if(!accountManagement.verifyAccountExists(EntityImpl.parse("user2@vysper.org"))) {accountManagement.addUser(EntityImpl.parse("user2@vysper.org"), "password");}XMPPServer server = new XMPPServer("vysper.org");server.addEndpoint(new TCPEndpoint());server.setStorageProviderRegistry(providerRegistry);server.setTLSCertificateInfo(new File("/path/to/bogus_mina_tls.cert"), "boguspw");server.start();System.out.println("server is running...");} catch (Exception e) {e.printStackTrace();}started = true;}public boolean isStarted() {return this.started;}}

和基本客户, 来自Vysper 。

import java.util.Date;import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.packet.Time;
import org.jivesoftware.smackx.packet.Version;public class BasicClient {static class IQListener implements PacketListener {public void processPacket(Packet packet) {IQ iq = (IQ) packet;String iqString = iq.toString();System.out.println("T" + System.currentTimeMillis() + " IQ: "+ iqString + ": " + iq.toXML());}}static class PresenceListener implements PacketListener {public void processPacket(Packet packet) {Presence presence = (Presence) packet;String iqString = presence.toString();final PacketExtension extension = presence.getExtension("http://jabber.org/protocol/caps");if (extension != null)System.out.println("T" + System.currentTimeMillis() + " Pres: "+ iqString + ": " + presence.toXML());}}public void test() throws XMPPException {String me = "user2@vysper.org";String to = "user1@vysper.org";try {ConnectionConfiguration connectionConfiguration = new ConnectionConfiguration("localhost");connectionConfiguration.setCompressionEnabled(false);connectionConfiguration.setSelfSignedCertificateEnabled(true);connectionConfiguration.setExpiredCertificatesCheckEnabled(false);
//            connectionConfiguration.setDebuggerEnabled(true);connectionConfiguration.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
//            XMPPConnection.DEBUG_ENABLED = true;XMPPConnection connection = new XMPPConnection(connectionConfiguration);connection.connect();SASLAuthentication saslAuthentication = connection.getSASLAuthentication();saslAuthentication.authenticate(me, "password", "test");connection.login(me, "pqssword");connection.getRoster().setSubscriptionMode(Roster.SubscriptionMode.accept_all);connection.addPacketListener(new IQListener(), new PacketFilter() {public boolean accept(Packet packet) {return packet instanceof IQ;}});connection.addPacketListener(new PresenceListener(),new PacketFilter() {public boolean accept(Packet packet) {return packet instanceof Presence;}});Chat chat = null;if (to != null) {Presence presence = new Presence(Presence.Type.subscribe);presence.setFrom(connection.getUser());String toEntity = to;presence.setTo(toEntity);connection.sendPacket(presence);chat = connection.getChatManager().createChat(toEntity,new MessageListener() {public void processMessage(Chat inchat,Message message) {System.out.println("log received message: "+ message.getBody());}});}connection.sendPacket(new Presence(Presence.Type.available,"pommes", 1, Presence.Mode.available));Thread.sleep(1000);// query server versionsendIQGetWithTimestamp(connection, new Version());// query server timesendIQGetWithTimestamp(connection, new Time());chat.sendMessage("Hello " + to + " at " + new Date());connection.disconnect();} catch (Throwable e) {e.printStackTrace(); // To change body of catch statement use File |// Settings | File Templates.}System.out.println("bye");}private static void sendIQGetWithTimestamp(XMPPConnection connection, IQ iq) {iq.setType(IQ.Type.GET);connection.sendPacket(iq);System.out.println("T" + System.currentTimeMillis()+ " IQ request sent");}
}

我们快要准备好了。 当然,现在我们需要一个XMPP客户端,例如Pidgin 。

首先,让我对这个博客表示感谢 ,因为我不知道为什么,Vysper站点几乎没有关于如何配置Pidgin的信息,因此这篇博客非常有用。

让我向您展示我的pidgin用户的样子:

1

2

3

我知道,是葡萄牙语。

就是这样。 我们都准备好了。 启动您的JSF Web应用程序并播放。

请注意,通信是双向的,因此您可以仅使用XMPP客户端将命令发送到服务器。 为此,您只需要更改此侦听器即可:

chat = connection.getChatManager().createChat(toEntity,new MessageListener() {public void processMessage(Chat inchat,Message message) {System.out.println("log received message: "+ message.getBody());}});

我想知道我们是否可以创建一个DSL来处理一些命令,是否可以找到一些自动完成的pidgin插件来使用该DSL编写命令。 欢迎提出建议!

ps。 EJB不能正常关闭服务器。 但是我敢打赌,如果服务器关闭,有一些EJB注释可以做到这一点。

翻译自: https://www.javacodegeeks.com/2014/09/embedding-a-xmpp-server-inside-your-jsf-web-application-using-vysper-tomee-and-primefaces.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

appium和selenium不同与相同之处

原文来自&#xff1a; https://www.cnblogs.com/zhengshuheng/p/6370398.html selenium是web端的自动化&#xff0c;appium是app端的自动化&#xff0c;它继承了webdriver(也就是selenium 2) 转载于:https://www.cnblogs.com/lv-lxz/p/11118862.html

Mockito 101

Mockito是一个模拟框架&#xff0c;可让您使用简洁的API编写漂亮的测试。 它偏向于最低规格&#xff0c;使不同的行为看起来有所不同&#xff0c;并显示清晰的错误消息。 创造嘲弄 要使用Mockito创建模拟&#xff0c;只需使用Mock注释模拟&#xff0c;然后调用MockitoAnnotati…

前端开发常用代码片段(下篇)

二十二、正则表达式 //验证邮箱/^\w ([0-9a-zA-Z] [.]) [a-z]{2,4}$///验证手机号/^1[3|5|8|7]\d{9}$///验证URL/^http:\/\/. \.///验证身份证号码/(^\d{15}$)|(^\d{17}([0-9]|X|x)$)///匹配字母、数字、中文字符/^([A-Za-z0-9]|[\u4e00-\u9fa5])*$///匹配中文字符/[\u4e00-\u9…

使用 Visual Studio 编译 wget 为库文件

添加代码与预编译指令与上一篇使用 Visual Studio 编译 wget 为可执行文件一致&#xff0c;区别在于这回建的是静态库工程&#xff08;编译为动态库过程类似:)&#xff09; 从wget的main函数开始读下来&#xff0c;发现问题不少&#xff0c;程序可能基于效率或者编码方便的因素…

动态规划(0-1背包)--- 改变一组数的正负号使得它们的和为一给定数

改变一组数的正负号使得它们的和为一给定数 494. Target Sum (Medium) Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation:-11111 3 1-1111 3 11-111 3 111-11 3 1111-1 3There are 5 ways to assign symbols to make the sum of nums be target 3. 题目描述…

关于设计模式的胡思乱想

设计模式是一个指导&#xff0c;并不强制。有很多地方并不需要设计模式介入&#xff0c;因为设计模式是分离变化&#xff0c;很多代码是一次性的&#xff0c;不会变。如果我们一开始写程序的时候就加入设计模式&#xff0c;这样就显得过度设计&#xff0c;既耗时又费力。 并且…

JSR 310新日期/时间API的自定义JSR 303 Bean验证约束

借助JSR 310&#xff0c;Java 8终于为我们带来了不错的日期和时间API。 对于仍在使用Java 7的那些人&#xff08;例如我目前在我的当前项目中&#xff09;&#xff0c;有很好的反向移植&#xff0c;请访问www.threeten.org了解更多详细信息。 但是&#xff0c;由于有关该主题的…

H5之audio标签放音兼容所有浏览器方法

前端交流群&#xff0c;群文件提供大量文档、书籍和资料。期待你的加入&#xff01;群号&#xff1a;127768464 由于项目需要&#xff0c;最近刚做了一个网页放音的功能&#xff0c;使用到了H5新标签<audio></audio>&#xff0c;但是audio只能支持IE8以上的浏…

VisualStudio2010 SP1 SP1 SDK SQLServer 2008 SP3 下载地址

SP1:http://go.microsoft.com/fwlink/?LinkId210710 SP1 SDK:http://www.microsoft.com/download/en/details.aspx?id21835 SQLServer2008 sp3:http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid757bca07-7b52-46fb-ab92-476be9339442&displaylangzh-cn …

python高级特性:迭代器与生成器

前言 有一个列表 l [a,b,c,d,e] 我想取列表中的内容&#xff0c;有几种方式&#xff1f; # 1.最简单的方法用for循环。 for i in l:print(i,end" ") # 2.用列表内置的方法。 while 1:if l:print(l.pop(),end" ") 这是用常见的方式取出列表中的数据。 …

webpack中实现按需加载

当页面中一个文件过大并且还不一定用到的时候&#xff0c;我们希望在使用到的时候才开始加载这个文件俗称按需加载。这样可以减少页面的响应时间&#xff0c;提高访问速度。 使用webpack打包的出来的文件要实现以上的要求有两种方式&#xff0c;一个是webpack特有的require.en…

H5各种头部meta标签的功能

<!DOCTYPE html> H5标准声明&#xff0c;使用 HTML5 doctype&#xff0c;不区分大小写 <head lang”en”> 标准的 lang 属性写法 <meta charset’utf-8′> 声明文档使用的字符编码 <meta http-equiv”X-UA-Compatible” content”IEedge,chrome1″…

如何使用单例EJB和MBean构建和清除参考数据缓存

在我的一个项目中&#xff0c;我需要使用EclipseLink作为ORM框架从Java EE 6 WebLogic环境中的多个源中加载参考数据。 由于我在Java EE世界中找不到与Spring YET的Cacheable相当的注释&#xff0c;因此我不得不编写自己的缓存解决方案。 尽管参考数据几乎不会随时间变化&#…

让 UV4 支持STC 单片机

Keil 本身并没有自带 STC 8051 单片机的数据&#xff0c;这样用起来就非常令人不爽&#xff0c;好在国内有个青年已经整理了一个补丁。 这个补丁包含三个修正&#xff1a; 汉字bug修正&#xff0c;这个是老生常谈了&#xff0c;很奇怪Keil十年来都没有修正这个&#xff0c;说明…

【总结】计算机网络常见问题

1、TCP/IP协议与OSI协议 相互通信的两个计算机系统必须高度协调工作才行&#xff0c;而这种“协调”是相当复杂的。 “分层”可将庞大而复杂的问题&#xff0c;转化为若干较小的局部问题&#xff0c;而这些较小的局部问题就比较易于研究和处理。 计算机网络采用了分层的体系结构…

webpack3的CommonsChunkPlugin插件详解

webpack打出来的包在不做处理的情况下是非常大的&#xff0c;所有依赖都被塞进一个文件中&#xff0c;文件中有业务代码&#xff0c;有业务代码依赖的第三方库代码&#xff0c;还有webpack生成的运行时代码等。这样的一个文件不方便静态资源缓存&#xff0c;并且初始化页面的时…

详细介绍jQuery.outerWidth() 函数具体用法

outerWidth()函数用于设置或返回当前匹配元素的外宽度。外宽度默认包括元素的内边距(padding)、边框(border)&#xff0c;但不包括外边距(margin)部分的宽度。你也可以指定参数为true&#xff0c;以包括外边距(margin)部分的宽度。如下图&#xff1a; 如果你要获取其它情况的宽…

自动装箱

自Java 1.5起&#xff0c;所有Java开发人员都可以使用自动装箱功能。嗯&#xff0c;我可能太乐观了。 至少所有开发人员都应该可以使用自动装箱。 毕竟&#xff0c;在ORACLE页面上有一个很好的教程。 自动装箱是Java编译器在需要时自动从原始类型创建代码创建对象的代码时的现…

SQLite 入门教程(一)基本控制台(终端)命令

一、基本简介 SQLite 是一个自持的&#xff08;self-contained&#xff09;、无服务器的、零配置的、事务型的关系型数据库引擎。因为他很小&#xff0c;所以也可以作为嵌入式数据库内建在你的应用程序中。SQLite 被应用在 Solaris 10操作系统、Mac OS 操作系统、iPhone 和 Sky…

PHP中的session

1.1原理 1.session是服务器端的技术 2.session是基于cookie技术的 1.2session操作 1.默认情况下&#xff0c;会话不会自动开启&#xff0c;通过session_start()开启会话 2.通过session_id()获取会话的编号 3、通过$_SESSION操作会话 4、会话可以保存除了资源以外的所有类型…