WebSocket 详解--spring boot简单使用案例

一、什么是WebSocket

WebSocket 是一种网络通信协议,专为在单个 TCP 连接上进行全双工通信而设计。WebSocket 允许客户端和服务器之间的消息能够实时双向传输。这与传统的 HTTP 请求-响应模式有很大的不同。

二、WebSocket 的关键特性

  • 双向通信:WebSocket 提供了双向通信通道。客户端和服务器可以随时向对方发送消息,而无需客户端发起请求。

  • 持久连接:一旦 WebSocket 连接建立,连接将保持打开状态,直到客户端或服务器显式关闭它。这样避免了频繁的 HTTP 请求开销。

  • 低延迟:由于连接保持打开状态,WebSocket 消息的传输延迟非常低,非常适合需要快速响应的应用,如在线游戏、实时聊天等。

  • 轻量协议:WebSocket 协议头部相对较小,减少了数据传输的开销。

三、WebSocket 工作原理

  • 握手:WebSocket 连接始于 HTTP 请求。客户端发出一个带有特殊头部的 HTTP 请求,要求升级到 WebSocket 协议。服务器同意后,通过 HTTP 101 状态码响应,表示协议切换。

  • 数据传输:握手完成后,客户端和服务器之间的通信切换到 WebSocket 协议。两者可以在这条连接上随时发送文本或二进制消息。

  • 连接关闭:连接可以由客户端或服务器主动关闭,通过发送关闭消息并随后关闭 TCP 连接。

四、WebSocket 应用场景

  1. 实时聊天应用:如在线客服、社交网络聊天。
  2. 在线游戏:需要低延迟实时通信的多人游戏。
  3. 实时数据流:如股票行情、体育比分更新。
  4. 协同编辑:如 Google Docs 这样的实时文档编辑工具。
  5. 物联网(IoT)设备:需要与服务器持续通信的智能设备。

WebSocket 的优势在于其双向通信能力和低延迟,是需要实时数据更新的应用的不二选择。

五、WebSocket简单使用案例——java为例

1、为了方便部署,直接创建一个spring boot项目

首先,使用 Spring Initializr 创建一个新的 Spring Boot 项目。你可以访问 Spring Initializr 或者在 IntelliJ IDEA 中创建一个新项目。

选择的依赖项

  • Spring Web
  • Spring Boot Starter WebSocket

下载项目并解压到你的工作目录中。

2. 编写 WebSocket 服务器端点

2.1 创建 WebSocket 配置类

src/main/java/com/example/demo 下创建一个配置类 WebSocketConfig.java

package com.example.demo;

import org.springframework.context.annotation.Configuration;
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 MyWebSocketHandler(), "/websocket")
                .setAllowedOrigins("*");
    }
}
2.2 创建 WebSocket 处理器

在同一包下创建一个处理器类 MyWebSocketHandler.java

package com.example.demo;

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

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

public class MyWebSocketHandler extends TextWebSocketHandler {

    private static Set<WebSocketSession> sessions = 
        Collections.synchronizedSet(new HashSet<>());

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        for (WebSocketSession webSocketSession : sessions) {
            if (webSocketSession.isOpen() && !session.getId().equals(webSocketSession.getId())) {
                webSocketSession.sendMessage(new TextMessage(message.getPayload()));
            }
        }
    }

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

3. 创建 WebSocket 客户端

为了测试 WebSocket,我们可以创建一个简单的 HTML 文件和 JavaScript 客户端。

src/main/resources/static 下创建一个新的 HTML 文件 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Test</title>
</head>
<body>
    <h1>WebSocket Test</h1>
    <input type="text" id="messageInput" placeholder="Enter message">
    <button onclick="sendMessage()">Send</button>
    <ul id="messages"></ul>

    <script>
        let websocket = new WebSocket("ws://localhost:8080/websocket");

        websocket.onopen = function(event) {
            console.log("Connected to WebSocket");
        };

        websocket.onmessage = function(event) {
            let messages = document.getElementById("messages");
            let message = document.createElement("li");
            message.textContent = event.data;
            messages.appendChild(message);
        };

        websocket.onclose = function(event) {
            console.log("Disconnected from WebSocket");
        };

        function sendMessage() {
            let input = document.getElementById("messageInput");
            websocket.send(input.value);
            input.value = '';
        }
    </script>
