当前位置: 首页 > article >正文

Java Web开发进阶——WebSocket与实时通信

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,广泛应用于需要实时数据交换的应用程序中。它能够实现服务器与客户端之间的双向通信,避免了传统 HTTP 请求/响应的延迟。结合 Spring Boot,开发实时通信应用变得更加高效与简便。


1. WebSocket的基本概念与应用
1.1 什么是WebSocket?

WebSocket 是一种协议,它允许客户端和服务器之间通过持久的连接进行实时双向通信。在传统的 HTTP 协议中,客户端发起请求,服务器响应请求,这种通信方式是单向的,且每次请求都需要重新建立连接。而 WebSocket 通过在客户端和服务器之间建立一个长连接,实现了数据的双向实时传输,极大地提高了应用的实时性和响应能力。

  • 全双工通信:WebSocket 允许客户端和服务器同时发送数据,这与传统的请求-响应模型不同。
  • 低延迟:由于建立了持久连接,数据传输的延迟非常低,适合实时应用。
  • 节省带宽:WebSocket 可以避免每次请求都建立连接,减少了请求头和握手的开销。
1.2 WebSocket的应用场景

WebSocket 的实时通信特性使得它非常适合以下应用场景:

  • 实时聊天应用:如在线客服、即时通讯。
  • 在线游戏:多人在线互动游戏。
  • 股票和金融应用:实时股票价格和市场数据更新。
  • 协作应用:如多人协作编辑器、在线文档协作。
  • 实时通知系统:推送通知和事件广播。

2. 使用Spring Boot实现WebSocket
2.1 引入Spring Boot WebSocket依赖

Spring Boot 提供了对 WebSocket 协议的原生支持,使用 spring-boot-starter-websocket 依赖即可实现 WebSocket 功能。在 pom.xml 中加入如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.2 配置WebSocket

Spring Boot 支持使用 @Configuration 注解的配置类来配置 WebSocket。通过实现 WebSocketConfigurer 接口并重写 registerWebSocketHandlers 方法,可以自定义 WebSocket 的配置。

例如:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new ChatWebSocketHandler(), "/chat")
                .setAllowedOrigins("*");  // 允许所有来源的跨域请求
    }
}

在此配置类中,addHandler 方法指定了 WebSocket 请求路径 /chat,并且配置了处理 WebSocket 消息的 ChatWebSocketHandler 类。

2.3 编写WebSocket处理器

WebSocketHandler 是处理 WebSocket 消息的核心类。在 Spring Boot 中,我们可以自定义一个 WebSocketHandler 来处理连接、消息、关闭等事件。

例如,ChatWebSocketHandler 可以实现以下功能:

  • 处理连接建立:客户端连接成功时调用。
  • 处理消息传递:接收到客户端消息时调用。
  • 处理连接关闭:客户端断开连接时调用。
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;

public class ChatWebSocketHandler extends TextWebSocketHandler {

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("New WebSocket connection established: " + session.getId());
        session.sendMessage(new TextMessage("Welcome to the chat room!"));
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("Received message: " + payload);

        // Echo the message back to the client
        session.sendMessage(new TextMessage("Echo: " + payload));
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, org.springframework.web.socket.CloseStatus status) throws Exception {
        System.out.println("Connection closed: " + session.getId());
    }
}

在这个 ChatWebSocketHandler 类中,afterConnectionEstablished 用来在客户端连接后发送一条欢迎消息,handleTextMessage 用来处理客户端发送的消息,并回传相同的消息。

2.4 前端WebSocket客户端

在前端页面中,我们可以通过 JavaScript 的 WebSocket API 来连接 WebSocket 服务,并发送接收消息。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Chat</title>
</head>
<body>
    <h1>WebSocket Chat</h1>
    <textarea id="chat" cols="30" rows="10" readonly></textarea><br/>
    <input type="text" id="message" placeholder="Enter message"/>
    <button onclick="sendMessage()">Send</button>

    <script>
        var socket = new WebSocket("ws://localhost:8080/chat");

        socket.onopen = function () {
            console.log("Connected to WebSocket server.");
        };

        socket.onmessage = function (event) {
            document.getElementById("chat").value += "Server: " + event.data + "\n";
        };

        function sendMessage() {
            var message = document.getElementById("message").value;
            socket.send(message);
            document.getElementById("chat").value += "You: " + message + "\n";
            document.getElementById("message").value = "";
        }
    </script>
