HTML5+websocket实现举例

本文介绍如何使用 HTML5 和 JavaEE 实现 WebSocket 的双向通信。包括 WebSocket 服务器端点的定义及客户端页面的设计,展示了如何建立连接并进行数据交换。
在本教程中,我们将实现一个HTML5 websocket诉诸于Java EE websocket实现(ServerEndpoint)。

介绍

HTML5规范了web浏览器的能力建立全双工TCP连接与websocket服务器兼容。

换句话说,浏览器现在可以与服务器建立连接,通过相同的发送或接收数据建立通信通道,无需由HTTP协议本身引入的开销。

在本教程中,我们将实现一个简单的Java EE环境中websocket服务器端点以及相应的客户端发送和接收数据的基础设施。

本教程将下列环境:

 

  1. Ubuntu 12.04
  2. JDK 1.7.0.21
  3. Glassfish 4.0
请注意 :介绍了WebSockets支持Java EE 7

WebSocket服务器端点

让我们定义一个Java EE websocket服务器端点:

WebSocketTest.java

package com.byteslounge.websockets; import java.io.IOException; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/websocket") public class WebSocketTest { @OnMessage public void onMessage(String message, Session session) throws IOException, InterruptedException { // Print the client message for testing purposes System.out.println("Received: " + message); // Send the first message to the client session.getBasicRemote().sendText("This is the first server message"); // Send 3 messages to the client every 5 seconds int sentMessages = 0; while(sentMessages < 3){ Thread.sleep(5000); session.getBasicRemote(). sendText("This is an intermediate server message. Count: " + sentMessages); sentMessages++; } // Send a final message to the client session.getBasicRemote().sendText("This is the last server message"); } @OnOpen public void onOpen() { System.out.println("Client connected"); } @OnClose public void onClose() { System.out.println("Connection closed"); } } 

正如你可能已经注意到我们进口的几类 javax.websocket 包中。

@ServerEndpoint 注释用于类型水平和当前类定义为一个websocket服务器端点。 这个注释中使用的值代表端点的URL将监听客户端连接。

onOpen onClose 方法注释与 @OnOpen @OnClose 分别。 这些注释几乎是不言而喻的:他们定义哪些方法将呼吁一个新的客户端连接和断开。

方法 onMessage 有注释的 @OnMessage 。 这个注释定义的方法将调用当收到新消息从客户端。 注意,这个方法可以定义一个可选参数的类型 javax.websocket.Session (在我们的例子中 会话 参数)。 如果这个参数是定义了容器将注入会话相关联与当前客户端发送的消息被处理。

在我们的例子中我们只是客户端消息内容写入到标准输出。 然后我们继续发送消息到客户端之后,用5秒间隔3测试消息。 最后我们最后一个消息发送到客户端。

客户端

现在我们需要写我们websocket测试应用程序的客户端:

page.html

<!DOCTYPE html>
<html>
<head> <title>Testing websockets</title> </head> <body> <div> <input type="submit" value="Start" onclick="start()" /> </div> <div id="messages"></div> <script type="text/javascript"> var webSocket = new WebSocket('ws://localhost:8080/byteslounge/websocket'); webSocket.onerror = function(event) { onError(event) }; webSocket.onopen = function(event) { onOpen(event) }; webSocket.onmessage = function(event) { onMessage(event) }; function onMessage(event) { document.getElementById('messages').innerHTML += '<br />' + event.data; } function onOpen(event) { document.getElementById('messages').innerHTML = 'Connection established'; } function onError(event) { alert(event.data); } function start() { webSocket.send('hello'); return false; } </script> </body> </html> 

这是一个简单的测试页面,其中包含的JavaScript创建一个websocket连接了websocket服务器端点。

onOpen 方法将调用当我们与服务器建立连接端点。

onError 方法被调用时,当一个错误发生在客户端和服务器之间的通信。

onMessage 方法将调用从服务器收到消息时。 在我们的例子中我们只是附加DOM的从服务器接收到的消息。

我们连接到websocket服务器端点通过构造 新的WebSocket() 并通过端点URL:

ws:/ / localhost:8080 / byteslounge / websocket

测试

我们现在可以测试我们的应用程序通过访问测试页面:

http://localhost:8080 / byteslounge / page.html

我们将会看到的 连接建立 消息如预期:

http://localhost:8080 / byteslounge / page.html
Websocket - Connection established

现在当我们按下这个按钮将通过websocket服务器发送初始消息和接收后续测试由服务器发送的消息:

由服务器发送的消息和接收的客户端
Websocket - Messages exchanged

websocket握手

客户机和服务器之间的TCP连接建立后的发生在HTTP协议握手。 很容易观察握手通过HTTP流量调试器。 一旦我们创建的 WebSocket 实例在客户端请求和各自的服务器响应会发生如下:

请注意 :我们将只包括相关的HTTP头websockets握手

要求:

获得/ byteslounge / websocket HTTP / 1.1
连接:升级
升级:websocket
Sec-WebSocket-Key:wVlUJ / tu9g6EBZEh51iDvQ = =

回应:

