在JDeveloper 12.1.3中将Java API用于WebSockets

介绍

最新版本的JDeveloper 12c(12.1.3.0)和WebLogic Server 12.1.3一起提供了一些新的Java EE 7功能。 其中之一是对用于WebSocket的JSR 356 Java API的支持。 实际上,从12.1.2.0版本开始就支持WebSocket协议(RFC 6455),但是它基于WebSocket API的WebLogic特定实现。 现在,此专有的WebLogic Server WebSocket API已被弃用。 但是,仍支持向后兼容。

在本文中,我将展示一个在简单的ADF应用程序中为WebSocket使用JSR 356 Java API的示例。 该用例是关于在塔​​斯曼海发生的一些帆船赛。 有三艘船参加帆船赛,它们将穿越塔斯曼海,从澳大利亚航行至新西兰海岸。 该示例应用程序的目标是监视帆船赛,并告知用户进行情况,在地图上显示船只的位置。

我们将在应用程序中声明一个WebSocket服务器端点,当用户打开页面时,Java脚本函数将打开一个新的WebSocket连接。 该应用程序使用计划的服务,该服务每秒钟更新一次船的坐标,并向所有活动的WebSocket客户端发送一条包含新船位置的消息。 在客户端,Java脚本功能接收消息并根据GPS坐标将标记添加到Google地图。 因此,每个对帆船赛感兴趣的用户都将看到代表比赛当前状态的同一张更新图片。

WebSocket服务器端点

让我们从声明一个WebSocket服务器端点开始。 当前实施中有一个小问题,将来的发行版中可能会解决。 WebSocket端点不能与ADF页面混合使用,应将它们部署在单独的WAR文件中。 最简单的方法是在应用程序中创建一个单独的WebSocket项目,并在此项目中声明所有必需的端点:

屏幕截图2014年10月7日下午12.17.58

这对于为项目设置可读的Java EE Web上下文根也很重要:

屏幕截图2014年10月7日下午12.26.35

下一步是创建一个Java类,它将成为WebSocket端点。 因此,这是一个普通的类,在开始时带有特殊注释:

@ServerEndpoint(value = "/message")
public class MessageEndPoint {public MessageEndPoint() {super();}
}

注意,JDeveloper用红色标记注释。 我们将通过让JDeveloper为Web Socket配置项目来解决此问题。

屏幕截图2014年10月7日下午12.59.45
完成此操作后,JDeveloper将把该项目转换为一个Web项目,并添加Web.xml文件并添加必要的库:

屏幕截图2014年10月7日下午1.32.56
此外,端点类变得可运行,我们可以运行它以检查其实际工作方式:

屏幕截图2014年10月7日下午1.34.55
作为响应,JDeveloper生成以下URL,在该URL上WebSocket端点可用。 请注意,URL包含项目上下文根( WebSocket )和批注的value属性( / message )。 如果一切正常,那么在单击URL时,将获得“已成功连接”信息窗口:

屏幕截图2014年10月7日下午1.37.44

顺便说一句,消息中有一个错字。

现在让我们向WebSocket终结点类添加一些实现。 根据规范,将为每个WebSocket连接创建一个MessageEndPoin t类的新实例。 为了容纳所有活动的WebSocket会话,我们将使用静态队列:

