在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,一经查实,立即删除!

相关文章

【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; 性能问题的频率和严重性 最受欢迎的监控解决方案 查找根本原因的工具和技术 …

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

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

减少主要GC暂停的频率

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

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即可将列选择的选择列…

使用JGit API探索Git内部

您是否想过提交及​​其内容如何存储在Git中&#xff1f; 好吧&#xff0c;我有&#xff0c;在上一个下雨的周末&#xff0c;我有一些空闲时间&#xff0c;所以我做了一些研究。 因为我对Java的感觉比对Bash的感觉要多&#xff0c;所以我使用了JGit和一些学习测试来探索提交的…

Html5 布局方式

在Html5之前&#xff0c;统一采用的是Div css的方式进行布局&#xff0c;但是却和开发人员的命名方式&#xff0c;喜好有关。在新的Html5中&#xff0c;布局却显得更加人性化&#xff0c;更易理解了。如增加了Header&#xff0c;Footer&#xff0c;Section&#xff0c;Aside标签…

PrimeFaces Mobile入门

介绍 如果您已经开发了利用PrimeFaces的应用程序&#xff0c;或者打算开发可在台式机和移动设备上使用的Web应用程序&#xff0c;请考虑将PrimeFaces Mobile用于您的移动实施。 这篇博客文章将介绍一些基础知识&#xff0c;以帮助您开始为现有的PrimeFaces应用程序开发移动界面…

attachEvent和addEventListener

attachEvent和addEventListener在前端开发过程中经常性的使用&#xff0c;他们都可以用来绑定脚本事件&#xff0c;取代在html中写 obj.οnclickmethod。相同点&#xff1a; 它们都是DOM对象的方法&#xff0c;可以实现一种事件绑定多个事件处理函数。 obj document.getElemen…

如果删除github上项目的文件

1. 你要有前面一章的开发平台和github插件&#xff0c;下面就是基于前面来做的。 如何删掉你github上的文件呢&#xff1f;想必你的电脑有一个下载的git工具了&#xff0c;如果还是没有的话&#xff0c;请用npm下载一个git。这是我已经下载好的。 2. 然后打开这个git&#xff…

在WildFly和OpenShift上的WebSocket聊天

聊天是解释WebSocket的最典型示例之一。 它是一个相当常用的界面&#xff0c;可以很容易地解释WebSocket的基本概念。 当然&#xff0c;Java EE 7 WebSocket也有一个&#xff0c; 在这里可用 &#xff01; 您可以使用以下步骤在WildFly上轻松运行它&#xff1a; curl -O http:…

Ubuntu20.04纯命令配置PCL(点云库)

Ubuntu20.04纯命令配置PCL&#xff08;点云库&#xff09; 最近在学习点云库&#xff08;PCL&#xff09;的使用&#xff0c;第一步就是在自己的电脑安装配置PCL。 首先&#xff0c;对于ubuntu 16.04以上版本&#xff0c;可以直接使用命令进行安装&#xff0c;新建好一个文件夹…

css html应用实例1:滑动门技术的简单实现

关于滑动门&#xff0c;现在的页面中好多地方都会用到滑动门&#xff0c;一般用作于导航背景&#xff0c;它的官方解释如下&#xff1a; 滑动门&#xff1a;根据文本自适应大小&#xff0c;根据背景的层叠性制作&#xff0c;并允许他们在彼此之上进行滑动&#xff0c;以创造出…

魔戒1

转载于:https://www.cnblogs.com/moonlightpeng/p/11240880.html

jQuery应用实例2:简单动画

效果&#xff1a; 代码&#xff1a; 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">2 <html xmlns"http://www.w3.org/1999/xhtml">3 <head>…

Spring Data JPA教程:简介

创建使用Java Persistence API的存储库是一个繁琐的过程&#xff0c;需要大量时间&#xff0c;并且需要大量样板代码。 通过执行以下步骤&#xff0c;我们可以消除一些样板代码&#xff1a; 创建一个抽象的基础存储库类&#xff0c;该类为实体提供CRUD操作。 创建扩展抽象基础…