HTTP / 1.1 101 Web Socket协议握手
升级:websocket
Sec-WebSocket-Accept:2 tnh + 0 h5gtx019lci6mnvs66psy =

请注意,客户端请求协议升级到WebSocket协议通过使用 连接:升级 升级:websocket HTTP头信息。 服务器响应,客户端请求被接受,它将改变协议WebSocket(使用HTTP状态代码101):

HTTP / 1.1 101 Web Socket协议握手

下载样例

示例源代码可供下载的这个页面。 测试在Glassfish 4被处决(你需要一个Java EE 7兼容的应用程序服务器)。

从本文下载源代码

 

转载于:https://www.cnblogs.com/lyl693/p/6656716.html

<think> 我们正在讨论WebSocket实现方式,特别是关于是否需要通过Nginx代理的问题。 用户的问题:WebSocket是否可以不通过Nginx实现? 回答思路: 1. 明确回答:完全可以不通过Nginx实现WebSocket通信。 2. 解释原因:WebSocket协议本身是独立的,它可以在客户端和服务器之间直接建立连接。 3. 使用Nginx的场景:当需要负载均衡、安全加固(如SSL终止)、统一入口等时才需要Nginx作为反向代理。 4. 直接实现的优势:减少中间环节,降低延迟,简化架构。 5. 直接实现的劣势:需要自己处理安全、负载均衡等问题。 6. 举例说明:可以使用各种后端框架(如Node.js的ws库、Python的WebSockets库等)直接创建WebSocket服务器。 引用说明:根据用户提供的引用内容,引用[1]和[2]都提到了使用Nginx作为WebSocket代理的场景,但并没有说必须使用。引用[3]的标题提到“NGINX如何支持WebSocket协议”,这也说明Nginx只是支持,而不是必须。 因此,我们可以在回答中引用这些资料,同时说明不通过Nginx也是可行的。 结构化回答: 一、直接结论 二、为什么可以不通过Nginx 三、直接实现的优势与劣势 四、如何直接实现(简单示例) 五、适用场景对比 最后,生成相关问题。 注意:使用中文,按照要求格式化数学公式(虽然这个问题可能没有数学公式,但如果有的话要遵守规则)。 </think> ### WebSocket 能否不通过 Nginx 实现? **完全可以**。WebSocket 协议本身是独立的通信协议,完全不依赖 Nginx 即可实现完整的通信功能。以下是关键说明: #### 一、无需 Nginx 的实现原理 1. **协议独立性** WebSocket 协议(RFC 6455)基于 TCP 层实现,只需满足两个条件即可建立连接: - 客户端支持 WebSocket API(浏览器/Node.js 等) - 服务端实现 WebSocket 握手逻辑(如 Node.js 的 `ws` 库、Python 的 `websockets`) 2. **直接通信路径** ```mermaid graph LR A[客户端] -- WebSocket直连 --> B[服务端] ``` 客户端可直接通过 `ws://your-server:port` 连接后端服务,无需任何中间代理[^3]。 #### 二、实现方式示例(Node.js) ```javascript // 服务端代码 (Node.js + ws 库) const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); // 直接监听端口 wss.on('connection', (ws) => { ws.send('Connected directly!'); // 客户端直接收到消息 }); ``` ```html <!-- 客户端代码 --> <script> const socket = new WebSocket('ws://your-server-ip:8080'); // 直连服务端 socket.onmessage = (e) => console.log(e.data); // 输出 "Connected directly!" </script> ``` #### 三、不通过 Nginx 的适用场景 | **场景** | **优势** | **典型用例** | |------------------------|----------------------------------|---------------------------| | 开发/测试环境 | 部署简单,调试方便 | 本地开发工具链 | | 内网服务通信 | 延迟低(减少代理跳转) | 微服务间实时数据同步 | | 单点小型应用 | 节省服务器资源 | 物联网设备管理后台 | | 协议定制需求 | 避免代理层修改头部/超时限制 | 自定义二进制协议传输 | #### 四、使用 Nginx 的场景对比 | **特性** | **直连 WebSocket** | **通过 Nginx 代理** | |------------------|----------------------------------|----------------------------------| | 部署复杂度 | ⭐️ 简单(无需配置代理) | ⭐️⭐️⭐️ 需配置 Nginx 规则 | | 安全性 | ⭐️⭐️ 依赖应用层实现 | ⭐️⭐️⭐️ 可配置 WAF/SSL 卸载 | | 负载均衡 | ❌ 不支持 | ⭐️⭐️⭐️ 支持 upstream 分发 | | 高并发处理 | ⭐️ 受限于单进程 | ⭐️⭐️⭐️ 利用 Nginx 事件驱动模型 | > 提示:生产环境中,若需**负载均衡**或**统一入口管理**,则推荐使用 Nginx 代理,否则直连更高效[^1][^3]。 ### 小结 WebSocket 本质是独立协议,**无需 Nginx 即可实现完整功能**。在简单架构、低延迟需求或开发环境中,直连是更轻量的方案;而大型分布式系统则需要 Nginx 提供负载均衡和安全加固能力[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值