</body>
</html>

4. 运行 Spring Boot 应用程序

打开你的 IDE(如 IntelliJ IDEA),加载项目并运行 Spring Boot 应用程序。

你可以通过运行 DemoApplication.java 主类来启动应用程序:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

5. 测试 WebSocket

启动应用程序后,打开浏览器并访问 http://localhost:8080。你应该看到一个简单的页面,允许你输入消息并发送。消息将通过 WebSocket 发送到服务器,并广播到所有连接的客户端。

这是一个使用 Spring Boot 和注解配置的 WebSocket 完整示例。这个示例展示了如何使用注解简化 WebSocket 的配置和处理。你可以根据需要进一步扩展和定制这个项目。

6、效果展示

7、注解的写法

直接使用注解包括 @OnOpen, @OnMessage, @OnClose, @OnError等去配置websocket

创建一个配置类 WebSocketConfig.java:

package com.example.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

在同一包下创建 WebSocket 端点类 WebSocketServer.java

package com.example.demo;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@ServerEndpoint("/websocket")
public class WebSocketServer {

    private static Set<Session> clients = Collections.synchronizedSet(new HashSet<>());

    @OnOpen
    public void onOpen(Session session) {
        clients.add(session);
        System.out.println("New connection with client id: " + session.getId());
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println("New message from client id: " + session.getId() + ": " + message);
        for (Session client : clients) {
            if (!client.getId().equals(session.getId())) {
                client.getBasicRemote().sendText(message);
            }
        }
    }

    @OnClose
    public void onClose(Session session) {
        clients.remove(session);
        System.out.println("Connection closed with client id: " + session.getId());
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("Error from client id: " + session.getId());
        throwable.printStackTrace();
    }
}

其他地方和上面的一样。

六、实际开发可能需要考虑的相关问题

1、处理客户端断网的策略。

  • 心跳检测:定期发送心跳消息以确保连接的有效性。
  • 超时处理:在特定时间内未收到客户端的消息或心跳回应时关闭连接。
  • 异常处理:捕获并处理连接异常,如断网错误。

2、连接管理

  • 连接断开和重连:客户端可能会由于网络波动、服务器重启等原因导致连接断开。需要实现自动重连机制。
    • 解决方案:客户端实现自动重连,服务器端实现连接状态的监控和重连处理。
  • 连接数量限制:服务器可能会面临大量的并发连接,需要管理连接的生命周期。
    • 解决方案:使用连接池、限制单个用户的最大连接数、负载均衡。

3、数据传输

  • 消息顺序:WebSocket 是全双工通信,消息可能会乱序到达。

    • 解决方案:在消息中添加序列号,客户端根据序列号重排消息。
  • 消息大小:某些应用可能需要传输大数据,WebSocket 本身对消息大小有一定限制。

    • 解决方案:将大消息分割成小块发送,在客户端重新组装。

4、安全性

  • 数据加密:WebSocket 传输的数据可以被中间人截获。

    • 解决方案:使用 wss:// 协议(基于 TLS 加密的 WebSocket)确保传输安全。
  • 身份验证和授权:需要确保只有经过认证和授权的客户端才能建立 WebSocket 连接。

    • 解决方案:在握手阶段进行身份验证,使用 JWT 或其他令牌机制。
  • 跨站脚本攻击 (XSS):WebSocket 可能成为 XSS 攻击的目标。

    • 解决方案:在服务器端验证和过滤输入数据,确保数据格式和内容安全。

5、性能优化

  • 延迟:需要尽量减少消息传输的延迟。

    • 解决方案:优化网络路径、使用更快的服务器、减少数据量。
  • 带宽消耗:频繁的消息传输会消耗大量带宽。

    • 解决方案:压缩消息、优化数据结构。

6、服务器架构

  • 扩展性:需要确保 WebSocket 服务器能处理大量并发连接。

    • 解决方案:使用集群和负载均衡,将连接分配到多个服务器上。
  • 高可用性:需要确保服务器在出现故障时能迅速恢复。

    • 解决方案:使用容错和故障转移机制,配置多个冗余服务器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/707701.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Mars3d】config.json中的蓝色底图map.basemap = 2017代码实现

