2KB项目,专业的源码交易网站 帮助 收藏 每日签到

运用 JSR 356 API 构建 Java WebSocket 使用

  • 时间:2019-06-01 21:15 编辑:2KB 来源:2KB.COM 阅读:566
  • 扫一扫,手机访问
  • 分享
摘要:
WebSocket Tyrus 英文原文:How to build Java WebSocket Applications Using the JSR 356 API

大师都晓得如许一个现实,那就是HTTP(Hypertext Transfer Protocol)是一个无形态的恳求-响应式协议。HTTP协议的这类容易设计使它颇具扩大性却不敷高效,而且不合适于频仍交互的及时收集使用。HTTP被设计用来实行文档同享而不是用来树立频仍交互的收集使用。HTTP生来就不太正轨,对每个http恳求/呼应,都要经过线路传输很多头信息。

在HTTP 1.1版本之前,每个提交到Server的恳求都会创立一个新的链接。这类状况在HTTP 1.1中经过引入HTTP耐久化衔接得以改良。耐久化衔接答应web阅读器复用异样的衔接来获得图片,剧本等等。

HTTP被设计成半双工的,这意味着统一时辰只答应向一个标的目的上传输数据。Walkie-talkie是一个半双工设备的例子,由于一个时辰只能有一个人措辞。开发者们曾经发明出了一些任务办法或者应对办法来克制HTTP的这个缺陷。这些任务办法包含轮询,长效轮询和

运用轮询时,客户端采取同步伐用来从Server获得信息。假如Server有新信息,它会在呼应中前往数据。不然,就不会有信息前往给客户端,然后客户端会在一段时间以后再次创立一个新的衔接。这是一种很低效却很容易的取得及时行动的方法。长效轮询是另外一种任务办法,客户端会对Server倡议一个衔接,Server会坚持该衔接直到有可用数据或者超越了指定超期时间。长效轮询也被称为comet。因为同步的HTTP和这些异步使用之间的不适配,这些计划易于庞杂化,无规范化和低效化。

跟着时间的推移,关于在客户端和Server之间树立基于规范的、双向的、全双工通道的需求,曾经增加了。在本文中,我们会看到WebSockets是怎么协助处理这些问题的,然后了解一下怎么在Java中运用JSR 356 API来构建基于WebSocket的使用。

请留意本文不会会商到OpenShift WebSocket支撑。假如你想了解OpenShift WebSocket支撑,请参考Marek Jelen这篇文章

甚么是WebSocket?

一个WebSocket是经过一个自力的TCP衔接完成的、异步的、双向的、全双工的音讯通报完成机制。WebSockets不是一个HTTP衔接,却运用HTTP来领导一个WebSocket衔接。一个全双工的系统答应同时实行双向的通信。海洋线路德律风是一个全双工设备的例子,由于它们答应两个通话者同时讲话并被对方听到。最后WebSocket被提议作为HTML5标准的一部分,HTML5许诺给当代的交互式的web使用带来开发上的便当和收集效力,可是随后WebSocket被移到一个仅用来寄存WebSockets标准的自力的规范文档里。它包括两件工作 -- WebSocket协议标准,即2011年12月发布的RFC 6455,和WebSocket JavaScript API

WebSocket协议应用HTTP 升级头信息来把一个HTTP衔接升级为一个WebSocket衔接。HTML5 WebSockets 处理了很多招致HTTP不合适于及时使用的问题,而且它经过防止庞杂的任务方法使得使用构造很容易。

最新的阅读器都支撑WebSockets,以下图所示。该信息来自于http://caniuse.com/#feat=websockets.

WebSocket browser support

WebSocket是怎么任务的?

每个WebSocket衔接的性命都是从一个HTTP恳求Start的。HTTP恳求跟其他恳求很相似,除它具有一个Upgrade头信息。Upgrade头信息表现一个客户端盼望把衔接升级为分歧的协议。对WebSockets来讲,它盼望升级为WebSocket协议。当客户端和Server经过底层衔接第一次握手时,WebSocket衔接经过把HTTP协议转换升级为WebSockets协议而得以树立。一旦WebSocket衔接成功树立,音讯就能够在客户端和Server之间实行双向发送。