public class MessageEndPoint {//A new instance of the MessageEndPoint class //is going to be created for each WebSocket connection//This queue contains all active WebSocket sessionsfinal static Queue<Session> queue = new ConcurrentLinkedQueue<>(); @OnOpenpublic void open(Session session) {queue.add(session);         }    @OnClosepublic void closedConnection(Session session) {queue.remove(session);}@OnErrorpublic void error(Session session, Throwable t) {queue.remove(session);t.printStackTrace();}

建立新连接,关闭新连接以及发生错误时 ,将分别调用带注释的方法openclosedConnectionerror 。 完成此操作后,我们可以使用一些静态方法向所有客户端广播文本消息:

public static void broadCastTex(String message) {for (Session session : queue) {try {session.getBasicRemote().sendText(message);} catch (IOException e) {e.printStackTrace();}}}

在我们的用例中,我们必须用船的新GPS坐标通知用户,因此我们应该能够通过WebSockets发送比文本消息更复杂的信息。

发送对象

基本上,示例应用程序的业务模型由两个简单的Java类Boat表示

public class Boat {private final String country;private final double startLongitude;private final double startLatitude;private double longitude;private double latitude;public String getCountry() {return country;}public double getLongitude() {return longitude;}public double getLatitude() {return latitude;}public Boat(String country, double longitude, double latitude) {this.country = country;this.startLongitude = longitude;this.startLatitude = latitude;}
...

帆船赛

public class Regatta {private final Boat[] participants = new Boat[] {new Boat("us", 151.644, -33.86),new Boat("ca", 151.344, -34.36),new Boat("nz", 151.044, -34.86)};public Boat[] getParticipants() {return participants;}
...

对于我们的用例,我们将向WebSocket客户端发送Regatta类的实例。 船会包含以Boat类实例表示的所有赛船会参与者,其中包含更新的GPS坐标( 经度纬度 )。

这可以通过创建Encoder.Text <Regatta>接口的自定义实现来完成,换句话说,我们将创建一个编码器,该编码器可以将Regatta实例转换为文本并指定该编码器供WebSocket使用端点,同时发送Regatta实例。

public class RegattaTextEncoder implements Encoder.Text<Regatta> {@Overridepublic void init(EndpointConfig ec) { }@Overridepublic void destroy() { }private JsonObject encodeBoat(Boat boat) throws EncodeException {JsonObject jsonBoat = Json.createObjectBuilder().add("country", boat.getCountry()).add("longitude", boat.getLongitude()).add("latitude" , boat.getLatitude()).build();return jsonBoat;}@Overridepublic String encode(Regatta regatta) throws EncodeException {JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();         for (Boat boat : regatta.getParticipants()) {arrayBuilder.add(encodeBoat(boat));}return arrayBuilder.build().toString(); }}
@ServerEndpoint(value = "/message",encoders = {RegattaTextEncoder.class })

完成后,我们可以将对象发送给我们的客户:

public static void sendRegatta(Regatta regatta) {for (Session session : queue) {try {session.getBasicRemote().sendObject(regatta);} catch (EncodeException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}

RegattaTextEncoder使用Json表示法将Regatta对象表示为船的列表,因此它将是这样的:

[{"country":"us","longitude":151.67,"latitude":-33.84},{"country":"ca", ...},{"country":"nz", ...}]

接收讯息

在客户端,我们使用Java脚本函数来打开新的WebSocket连接:

//Open a new WebSocket connection
//Invoked on page load 
function connectSocket() {  websocket = new WebSocket(getWSUri());    websocket.onmessage = onMessage;   
}

当消息到达时,我们将遍历一系列船只,并为每条船只在地图上添加一个标记:

function onMessage(evt) {var boats = JSON.parse(evt.data);for (i=0; i<boats.length; i++) {markBoat(boats[i]);  }   
}function markBoat(boat) {var image = '../resources/images/'+boat.country+'.png';var latLng = new google.maps.LatLng(boat.latitude,boat.longitude);  mark = new google.maps.Marker({position: latLng,map: map,title: boat.country,icon: image});
}

您可以在此处了解如何将Google地图集成到您的应用程序中。

运行帆船赛

为了模拟现场表演,我们使用ScheduledExecutorService 。 我们将每秒更新一次GPS坐标,并将更新广播给所有用户:

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> runHandle;//Schedule a new regatta on Start button click
public void startRegatta(ActionEvent actionEvent) {//Cancel the previous regattaif (runHandle != null) {runHandle.cancel(false);  }            runHandle = scheduler.scheduleAtFixedRate(new RegattaRun(), 1, 1, TimeUnit.SECONDS); 
}public class RegattaRun implements Runnable {private final static double FINISH_LONGITUDE = 18;private final Regatta regatta = new Regatta();//Every second update GPS coordinates and broadcast//new positions of the boatspublic void run() {            regatta.move();MessageEndPoint.sendRegatta(regatta);           if (regatta.getLongitude() >= FINISH_LONGITUDE) {runHandle.cancel(true);       }}
}

赌你的船

最后,我们的工作结果如下所示:

屏幕截图2014年10月7日下午5.24.01
本文的示例应用程序需要JDeveloper 12.1.3。 玩得开心!

而已!

翻译自: https://www.javacodegeeks.com/2014/10/using-java-api-for-websockets-in-jdeveloper-12-1-3.html

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

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

相关文章

基于Verilog语言的伪随机码的编写

写之初&#xff0c;笔者并没有太大的自信&#xff0c;因为笔者对伪随机码并没有太多的认识。但老师有命&#xff0c;笔者不得不进行编写&#xff0c;同时笔者也特别希望能有个项目来锻炼自己。 笔者在开始编写的时候&#xff0c;首先上网查了很多的资料&#xff0c;对伪随机码算…

【HBuilder】手机App推送至Apple App Store过程

一、前言 最近由于公司同事离职&#xff0c;顶替这位同事从事手机App的研发工作&#xff0c;BIM数据平台部门采用的是HBuilder作为手机App的制作环境。本篇介绍我是如何将HBuilder的Release包发布至App Store的。 二、内容 1. 首先登录Apple Developer网站 2. 点击iTunes Conn…

Java性能调优调查结果(第四部分)

这是系列文章中的最后一篇&#xff0c;我们将分析我们在2014年10月进行的Java Performance Tuning Survey的结果。如果您还没有阅读第一篇文章&#xff0c;我建议您首先阅读以下内容&#xff1a; 性能问题的频率和严重性 最受欢迎的监控解决方案 查找根本原因的工具和技术 …

2012年第一个工作日

换代理尝试&#xff0c;竟然可以发博客了。以前的博客太散乱&#xff0c;打算在这里安家。 今天花了一上午时间&#xff0c;在各大网站不停地晃。希望自己能够弄清楚这个快速变化的世界。 2012确切的目标&#xff1a; 1. 工作仍然是首要的&#xff0c;锻炼的能力不同而已&#…

基于ArcEngine的插件式框架

先整理下&#xff0c;过几天把我以前用过的一个插件式GIS框架共享出来。转载于:https://www.cnblogs.com/songhuaiyu/archive/2010/08/16/1800854.html

【JQuery】选择器

一、前言 上一章学习完了Js的一些基本内容&#xff0c;本章开始学习JQuery语法。JQuery的基础语法是&#xff1a; $(selector).action() 那么重要的两个元素&#xff0c;一个是选择器&#xff0c;另一个是行为&#xff01;本章开始学习JQuery的选择器。 二、内容 $("*&quo…

android eclipse 配置 在项目右击选择properties

转载于:https://www.cnblogs.com/guoxiaoyue/p/3485243.html

减少主要GC暂停的频率

这篇文章将讨论一种技术&#xff0c;以减少应用程序等待时间造成的垃圾收集暂停的负担。 正如我几年前所写&#xff0c; 在JVM中无法禁用垃圾收集 。 但是&#xff0c;有一个巧妙的技巧可以用来大大减少长时间停顿的时间和频率。 如您所知&#xff0c;JVM中发生了两个不同的GC…

软件工程中交流的思考

良好的交流可以有效的降低项目的开发成本&#xff0c;相反不但可能数倍的增加成本&#xff0c;甚至可能导致项目的失败。 怎样在项目执行过程进行有效的交流呢&#xff1f; 1. 识别项目中交流主体。 2. 明确交流主题、内容、目标。 3. 做好交流记录、分析、整理、执行。 4. 交流…

【WebGL】《WebGL编程指南》读书笔记——第2章

一、前言 最近看了《WebGL编程指南》这本书&#xff0c;发现还是很有意思的&#xff0c;故每章阅读后做个笔记。 二、正文 Example1&#xff1a;在canvas中绘制2D矩形 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /&…

一个人的网站开发

从零开始开发一个全栈Web应用实录 https://blog.csdn.net/weixin_31347831/article/details/74625813 如何用PHP完整的开发一个网站&#xff1f; https://blog.csdn.net/a6984021/article/details/88787885 一个人如何完成一整个网站的开发&#xff08;推荐好文&#xff0c;看完…

WAI-ARIA对自动完成小部件的支持

在本文中&#xff0c;我想讨论AutoComplete小部件的可访问性。 在您键入该字段时&#xff0c;通常会使用“自动完成”窗口小部件提供建议。 在当前的工作中&#xff0c;我基于Twitter的Typeahead &#xff08;一个灵活JavaScript库&#xff09;实现了JSF组件&#xff0c;该库为…

eclipse中java.lang.OutOfMemoryError: Java heap space错误

Myeclipse中报java.lang.OutOfMemoryError: Java heap space错误 解决办法: 选中被运行的类&#xff0c;点击菜单‘run->run Configuration’&#xff0c;选择(x)Argument标签页下的vm arguments框里 输入 -Xmx800m, 保存运行。问题解决 转载于:https://www.cnblogs.com/vig…

[Vue warn]: Invalid prop: custom validator check failed for prop xxx.问题

在用vue ui框架&#xff08;iview、elementui等&#xff09;做项目&#xff0c;会遇到这种问题 这样的&#xff0c;点那都报错&#xff0c;千辛万苦的付出&#xff0c;却找不到问题在哪 其实很简单&#xff0c;报错都显示出那个组件的问题了 ‘<Form>’这个组件&#xf…

CheckList 如何梳理可减少上线的验证时间(总结篇)

对CheckList的执行发起的思考&#xff1f; &#xff08;1&#xff09;功能越来越多&#xff0c;CheckList越补充越多&#xff0c;执行CheckList时间越来越长&#xff0c;如何减少上线的验证时间&#xff1f;&#xff08;2&#xff09;减少上线验证的时间外&#xff0c;如何保证…

PrimeFaces 5.0 DataTable列切换器

我有机会与PrimeFaces 5.0 DataTable一起工作&#xff0c;并且增强功能很棒。 今天&#xff0c;我只想展示其中的一项新功能……DataTable列切换器。 此功能使您可以通过复选框列表选择显示哪些列。 要使用列切换器&#xff0c;只需添加一个commandButton即可将列选择的选择列…

[恢]hdu 2016

2011-12-14 04:21:57 地址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2016 题意&#xff1a;中文。 mark&#xff1a;wa了2次&#xff0c;a^b^a^b这种交换只能用在a和b不同的时候&#xff0c;否则清零。没考虑第一个元素就是最小值的情况。 代码&#xff1a; # in…

CSS3总结(干货)

1、css3中好用的选择器   :target       //突出显示活动的HTML锚 ::after / ::before{content:" ";}  //content必须有&#xff0c;若无内容&#xff0c;用空格占位 2、文字 a.导入字体&#xff1a; font-face b.文字阴影&#xff1a;text-shadow ps:相…

关于Java泛型和擦除

“编译期间擦除泛型”是常识&#xff08;好吧&#xff0c;类型参数和实参实际上就是被擦除的&#xff09;。 这是由于“类型擦除”而发生的。 但这是错误的&#xff0c;正如许多开发人员所假设的那样&#xff0c;删除了<..>符号内指定的所有内容。 请参见下面的代码&…

关于软件测试学习心得

软件测试是软件开发过程中最重要环节&#xff0c;在进行测试之前需要写测试计划&#xff0c;测试计划需要哪几个部分呢&#xff1f;在郁莲老师的课上教导如何做测试计划。 目录 1 引言 1.1 编写目的 1.2 项目背景和产品简介 1.3 专业术语 2 测试目标 3. 测试范围 3.1 功能性测试…