集成CDI和WebSockets

考虑尝试一个简单的Java EE 7原型应用程序,该应用程序涉及JAX-RS(REST),WebSockets和CDI。

注意 :不想让它成为破坏者-但这篇文章主要讨论了我在尝试使用Web套接字和使用CDI作为“胶水”的REST(在Java EE应用程序中)时遇到的问题。 整合并未实现,但是仍然吸取了一些教训:-)

这个想法是使用REST端点作为Web套接字端点的“提要”,从而将数据“推”到所有连接的客户端:

  • JAX-RS端点,它从其他来源接收数据(可能是实时的)作为Web套接字端点的输入
  • 使用CDI事件作为黑白JAX-RS和WebSocket端点的粘合剂,并“触发”有效负载
    @Path("/feed")
    public class RESTFeed {@InjectEvent<String> event;@POST@Consumes(MediaType.TEXT_PLAIN)public void push(String msg) {event.fire(msg);}
    }
  • 在WebSocket端点实现中使用CDI Observer方法将数据推送到连接的客户端:
    public void onMsg(@Observes String msg) {//different WS enpoint instance - notice the hash code value in the server logSystem.out.println("WS End point class ID -- " + this.hashCode());try {client.getBasicRemote().sendText(msg);} catch (IOException ex) {Logger.getLogger(ServerEndpoint.class.getName()).log(Level.SEVERE, null, ex);}
    }

当然,目前还没有考虑到更详细的信息,例如性能,异步通信等。 更多实验

但这有可能吗?

这是我执行的步骤

  • 部署代码
  • 浏览到http:// localhost:8080 / Explore-WebSocket-CDI-Integration-Maven /并作为Web套接字客户端连接

开始

  • 使用Postman在REST端点上触发HTTP POST请求

防火

繁荣! Observer方法中的NullPointerException –我等待了几秒钟,然后现实击中了我!

pe

根本原因(据我了解)

  • WebSocket端点的行为

WebSocket端点与JAX-RS资源类相似,因为每个连接的客户端都有一个Web套接字端点类的实例(至少默认情况下)。 WebSocket规范中明确提到了这一点。 客户端(对等方)连接后,便会创建一个唯一的实例,并且可以安全地将Web套接字会话对象(对等方的表示形式)作为实例变量进行缓存。 IMO,这是一个简单干净的编程模型

规格

  • 但是CDI容器还有其他计划!

REST端点一旦触发CDI事件(响应POST请求),CDI容器就会创建WebSocket终结点(在本例中为CDI Observer)的其他实例。 为什么? 因为CDI bean本质上是上下文相关的 。 该应用程序不控制CDI bean的实例。 它只是使用它们(通过@Inject)。 由容器来创建和销毁bean实例,并确保在相同上下文中执行的bean可以使用适当的实例。 容器如何确定上下文呢? 通过范围 –应用程序,会话,请求等…..

(再次,在CDI规范中明确提到)

规格

因此,问题的要点是没有WebSocket终结点当前上下文的实例–因此,CDI将创建一个新实例以传递消息。 当然,这意味着实例变量将指向null,因此将指向NPE(Duh!)

WebSocket端点将使用哪个CDI范围? 我尝试了@ ApplicationScoped,@ SessionScoped和@RequestScoped却没有太多运气–仍然是一个新实例和一个NPE

还有其他选择吗?

  • 将会话集定义为静态变量将达到目的:
    private static Set<Session> peers = Collections.synchronizedSet(new HashSet());

但是,如果仅在观察者方法中需要处理客户端特定状态(只能作为实例变量处理)的情况下,IMO只是一种黑客手段,这是不可行的–它势必会保持未初始化的状态。

  • 服务器发送事件 ? 但是最终,SSE!= WebSocket。 如果用例要求“仅”服务器端推送,则可以选择使用。 SSE尚未成为Java EE标准-Java EE 8可能使之成为可能

解决方法

我不是专家,但是我想这取决于WebSocket规范,以便更清楚地说明如何将其与CDI结合使用。 鉴于CDI是Java EE规范中必不可少的一部分,因此将其与其他规范(特别是以HTML5为中心的规范,例如JAX-RS,WebSocket等)进行无缝集成非常重要。

Bruno Borges的这篇文章链接到与JMS,CDI和WebSocket以及它们如何相互集成有关的类似问题。

我错过了明显的事情吗? 您有什么建议/解决方案吗? 请随时鸣叫! :-)

示例代码在GitHub上可用 (以供您查看)。 我在GlassFish 4.1和Wildfly 8.2.0上尝试过

我想现在就这些了。 :-)

干杯!

翻译自: https://www.javacodegeeks.com/2015/02/integrating-cdi-websockets.html

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

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

相关文章

【记】jQuery中的选择器:visible对visibility:hidden的处理

首先先介绍visibility这个CSS属性。 visibility用于表示该元素是否显示&#xff0c;其取值有&#xff1a; visible&#xff1a;设置对象可视。  hidden&#xff1a;设置对象隐藏。  collapse&#xff1a;主要用来隐藏表格的行或列&#xff0c;隐藏的行或列能够被其他内容是…

React - antd4 中在form中为Switch赋值无效

项目场景&#xff1a; React - antd4; From表单 问题描述&#xff1a; Switch赋初始值无效 # 解决方案&#xff1a; let newCheck {};if (propsForm.type switch) {newCheck {...newCheck,valuePropName: "checked"}}<Form.Itemkey{propsForm.id}name{propsF…

在实践中重试HTTP标头

Retry-After是鲜为人知的HTTP响应标头。 让我引用RFC 2616&#xff08;HTTP 1.1规范&#xff09;的相关部分&#xff1a; 14.37重试后 Retry-After响应标头字段可与503 &#xff08; 服务不可用 &#xff09;响应一起使用&#xff0c;以指示请求该客户端的服务预计无法使用多…