WebSockets带来了功能,容易化和更少带宽耗费

  1. WebSockets比其它任务方法比方轮询更有效也更高效。由于它需求更少的带宽而且下降了延时。
  2. WebSockets简化了及时使用的构造系统。
  3. WebSockets在点到点发送音讯时不需求头信息。这明显的下降了带宽。

WebSocket运用案例

一些可能的WebSockets运用案例有:

  • 谈天使用
  • 多人游戏
  • 股票交易和金融使用
  • 文档协作编辑
  • 社交使用

Java中运用WebSockets

在Java社区中下面的情况很广泛,分歧的供给商和开发者编写类库来运用某项技术,一段时间以后当该技术成熟时它就会被规范化,来使开发者可以在分歧完成之间相互操作,而不必冒供给商锁定的风险。当JSR 365启动时,WebSocket就曾经有了超越20个分歧的Java完成。它们中的大大多数都有着分歧的API。JSR 356是把Java的WebSocket API实行规范化的效果。开发者们可以撇开详细的完成,直接运用JSR 356 API来创立WebSocket使用。WebSocket API是完整由事情驱动的。

JSR 356 -- WebSockets的Java API

JSR 356,WebSocket的Java API,规则了开发者把WebSockets 整合进他们的使用时可使用的Java API — 包含Server端和Java客户端。JSR 356是行将出台的Java EE 7规范中的一部分。这意味着一切Java EE 7兼容的使用Server都将有一个恪守JSR 356规范的WebSocket协议的完成。开发者也能够在Java EE 7使用Server以外运用JSR 356。今朝Apache Tomcat 8的开发版本将会增加基于JSR 356 API的WebSocket支撑。

一个Java客户端可使用兼容JSR 356的客户端完成,来衔接到WebSocketServer。对web客户端来讲,开发者可使用WebSocket JavaScript API来和WebSocketServer实行通信。WebSocket客户端和WebSocketServer之间的差别,仅在于二者之间是经过甚么方法衔接起来的。一个WebSocket客户端是一个WebSocket终端,它初始化了一个到对方的衔接。一个WebSocketServer也是一个WebSocket终端,它被发布出去而且等候来自对方的衔接。在客户端和Server端都有回调监听办法 --  onOpen , onMessage , onError, onClose。前面我们创立一个使用的时分再来更具体的了解这些。

Tyrus -- JSR 356 参考完成

TyrusJSR 356的参考完成。我们会鄙人一节中以自力形式用Tyrus开发一个容易使用。一切Tyrus组件都是用Java SE 7编译器实行构建的。这意味着,你也最少需求不低于Java SE 7的运转情况才干编译和运转该使用示例。它不能够在Apache Tomcat 7中运转,由于它依靠于servlet 3.1标准。

运用WebSockets开发一个单词游戏

如今我们预备创立一个十分容易的单词游戏。游戏者会失掉一个字母排序紊乱的单词,他或她需求把这个单词恢恢复样。我们将为每次游戏运用一个独自的衔接。

本使用的源代码可以从github获得 https://github.com/shekhargulati/wordgame

步调 1 : 创立一个模板Maven项目

Start时,我们运用Maven原型来创立一个模板Java项目。运用下面的号令来创立一个基于Maven的Java项目。

$ mvn archetype:generate -DgroupId=com.shekhar -DartifactId=wordgame -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

步调 2 : 向pom.xml中添加需求的依靠

正如上节中提到的,你需求Java SE 7来构建运用Tyrus的使用。要在你的maven项目中运用Java 7,你需求在设置装备摆设中添加maven编译器插件来运用Java 7,以下所示。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <compilerVersion>1.7</compilerVersion>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>

下面,添加对JSR 356 API的依靠。javax.websocket-api的以后版本是 1.0。

<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.0</version>
</dependency>

下面我们将要添加与Tyrus JSR 356完成相干的依靠。tyrus-server包供给了JSR 356服务端WebSocket API完成,tyrus-client包供给了JSR356客户端WebSocket API完成。

<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-server</artifactId>
    <version>1.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-client</artifactId>
    <version>1.1</version>
</dependency>