本身的地图效果&#xff1a; Mars3d的蓝色地图效果&#xff1a; 关键代码&#xff1a; basemaps: [{name: "高德电子",icon: "img/basemaps/gaode_vec.png",type: "gaode",layer: "vec",show: true,invertColor: true,filterColor: &q…

ARM32开发--IIC时钟案例

知不足而奋进 望远山而前行 目录 文章目录 前言 目标 内容 需求 开发流程 移植驱动 修改I2C实现 测试功能 总结 前言 在现代嵌入式系统开发中&#xff0c;移植外设驱动并测试其功能是一项常见的任务。本次学习的目标是掌握移植方法和测试方法&#xff0c;以实现对开…

电容式传感器的基本原理

电容式传感器由电容量可变的电容器和测量电路组成&#xff0c;其变量间的转换原理如图5—2所示。 图5—2电容式传感器变量间的转换关系 由电学可知&#xff0c;两个平行金属极板组成的电容器&#xff0c;如果不考虑其边缘效应&#xff0c;其电容为 Se——两个极板介质的介电常…

chrome浏览器设置--disable-web-security解决跨域

在开发人员于后台进行接口测试的时候&#xff0c;老是遇到跨域问题&#xff0c;这时前端总是会让后台添加跨域请求头来允许跨域请求&#xff0c;今天介绍一个简单的方法跨过这一步操作的设置。 –disable-web-security参数&#xff0c;禁用同源策略&#xff0c;利于开发人员本…

ARMxy赋能温室环境自动化调控

智慧农业正以其独特的魅力描绘着未来的轮廓。作为这一变革的中坚力量&#xff0c;ARMxy工业计算机凭借其高性能、低功耗及高度灵活性&#xff0c;正逐步成为智能温室控制、精准灌溉及作物生长监测领域的核心引擎。 智能温室的智慧大脑 位于某地的现代农业园区&#xff0c;一座…

Springboot 开发之任务调度框架(一)Quartz 简介

一、引言 常见的定时任务框架有 Quartz、elastic-job、xxl-job等等&#xff0c;本文主要介绍 Spirng Boot 集成 Quartz 定时任务框架。 二、Quartz 简介 Quartz 是一个功能强大且灵活的开源作业调度库&#xff0c;广泛用于 Java 应用中。它允许开发者创建复杂的调度任务&…

Apache Doris 基础 -- 部分数据类型及操作

您还可以使用SHOW DATA TYPES;查看Doris支持的所有数据类型。 部分类型如下&#xff1a; Type nameNumber of bytesDescriptionSTRING/可变长度字符串&#xff0c;默认支持1048576字节(1Mb)&#xff0c;最大精度限制为2147483643字节(2gb)。大小可以通过BE配置string_type_le…

硕思LOGO设计师软件最新版下载及详细安装教程

硕思Logo设计师是一款操作灵活简单&#xff0c;且功能强大的logo制作软件。它可以通过简单的点击就可以为网站、博客、论坛和邮件创建专业的logo、条幅、按钮、标题、图标和签名等。 该软件提供了很多精心设计的模板和丰富的资源&#xff0c;为更好的创建logo艺术作品&#xff…

CST Studio Suite 基础操作实验(稳恒电流的电场与磁场)

前言 前置的基础操作可见笔者之前一篇文章&#xff0c;在此不再赘述 因为整个实验要求都要用英文&#xff0c;有些不便更改部分的英文就没翻译了&#xff0c;见谅 CST Studio Suite 基础操作实验&#xff08;静电场&#xff09;-CSDN博客 核心步骤 无限长设置 假如是z轴上的…

算法体系-22 第二十二节:暴力递归到动态规划(四)

一 最小距离累加和 1.1 描述 给定一个二维数组matrix&#xff0c;一个人必须从左上角出发&#xff0c;最后到达右下角 沿途只可以向下或者向右走&#xff0c;沿途的数字都累加就是距离累加和 返回最小距离累加和 1.2 分析

