欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > WebSocket

WebSocket

2024/11/29 18:57:15 来源:https://blog.csdn.net/m0_73837751/article/details/144033129  浏览:    关键词:WebSocket

1. 什么是 WebSocket?

WebSocket 是一种网络通信协议,它在单个 TCP 连接上提供全双工通信(Full-Duplex Communication)的能力,允许服务器和客户端之间实时传输数据。

  1. 协议特点

    • 全双工通信:服务器和客户端可以主动发送消息,而不是传统 HTTP 的请求-响应模式。
    • 长连接:建立一次连接后,可以持续使用,直到一方主动关闭。
    • 低延迟:消息通过帧(Frame)发送,减少了传统 HTTP 头信息带来的开销。
    • 高效率:适合实时性要求高的场景。
  2. 工作原理

    • 握手阶段:客户端通过 HTTP 发起 WebSocket 升级请求,服务端返回 101 Switching Protocols,连接升级为 WebSocket 协议。
    • 通信阶段:在连接建立后,数据通过轻量级的帧格式进行传输。
    • 关闭阶段:一方主动发送关闭帧,连接断开。

2. WebSocket 的作用

WebSocket 的主要作用是实现实时通信,即当数据在服务器或客户端发生变化时,可以立即推送到对方,而无需轮询(Polling)或长轮询(Long Polling)。

  1. 实时数据传输

    • WebSocket 可以持续保持连接,无需频繁建立和关闭,适合快速传递实时数据。
  2. 服务器主动推送

    • 服务器可以主动向客户端发送消息,减少客户端对服务器的频繁请求。
  3. 节省带宽和资源

    • WebSocket 消息帧中没有冗余的 HTTP 头部信息,减少了带宽占用。
    • 对于高频通信,WebSocket 比传统的 HTTP 更高效。

3. WebSocket 与 HTTP 的区别

特性HTTP(传统)WebSocket(实时)
通信模型请求-响应模型,客户端必须发起请求才能获得响应双向通信,服务端和客户端都可以主动发送消息
连接状态每次请求建立新的连接连接建立后保持长连接
协议头开销每次请求和响应都包含完整的 HTTP 头部信息初次握手后,数据帧格式简单,无头部冗余
适用场景低频通信、非实时性场景高频通信、实时性要求高的场景

4. WebSocket 在 Java 开发中的使用场景

1.实时聊天系统

  • 场景描述:聊天室、私聊、群聊。
  • 实现功能
    • 用户之间实时发送和接收消息。
    • 服务器广播消息给多个用户。
  • 优势:相比轮询,WebSocket 的双向通信更高效。

2.实时通知和推送

  • 场景描述:例如实时股票价格更新、系统消息推送、用户活动通知。
  • 实现功能
    • 服务器可以主动向客户端推送数据。
  • 优势:低延迟,用户体验更好。

3.实时数据流

  • 场景描述:例如在线游戏的实时状态同步、物联网设备的数据流传输。
  • 实现功能
    • 客户端和服务器持续同步状态或传输数据。
  • 优势:节省带宽,支持大规模并发。

4.实时协作工具

  • 场景描述:例如多人协作文档编辑、实时白板。
  • 实现功能
    • 服务器实时广播用户的操作给其他参与者。
  • 优势:多用户实时协作,延迟低。

5.在线教育

  • 场景描述:实时课堂互动、学生提问、教师推送消息。
  • 实现功能
    • 服务器推送教学内容或问题答案。
  • 优势:实时互动,提升教学体验。

6.实时监控和仪表盘

  • 场景描述:例如服务器运行状态、日志监控、设备运行状态监控。
  • 实现功能
    • 实时向用户展示系统状态或日志信息。
  • 优势:无需刷新页面即可获得最新状态。

7.在线游戏

  • 场景描述:实时多人游戏的状态同步和交互。
  • 实现功能
    • 玩家操作即时同步到服务器和其他玩家。
  • 优势:低延迟、高效率。

5.WebSocket 在 Java 中的实现与支持工具

技术栈归属特点适用场景优点缺点
Socket.IO前端- 基于 WebSocket 的封装,支持事件驱动和自动降级机制浏览器端实时通信,如聊天系统、通知推送、协作工具- 易用,前端开发体验优秀
- 跨浏览器兼容性强
- 性能一般,依赖 Node.js 环境
javax.websocket后端- Java 官方 WebSocket 标准 API,轻量级简单实时通信,如聊天室、通知推送- 简单易用,标准化
- 无框架依赖
- 功能基础,缺乏高级特性
Spring WebSocket后端- 基于 javax.websocket 增强实现,支持 STOMP 和 SockJS 降级Spring Boot 项目中的实时通信,支持广播和订阅- 与 Spring 生态无缝集成
- 功能丰富
- 性能稍逊于底层框架(如 Netty)
Netty后端- 高性能网络通信框架,支持多协议(TCP、UDP、HTTP、WebSocket 等)高并发需求,如在线游戏、实时推送、物联网- 性能极高
- 灵活性强
- 学习曲线陡峭
- 开发复杂
Netty-socketio后端- 基于 Netty 的封装框架,提供与 Socket.IO 类似的事件驱动模型高并发实时通信,如实时聊天、事件推送- 性能高
- 开发简单,API 易用
- 灵活性不如 Netty
- 功能局限于 WebSocket


6.在 Java 中使用 javax.websocket 实现实时通信 

1. WebSocket 的使用步骤