最初,我们添加tyrus-container-grizzly依靠到我们的pom.xml中。这将供给一个自力的容器来安排WebSocket使用。

<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-container-grizzly</artifactId>
    <version>1.1</version>
</dependency>

你可以在这里检查完好的pom.xml文件。

步调 3 : 编写第一个JSR 356 WebSocketServer终端

如今我们的项目曾经设置终了,我们将Start编写WebSocketServer终端。你可以经过运用@ServerEndpoint注解来把任何Java POJO类声明为WebSocketServer终端。开发者也能够指定用来安排终真个URI。URI要相对WebSocket容器的根途径,必需以"/"扫尾。在以下所示的代码中,我们创立了一个十分容易的WordgameServerEndpoint。

package com.shekhar.wordgame.server;
 
import java.io.IOException;
import java.util.logging.Logger;
 
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.CloseReason.CloseCodes;
import javax.websocket.server.ServerEndpoint;
 
@ServerEndpoint(value = "/game")
public class WordgameServerEndpoint {
 
    private Logger logger = Logger.getLogger(this.getClass().getName());
 
    @OnOpen
    public void onOpen(Session session) {
        logger.info("Connected ... " + session.getId());
    }
 
    @OnMessage
    public String onMessage(String message, Session session) {
        switch (message) {
        case "quit":
            try {
                session.close(new CloseReason(CloseCodes.NORMAL_CLOSURE, "Game ended"));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            break;
        }
        return message;
    }
 
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason));
    }
}

@OnOpen注解用来标注一个办法,在WebSocket衔接被翻开时它会被挪用。每个衔接都有一个和它联系关系的session。在上面的代码中,当onOpen()办法被挪用时我们打印了一下session的id。对每个WebSocket衔接来讲,被@OnOpen标注的办法只会被挪用一次。

@OnMessage注解用来标注一个办法,每当收到一个音讯时它都会被挪用。一切营业代码都需求写入该办法内。上面的代码中,当从客户端收到"quit"音讯时我们会封闭衔接,其它状况下我们只是把音讯原封不动的前往给客户端。所以,在收到"quit"音讯之前,一个WebSocket衔接将会不断翻开。当收到加入音讯时,我们在session工具上挪用了封闭办法,通知它session的缘由。在示例代码中,我们说当游戏完毕时这是一个正常的封闭。

@OnClose注解用来标注一个办法,当WebSocket衔接封闭时它会被挪用。

步调 4 : 编写第一个JSR 356 WebSocket客户端终端

@ClientEndpoint注解用来标志一个POJO WebSocket客户端。相似于javax.websocket.server.ServerEndpoint,经过@ClientEndpoint标注的POJO可以使它的那些运用了收集套接字办法级别注解的办法,成为收集套嚼狭氟命周期办法。

package com.shekhar.wordgame.client;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;
 
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.DeploymentException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
 
import org.glassfish.tyrus.client.ClientManager;
 
@ClientEndpoint
public class WordgameClientEndpoint {
 
    private Logger logger = Logger.getLogger(this.getClass().getName());
 
    @OnOpen
    public void onOpen(Session session) {
        logger.info("Connected ... " + session.getId());
        try {
            session.getBasicRemote().sendText("start");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
 
    @OnMessage
    public String onMessage(String message, Session session) {
        BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
        try {
            logger.info("Received ...." + message);
            String userInput = bufferRead.readLine();
            return userInput;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
 
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        logger.info(String.format("Session %s close because of %s", session.getId(), closeReason));
    }
 
 
}

在上面的代码中,当WebSocket 衔接被翻开时,我们发送了一个"start"音讯给Server。每当从Server收到一个音讯时,被@OnMessage注解标注的onMessage办法就会被挪用。它起首记载下音讯让后等候用户的输出。用户的输出随后会被发送给Server。最初,当WebSocket 衔接封闭时,@OnClose标注的onClose()办法被被挪用。正如你所看到的,客户单和Server真个代码编程形式是类似的。这使得经过JSR 356 API来编写WebSocket使用的开发任务变得很轻易。

其它翻译版本 (1) 加载中 本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。 2KB翻译任务按照 CC 协议,假如我们的任务有进犯到您的权益,请实时联络我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部