</body>
</html>

在此 HTML 页面中,使用 WebSocket API 建立连接,点击发送按钮时将文本框内容发送到服务器,服务器会回传相同的消息并在页面上显示。


3. 开发实时聊天应用示例
3.1 项目需求

我们的目标是构建一个实时聊天应用,用户可以通过 WebSocket 与其他用户进行即时对话。该应用包括以下功能:

  • 用户连接到聊天服务器。
  • 用户输入消息并发送。
  • 服务器实时回传消息。
  • 聊天记录在页面上展示。
3.2 后端实现

我们已经在前面的部分中实现了 ChatWebSocketHandler 和 WebSocket 配置。接下来,我们可以为聊天应用提供更多的功能,如支持多个用户之间的消息转发。

修改 ChatWebSocketHandler 以支持广播消息:

import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;

import java.util.HashSet;
import java.util.Set;

public class ChatWebSocketHandler extends TextWebSocketHandler {

    private static final Set<WebSocketSession> sessions = new HashSet<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
        session.sendMessage(new TextMessage("Welcome to the chat room!"));
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        for (WebSocketSession s : sessions) {
            s.sendMessage(new TextMessage(payload));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, org.springframework.web.socket.CloseStatus status) throws Exception {
        sessions.remove(session);
    }
}

这里,我们使用一个 Set 来存储所有连接的 WebSocket 客户端,每次收到消息时,都将消息广播给所有连接的客户端。

3.3 前端实现

前端界面与之前类似,但我们改进了显示聊天记录和输入框的样式。每当一个用户发送消息时,其他所有连接的用户都会看到相同的消息。

<textarea id="chat" cols="30" rows="10" readonly></textarea><br/>
<input type="text" id="message" placeholder="Enter message"/>
<button onclick="sendMessage()">Send</button>

总结

WebSocket 是一种非常适合实时通信的协议,特别是在构建即时通讯、在线协作、实时数据更新等应用时。在 Spring Boot 中实现 WebSocket 非常简单,我们只需要添加相关依赖,配置 WebSocket 处理器,然后在前端使用 WebSocket API 进行连接和消息传递。通过这个简单的示例,我们可以构建一个实时聊天应用,展示 WebSocket 在实时通信中的强大能力。

关于作者:

15年互联网开发、带过10-20人的团队,多次帮助公司从0到1完成项目开发,在TX等大厂都工作过。当下为退役状态,写此篇文章属个人爱好。本人开发期间收集了很多开发课程等资料,需要可联系我


http://www.kler.cn/a/502727.html

相关文章:

  • 如何开放2375和2376端口供Docker daemon监听
  • 分多个AndroidManifest.xml来控制项目编译
  • Linux(Centos7)安装Mysql/Redis/MinIO
  • RK3568-rk809rtc休眠唤醒
  • rk3568 , buildroot , qt ,使用sqlite, 动态库, 静态库
  • 介绍下不同语言的异常处理机制
  • <2025 网络安全>《网络安全政策法规-关键信息基础设施安全保护条例》
  • 使用Qt和OpenGL实现一个旋转的各面颜色不一致的立方体及知识点分析
  • Three.js 数学工具:构建精确3D世界的基石
  • 是德科技Keysight N9020A实时频谱分析仪N9000A
  • 机器学习算法(一): 基于逻辑回归的分类预测
  • P10打卡——pytorch实现车牌识别
  • UE材质WorldPosition
  • wsl2上mysql出现ip端口冲突问题
  • Android 网络层相关介绍
  • Qt | 共享内存读写QSharedMemory(不同app互通)
  • 网络安全 信息收集入门
  • 详解用大模型超拟人语音做桌面AI宠物/机器人的个性化能力
  • FilmMusic
  • 54_ Caffeine实现多级缓存
  • 后盾人JS--JS值类型使用(终章)
  • 运行爬虫时可能遇到哪些常见问题?
  • 2024—AWS:re:Invent城市巡展——武汉站参会心笺
  • 【ubuntu24.04】配置ssh以root登录
  • lombok在高版本idea中注解不生效的解决
  • 人工智能计算机视觉学习路线——从基础到深度探索