在 Java 中使用 javax.websocket 实现实时通信时,需要完成以下步骤:

  1. 引入必要的依赖
    WebSocket 的标准 API 是 Java EE 的一部分。需要引入 javax.websocket 和 WebSocket 的实现(如 Tyrus)。

  2. 创建 WebSocket 服务端
    使用 @ServerEndpoint 注解定义 WebSocket 端点,处理客户端的连接、消息和断开事件。

  3. 配置 WebSocket 服务端
    在 Spring Boot 中注册 WebSocket 端点,使其能与 Web 应用程序协同运行。

  4. 创建 WebSocket 客户端(可选)
    使用 @ClientEndpoint 注解定义客户端端点,用于连接服务端并实现双向通信。

  5. 启动服务并进行通信
    测试服务端与客户端之间的实时消息交换。


2. 引入依赖

在 Spring Boot 项目中,引入以下依赖:

<dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version>
</dependency>
<dependency><groupId>org.glassfish</groupId><artifactId>tyrus-server</artifactId><version>1.17</version>
</dependency>
  • javax.websocket-api 提供 WebSocket API 接口。
  • tyrus-server 是 WebSocket 的实现库,用于支持运行。

3. 创建 WebSocket 服务端

在 Java 中,使用 @ServerEndpoint 注解定义服务端。

完整代码示例

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;@ServerEndpoint("/websocket")
public class WebSocketServer {// 存储所有客户端会话private static final CopyOnWriteArraySet<WebSocketServer> clients = new CopyOnWriteArraySet<>();// 当前会话private Session session;// 当客户端连接成功时触发@OnOpenpublic void onOpen(Session session) {this.session = session; // 保存当前会话clients.add(this); // 添加到客户端集合System.out.println("新的连接已建立,当前连接数:" + clients.size());sendMessage("欢迎加入 WebSocket 通信!");}// 当收到客户端消息时触发@OnMessagepublic void onMessage(String message, Session session) {System.out.println("收到客户端消息:" + message);broadcast("服务器收到消息:" + message); // 广播给所有客户端}// 当连接关闭时触发@OnClosepublic void onClose(Session session) {clients.remove(this); // 从客户端集合中移除System.out.println("连接已关闭,当前连接数:" + clients.size());}// 当发生错误时触发@OnErrorpublic void onError(Session session, Throwable error) {System.err.println("发生错误:" + error.getMessage());}// 向当前客户端发送消息private void sendMessage(String message) {try {this.session.getBasicRemote().sendText(message); // 发送文本消息} catch (IOException e) {e.printStackTrace();}}// 向所有客户端广播消息private void broadcast(String message) {for (WebSocketServer client : clients) {try {client.session.getBasicRemote().sendText(message);} catch (IOException e) {e.printStackTrace();}}}
}

代码详解

  • 类注解 @ServerEndpoint

    • 指定 WebSocket 服务端的路径为 /websocket
    • 客户端通过 ws://localhost:8080/websocket 连接服务端。
  • @OnOpen 方法

    • 在客户端连接成功时调用。
    • 参数 Session:表示与客户端的会话,用于发送消息或获取连接信息。
    • 将当前会话保存到 clients 集合中,便于广播消息。
  • @OnMessage 方法

    • 在收到客户端消息时调用。
    • 参数 message:客户端发送的消息。
    • 将消息打印到控制台,并广播给所有已连接的客户端。
  • @OnClose 方法

    • 在客户端关闭连接时调用。
    • clients 集合中移除当前会话。
  • @OnError 方法

    • 在通信过程中发生异常时触发。
    • 可以记录日志或进行异常处理。
  • sendMessage(String message) 方法

    • 使用 SessiongetBasicRemote().sendText() 方法发送消息到当前客户端。
  • broadcast(String message) 方法

    • 遍历 clients 集合,将消息广播给所有客户端。

4. 配置 WebSocket 服务端

将 WebSocket 服务注册到 Spring Boot 项目中。

实现代码

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.websocket.server.ServerEndpointConfig;@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointConfig.Configurator websocketConfigurator() {return new ServerEndpointConfig.Configurator();}
}

步骤说明

  • 配置类使用 @Configuration 注解。
  • @ServerEndpoint 标注的类注册为 WebSocket 服务。

5. 创建 WebSocket 客户端

使用 javax.websocket 提供的 API 创建客户端,用于连接服务端并与其通信。

完整代码示例

import javax.websocket.*;
import java.net.URI;@ClientEndpoint
public class WebSocketClient {@OnOpenpublic void onOpen(Session session) {System.out.println("客户端成功连接到服务端");try {session.getBasicRemote().sendText("Hello, WebSocket Server!");} catch (IOException e) {e.printStackTrace();}}@OnMessagepublic void onMessage(String message) {System.out.println("收到服务端消息:" + message);}@OnClosepublic void onClose() {System.out.println("客户端连接已关闭");}@OnErrorpublic void onError(Throwable error) {System.err.println("客户端发生错误:" + error.getMessage());}public static void main(String[] args) {WebSocketContainer container = ContainerProvider.getWebSocketContainer();String uri = "ws://localhost:8080/websocket";try {container.connectToServer(WebSocketClient.class, URI.create(uri));} catch (Exception e) {e.printStackTrace();}}
}

代码详解

  • 类注解 @ClientEndpoint

    • 指定该类为 WebSocket 客户端。
  • @OnOpen 方法

    • 在客户端成功连接到服务端时调用。
    • 使用 Session 对象的 getBasicRemote().sendText() 方法向服务端发送消息。
  • @OnMessage 方法

    • 在客户端收到服务端消息时调用。
    • 参数 message:服务端发送的消息。
  • @OnClose 方法

    • 在客户端与服务端断开连接时调用。
  • @OnError 方法

    • 在通信过程中发生异常时触发。
  • main 方法

    • 使用 WebSocketContainer 创建客户端连接,连接地址为 ws://localhost:8080/websocket

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com