第 14 章 创建 Jakarta WebSocket 应用程序
Jakarta WebSocket 协议提供 Web 客户端和服务器之间的双向通信。客户端和服务器之间的通信基于事件,与基于轮询的方法相比,可以更快地处理和缩小带宽。Jakarta WebSocket 使用 JavaScript API 以及使用 Jakarta WebSocket 规格的客户端 Jakarta WebSocket 端点,可用于 Web 应用。
首先作为 HTTP 连接在客户端和服务器之间建立连接。然后,客户端使用 Upgrade
标头请求 Jakarta WebSocket 连接。然后,所有通信都是相同的 TCP/IP 连接的全双工,而数据开销最少。由于每条消息都不包含不必要的 HTTP 标头内容,Jakarta WebSocket 通信需要更小的带宽。其结果是适用于应用程序的低延迟通信路径,需要实时响应。
JBoss EAP Jakarta WebSocket 实施为服务器端点提供全面的依赖注入支持,但它不为客户端端点提供上下文和依赖注入服务。
Jakarta WebSocket 应用程序需要以下组件和配置更改:
- 启用了 HTML 客户端或 Jakarta WebSocket 的 Java 客户端。您可以在此位置验证 HTML 客户端浏览器支持:http://caniuse.com/#feat=websockets
- Jakarta WebSocket 服务器端点类。
- 将项目依赖项配置为声明对 Jakarta WebSocket API 的依赖关系。
创建 Jakarta WebSocket 应用程序
以下代码示例取自 JBoss EAP 附带的 websocket-hello
快速入门。它是 Jakarta WebSocket 应用的一个简单示例,它打开连接、发送消息并关闭连接。它不实施任何其他功能或包含任何错误处理,这是真实应用所需要的。
创建 JavaScript HTML 客户端。
以下是 Jakarta WebSocket 客户端的示例。它包含这些 JavaScript 功能:
-
connect()
:此功能创建通过 Jakarta WebSocket URI 的 Jakarta WebSocket 连接。资源位置与服务器端点类中定义的资源匹配。此功能还会截获和处理 Jakarta WebSocketonopen
、onmessage
、onerror
和onclose
。 -
sendMessage()
:此功能获取表单中输入的名称,创建消息并使用 WebSocket.send()命令发送。 -
disconnect()
:此功能会发出 WebSocket.close()命令。 -
displayMessage()
:此功能将页面上的显示消息设置为 Jakarta WebSocket endpoint 方法返回的值。 DisplayStatus()
:此函数显示 Jakarta WebSocket 连接状态。示例:应用程序
index.html
Code<html> <head> <title>WebSocket: Say Hello</title> <link rel="stylesheet" type="text/css" href="resources/css/hello.css" /> <script type="text/javascript"> var websocket = null; function connect() { var wsURI = 'ws://' + window.location.host + '/websocket-hello/websocket/helloName'; websocket = new WebSocket(wsURI); websocket.onopen = function() { displayStatus('Open'); document.getElementById('sayHello').disabled = false; displayMessage('Connection is now open. Type a name and click Say Hello to send a message.'); }; websocket.onmessage = function(event) { // log the event displayMessage('The response was received! ' + event.data, 'success'); }; websocket.onerror = function(event) { // log the event displayMessage('Error! ' + event.data, 'error'); }; websocket.onclose = function() { displayStatus('Closed'); displayMessage('The connection was closed or timed out. Please click the Open Connection button to reconnect.'); document.getElementById('sayHello').disabled = true; }; } function disconnect() { if (websocket !== null) { websocket.close(); websocket = null; } message.setAttribute("class", "message"); message.value = 'WebSocket closed.'; // log the event } function sendMessage() { if (websocket !== null) { var content = document.getElementById('name').value; websocket.send(content); } else { displayMessage('WebSocket connection is not established. Please click the Open Connection button.', 'error'); } } function displayMessage(data, style) { var message = document.getElementById('hellomessage'); message.setAttribute("class", style); message.value = data; } function displayStatus(status) { var currentStatus = document.getElementById('currentstatus'); currentStatus.value = status; } </script> </head> <body> <div> <h1>Welcome to Red Hat JBoss Enterprise Application Platform!</h1> <div>This is a simple example of a Jakarta WebSocket implementation.</div> <div id="connect-container"> <div> <fieldset> <legend>Connect or disconnect using websocket :</legend> <input type="button" id="connect" onclick="connect();" value="Open Connection" /> <input type="button" id="disconnect" onclick="disconnect();" value="Close Connection" /> </fieldset> </div> <div> <fieldset> <legend>Type your name below, then click the `Say Hello` button :</legend> <input id="name" type="text" size="40" style="width: 40%"/> <input type="button" id="sayHello" onclick="sendMessage();" value="Say Hello" disabled="disabled"/> </fieldset> </div> <div>Current WebSocket Connection Status: <output id="currentstatus" class="message">Closed</output></div> <div> <output id="hellomessage" /> </div> </div> </div> </body> </html>
-
创建 Jakarta WebSocket 服务器端点。
您可以使用以下任一方法之一创建 Jakarta WebSocket 服务器端点:
-
编程端点
:端点扩展端点类。 -
标注
的端点
:端点类使用注释来与 Jakarta WebSocket 事件交互。代码比编程端点更容易。
以下代码示例使用注解的端点方法并处理以下事件:
-
@ServerEndpoint
注释将此类识别为 Jakarta WebSocket 服务器端点,并指定路径。 -
打开 Jakarta WebSocket 连接时会触发
@OnOpen
注释。 -
收到消息时会触发
@OnMessage
注释。 当 Jakarta WebSocket 连接关闭时,会触发
@OnClose
注释。示例:Jkarta WebSocket Endpoint Code
package org.jboss.as.quickstarts.websocket_hello; import javax.websocket.CloseReason; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/websocket/helloName") public class HelloName { @OnMessage public String sayHello(String name) { System.out.println("Say hello to '" + name + "'"); return ("Hello" + name); } @OnOpen public void helloOnOpen(Session session) { System.out.println("WebSocket opened: " + session.getId()); } @OnClose public void helloOnClose(CloseReason reason) { System.out.println("WebSocket connection closed with CloseCode: " + reason.getCloseCode()); } }
-
在项目 POM 文件中声明 Jakarta WebSocket API 依赖项。
如果使用 Maven,请将以下依赖项添加到
pom.xml
项目:示例:Maven 依赖性
<dependency> <groupId>org.jboss.spec.javax.websocket</groupId> <artifactId>jboss-websocket-api_1.1_spec</artifactId> <scope>provided</scope> </dependency>
JBoss EAP 随附的快速入门包括额外的 Jakarta WebSocket 客户端和端点代码示例。