【车载AI音视频电脑】200万像素迷你一体机

产品主要特点&#xff1a; -设备安装方便简洁&#xff0c;可通过3M胶直接将设备粘 贴到车前挡风玻璃上 -支持IE预览&#xff0c;手机&#xff0c;PAD实时预览&#xff0c; 支持电脑客 户端实时预览功能 -内置2路模拟高清, 每路均可达到200万像素。另 外可扩充2路1080P模拟…

什么是堡垒机?和跳板机是一个概念吗?

堡垒机&#xff0c;又称运维审计系统、跳板机&#xff0c;是一种位于内部网络与外部网络之间的安全防护设备&#xff0c;它充当了一个“中间人”的角色&#xff0c;所有对内部网络资源的远程访问都必须通过堡垒机进行。这一设计的核心目的&#xff0c;在于严格控制和记录所有进…

体验版小程序访问不到后端接口请求失败问题解决方案

文章目录 解决方案一&#xff1a;配置合法域名解决方案二&#xff1a;开发调试模式第一步&#xff1a;进入开发调试模式第二步&#xff1a;启用开发调试 注意事项结语 &#x1f389;欢迎来到Java面试技巧专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&…

IT运维三大王牌怎么选?一文看懂向日葵IT精英、行业青春、行业版

信息时代&#xff0c;随着智能化设备的不断普及&#xff0c;IT设备的数量是在不断增长的&#xff0c;企业的IT运维压力也逐渐增大&#xff0c;无论是大型企业、中小腰部企业、甚至初创企业和工作室&#xff0c;一款相对专业的远程IT运维方案也慢慢变成了刚需。 虽说大家都有着…

深度解析 | “透明部落(APT36)”持续攻击印度政府、国防部门

概要 近日&#xff0c;黑莓发现了总部位于巴基斯坦的高级持续威胁组织 Transparent Tribe (透明部落&#xff0c;APT36)&#xff0c;其目标是印度的政府、国防和航空航天部门。该活动从 2023 年底持续到 2024 年 4 月&#xff0c;并预计将持续下去。 在 "透明部落 "…

Python 显示笔记本电脑的电池状态和百分比

方法一&#xff1a; import psutil import psutil battery psutil.sensors_battery() if battery is None:print("No battery is found.")exit() print (battery) percentagebattery.percent print(f"Battery Percentage: {percentage}%")Battery的信息…

基于BP神经网络对鸢尾花数据集分类

目录 1. 作者介绍2. 关于理论方面的知识介绍2.1 BP神经网络原理2.2 BP神经网络结构 3. 关于实验过程的介绍&#xff0c;完整实验代码&#xff0c;测试结果3.1 鸢尾花数据集介绍3.2 代码演示3.3 结果演示 4. 问题与分析 1. 作者介绍 侯硕&#xff0c;男&#xff0c;西安工程大学…

【投稿优惠|权威主办】2024年能源、智能制造与材料科学国际学术会议(ICEIMMS 2024)

【投稿优惠|权威主办】2024年能源、智能制造与材料科学国际学术会议&#xff08;ICEIMMS 2024&#xff09; 2024 International Academic Conference on Energy, Intelligent Manufacturing, and Materials Science&#xff08;ICEIMMS 2024&#xff09; ▶会议简介 2024年能源…

充电宝哪个牌子好?揭秘无线磁吸充电宝哪个牌子性价比高!

大家是否曾经遇到过外出时手机电量告急&#xff0c;急需充电却苦于没有带充电器的情况&#xff1f;这时&#xff0c;满大街的共享充电宝就成了我们的救星。然而&#xff0c;在使用共享充电宝的过程中&#xff0c;我们也不得不面对一些现实问题。共享充电宝确实方便快捷&#xf…

LLM 大模型学习:数据预处理、模板设计以

在模型训练过程中&#xff0c;数据及数据处理是最为重要的工作之一。在当前模型训练流程趋于成熟的情况下&#xff0c;数据集的好坏&#xff0c;是决定了该次训练能否成功的最关键因素。 在上一篇中&#xff0c;我们提到了模型训练的基本原理是将文字转换索引再转换为对应的向…