热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

我有一个需要在完成某些工作时通知用户的应用程序。 它使用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看起来像这样:








很简单吧? 托管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 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 {/***
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



推荐阅读
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 用阿里云的免费 SSL 证书让网站从 HTTP 换成 HTTPS
    HTTP协议是不加密传输数据的,也就是用户跟你的网站之间传递数据有可能在途中被截获,破解传递的真实内容,所以使用不加密的HTTP的网站是不 ... [详细]
  • 本文最初发表在Thorben Janssen的Java EE博客上,每周都会分享最新的Java新闻和动态。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 本指南详细介绍了如何在CentOS 6.6 64位系统上以root用户身份部署Tomcat 8服务器。系统环境为CentOS 6.6 64位,采用源码安装方式。所需软件为apache-tomcat-8.0.23.tar.gz,建议将软件下载至/root/opt目录。具体下载地址请参见官方资源。本指南涵盖了从环境准备到服务启动的完整步骤,适用于需要在该系统环境下搭建高性能Web应用服务器的技术人员。 ... [详细]
  • 基于域名、端口和IP的虚拟主机构建方案
    本文探讨了在单台物理服务器上构建多个Web站点的虚拟主机方案,详细介绍了三种主要的虚拟主机类型:基于域名、基于IP地址和基于端口的虚拟主机。每种类型的实现方式及其优缺点均进行了深入分析,为实际应用提供了全面的技术指导。 ... [详细]
  • 解决Parallels Desktop错误15265的方法
    本文详细介绍了在使用Parallels Desktop时遇到错误15265的多种解决方案,包括检查网络连接、关闭代理服务器和修改主机文件等步骤。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • 在 Android 开发中,`android:exported` 属性用于控制组件(如 Activity、Service、BroadcastReceiver 和 ContentProvider)是否可以被其他应用组件访问或与其交互。若将此属性设为 `true`,则允许外部应用调用或与之交互;反之,若设为 `false`,则仅限于同一应用内的组件进行访问。这一属性对于确保应用的安全性和隐私保护至关重要。 ... [详细]
  • 本文深入解析了JDK 8中HashMap的源代码,重点探讨了put方法的工作机制及其内部参数的设定原理。HashMap允许键和值为null,但键为null的情况只能出现一次,因为null键在内部通过索引0进行存储。文章详细分析了capacity(容量)、size(大小)、loadFactor(加载因子)以及红黑树转换阈值的设定原则,帮助读者更好地理解HashMap的高效实现和性能优化策略。 ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • 本文深入探讨了 Git 与 SVN 的高效使用技巧,旨在帮助开发者轻松应对版本控制中的各种挑战。通过详细解析两种工具的核心功能与最佳实践,读者将能够更好地掌握版本管理的精髓,提高开发效率。 ... [详细]
author-avatar
虫虫2彡0120106
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有