Java中连接字符串的最佳方法

最近有人问我这个问题–在Java中使用运算符连接字符串是否对性能不利&#xff1f; 这让我开始思考Java中连接字符串的不同方法&#xff0c;以及它们如何相互对抗。 这些是我要研究的方法&#xff1a; 使用运算符 使用StringBuilder 使用StringBuffer 使用String.concat() …

时间转换以及公式

moment(item.updatedAt).fromNow() ;//距离今天多久了moment&#xff08;&#xff09;获得今天、明天和昨天的日期 let today moment(new Date());let tomorrow moment(new Date()).add(1,days);let yesterday moment(new Date()).add(-1, days);后续遇到继续补充

只不过是R.java文件的特性-----出错信息:R.java was modified manually! Reverting to generated version!...

出错信息:R.java was modified manually! Reverting to generated version! 出错原因&#xff1a;今天在res下建立了一个drawable的文件夹存放图片资源----图片名为1.jpg 后来R.java文件就报错了&#xff1a;R.java was modified manually! Reverting to generated version! 看…

十大最常见的Java性能问题

Java性能是所有Java应用程序开发人员都关心的问题&#xff0c;因为快速使应用程序与使其正常运行同等重要。 史蒂文海恩斯&#xff08;Steven Haines&#xff09;使用他在Java性能问题上的个人经验得出的结论是&#xff0c; 大多数问题都有共同的根本原因 。 因此&#xff0c;作…

antd form 初始化时间

initialValue: moment(record.showTime, YYYY-MM-DD HH:mm:ss)

uni-app 组件中的canvas转化为图片报错:errMsg:“canvasToTempFilePath:fail canvas is empty”

项目场景&#xff1a; uni-app,开发微信小程序 使用&#xff1a; wx.canvasToTempFilePath({canvasId: line,success: function(res) {console.log(canvasToImg, res);this.radarImg res.tempFilePath;},fail: function(res) {console.log(res);}});问题描述&#xff1a; ec…

正确获取Java事件通知

实现观察者模式以提供Java事件通知似乎是一件容易的事。 但是&#xff0c;容易陷入一些陷阱。 这是我在各种场合不慎造成的常见错误的解释…… Java事件通知 让我们从一个简单的bean StateHolder开始&#xff0c;它封装了带有适当访问器的私有int字段state &#xff1a; publ…

使用fn函数控制页面显示内容

在使用&#xff25;&#xff2c;的时候&#xff0c;不可避免的遇到&#xff0c;截取字符串&#xff0c;判断字符串长度等情况。这里给出简单的通过&#xff46;&#xff4e;函数操作字符串的deamon。 1、页面引入标签 <% taglib prefix"c" uri"http://java.s…

uni-app微信获取手机号,第一次解密总是失败

项目场景&#xff1a; uni-app; 获取code&#xff0c;后台解密手机号 问题描述&#xff1a; 每次第一次登陆&#xff0c;后台都会解密失败 原因分析&#xff1a; code获取错误&#xff1b;导致后台的解密key与code不对应 解决方案&#xff1a; 小程序获取手机号之前&#xf…

Java中不一致的操作会扩大规则

总览 当您在Java中执行一元或二进制操作时&#xff0c;标准行为是使用最宽的操作数&#xff08;或对byte &#xff0c; short和char使用更宽的操作数&#xff09;。 这很容易理解&#xff0c;但是如果考虑最佳类型可能会造成混淆。 乘法 当执行乘法运算时&#xff0c;您得到的…

圣诞节到了,用js给喜欢的人写一颗圣诞树吧

文章目录 1、效果预览2、代码2.1、定义数组写下祝福语2.2、模拟雪花落下的效果2.3、设置背景粒子2.4、操作动画效果2.5、定义闪烁效果2.6、定义粒子对象2.7、粒子对象播放2.8、绘制星星2.9、绘制圣诞树2.10、绘制星星背景动画2.11、定义初始化函数并调用 3、结尾 1、效果预览 圣…

Unity3D 访问Access数据库

Unity3D 访问Access数据库 在开始这个小教程之前呢&#xff0c;其实在网上你已经可以找到相关的资料了&#xff0c;但是我还是要把我自己做练习的一点东西分享出来。写这个教程的主要原因呢&#xff0c;是一个朋友在u3d的官网论坛里&#xff0c;找到了这个demo&#xff0c;但是…

uni.reLaunch前出现uni.showToast,不会成功弹出提示信息

解决方案&#xff1a; uni.showToast({title: 发布成功,duration: 1000});setTimeout(function() {uni.reLaunch({url: /pages/tips/index})}, 1000);

LaTeX 基础笔记。开篇

LaTeX 的起源非常牛逼&#xff0c;有一套书大家可能听说过《计算机程序设计艺术》&#xff0c;写了好几本。当然能在计算机方面写上艺术俩字的书恐怕不是我们一般人能读懂得东西了。他的作者在1976年准备写第二卷的时候发现计算机的排版非常难看&#xff0c;所以&#xff0c;为…

Java旧版不断发展

我最近偶然发现了JDK API的一个非常有趣的警告&#xff0c;即Class.getConstructors()方法。 它的方法签名是这样的&#xff1a; Constructor<?>[] getConstructors()有趣的是&#xff0c; Class.getConstructor(Class...)返回一个Constructor<T> &#xff0c;并…

React 学习笔记 —— Ref Hook

用以下三种方式创建 Ref 都可以 import React from reactexport default function Count () {const [count ,setCount] React.useState(0)const myRef React.createRef()const myRef2 React.useRef() // Ref Hook 的方式const myRef3 {current: undefined}const addNumber…