一文了解WebSocket及Springboot集成WebSocket

news2024/11/19 7:34:25

文章目录

  • WebSocket是什么
  • WebSocket通信原理和机制
  • WebSocket协议是什么
  • WebSocket协议和Http协议有什么区别
  • WebSocket常用在那些场景
  • Springboot集成WebSocket
    • pom依赖
    • java相关代码
      • config
      • component
    • html代码
    • 页面访问效果

WebSocket是什么

🍊WebSocket是一种网络通信协议,它提供了在单个TCP连接上进行全双工通信的能力。这意味着在一个连接上,服务器和客户端都可以同时发送和接收数据。

🍊WebSocket与HTTP协议不同,它使用了独立的端口,并且在建立连接后,不需要在每次数据传输时重新建立连接。这使得它特别适合于实时应用程序,例如聊天,在线游戏和股票交易等,这些应用程序需要高速,双向的数据传输。

🍊WebSocket协议是HTML5标准的一部分,因此它可以在现代浏览器中使用。WebSocket API可以在JavaScript中使用,这样就可以在网页上直接使用WebSocket进行通信。

🍊WebSocket使用了一种称为握手的连接建立机制,服务器和客户端在建立连接之前需要进行握手。握手是通过HTTP协议完成的,但是一旦建立连接后,数据传输将使用WebSocket协议。

WebSocket通信原理和机制

       WebSocket是一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务器之间能够进行双向通信而不必进行多次HTTP请求和响应。

WebSocket通信的流程如下:

  1. 客户端发送一个HTTP请求,请求的目的是为了要建立一个WebSocket连接。
  2. 服务器收到请求后,给出一个HTTP响应,并升级连接到WebSocket协议。
  3. 客户端和服务器之间建立一个WebSocket连接。
  4. 客户端和服务器之间可以进行双向通信,发送文本和二进制数据。
  5. 当客户端或服务器关闭连接时,WebSocket连接也会关闭。

与 HTTP 通信不同的是,WebSocket 通信是基于TCP的,所以它是一个持久连接。它允许服务器主动发送信息给客户端,而不是等待客户端的请求。这使得 WebSocket 通信成为了实现实时应用的理想选择。

如下图所示,发起一个websocket链接之后,请求和响应的参数里会有一些websocket相关的参数,该报文中有一个upgrade首部,它的作用是告诉服务端需要将通信协议切换到websocket

在这里插入图片描述

WebSocket协议是什么

🍊WebSocket协议是一种网络协议,它定义了浏览器和服务器之间的通信协议。WebSocket协议实现了客户端和服务器之间的双向通信,而不是传统的单向通信。

🍊WebSocket协议是基于TCP协议的,并且在建立连接时使用了HTTP协议。在建立连接时,客户端发送一个HTTP请求到服务器,请求升级连接到WebSocket协议。服务器收到请求后,给出一个HTTP响应,并升级连接到WebSocket协议。之后客户端和服务器就可以通过WebSocket协议进行双向通信了。

🍊WebSocket协议是一种全双工协议,它允许服务器主动发送信息给客户端,而不是等待客户端的请求。这使得WebSocket协议成为了实现实时应用的理想选择。

🍊WebSocket协议是IETF(Internet Engineering Task Force)标准化组织于2011年发布的一种新的协议,并且在2013年正式成为因特网标准。

WebSocket协议和Http协议有什么区别

WebSocket协议和HTTP协议有以下几点区别:

  1. 通信方式不同: HTTP协议是一种请求-响应协议,客户端发送请求给服务器,服务器返回响应。而WebSocket协议是一种全双工协议,客户端和服务器都可以主动发送消息。
  2. 链接状态不同: HTTP协议是无状态的,每次请求都是独立的。而WebSocket协议是有状态的,建立了连接之后,客户端和服务器之间可以维持长连接。
  3. 数据传输不同: HTTP协议是基于文本的,而WebSocket协议是基于二进制的。
  4. 延迟不同: HTTP协议每次请求都需要建立连接,等待响应,传输数据,释放连接,这整个过程都需要一些时间。而WebSocket协议只需要建立一次连接,之后就可以高效地进行数据传输,所以延迟更小。

WebSocket常用在那些场景

常见的应用场景如下:

  1. 在线聊天:实现实时的文本聊天功能。
  2. 直播和视频会议:实现实时的音频和视频传输。
  3. 游戏:实现实时的游戏状态同步和控制。
  4. 实时监控和控制:实现实时的硬件监控和控制。
  5. 数据可视化:实现实时的数据可视化和分析。
  6. 在线协作:实现实时的文档协作和编辑。
  7. 智能家居:实现实时的智能家居控制。
  8. 推送消息:实现实时的推送消息功能

这些场景中,WebSocket的实时通信特性使得WebSocket成为了一种理想的选择。

Springboot集成WebSocket

🍊使用springboot+WebSocket+JavaScript实现一个简单的示例

pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>8</java.version>
        <java.encoding>UTF-8</java.encoding>
        <slf4j.version>1.7.30</slf4j.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--  springboot集成websocket -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- 引入日志管理相关依赖-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-to-slf4j</artifactId>
            <version>2.14.0</version>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <target>${java.version}</target>
                        <source>${java.version}</source>
                        <encoding>${java.encoding}</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.6</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-release-plugin</artifactId>
                    <configuration>
                        <arguments>-Prelease</arguments>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>2.1</version>
                    <configuration>
                        <attach>true</attach>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>compile</phase>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>

                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

java相关代码

config

import org.springframework.beans.factory.annotation.Autowired;
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;

/**
 * @author 
 * @date 2023年01月29日 14:07
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Autowired
    private WebSocketHandler webSocketHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketHandler, "/websocket").setAllowedOrigins("*");
    }
}
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 
 * 解决跨域问题
 * @date 2023年01月29日 14:46
 */
@Component
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Content-Length, X-Requested-With");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}

component

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
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.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 
 * @date 2023年01月29日 14:08
 */
@Component
public class WebSocketHandler extends TextWebSocketHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketHandler.class);

    private static final List<WebSocketSession> sessions = new ArrayList<>();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        LOGGER.info("Received message: {}", message.getPayload());
        for (WebSocketSession webSocketSession : sessions) {
            try {
                webSocketSession.sendMessage(message);
            } catch (IOException e) {
                LOGGER.error("Error: {}", e.getMessage());
            }
        }
    }

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

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


html代码

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Example</title>
</head>
<body>
<input type="text" id="messageInput">
<button onclick="sendMessage()">Send</button>

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

    socket.onopen = function(event) {
        console.log("WebSocket is open now.");
    };

    socket.onmessage = function(event) {
        var message = event.data;
        console.log("Received message: " + message);
    };

    socket.onclose = function(event) {
        console.log("WebSocket is closed now.");
    };

    function sendMessage() {
        var message = document.getElementById("messageInput").value;
        socket.send(message);
    }
</script>
</body>
</html>

页面访问效果

访问页面时开启websocket连接,输入文字时能接收到对应的反馈信息

在这里插入图片描述

客户端发送和接收到的信息

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux C编程

编写C代码 编辑器&#xff1a;vim&#xff0c;编写.c文件 编译 gcc 源文件 -o 生成可执行文件名 gcc -c&#xff1a;只编译&#xff0c;不链接&#xff0c;生成.o文件 make工具和Makefile文件 make工具&#xff1a;GNU make&#xff0c;是一个文件&#xff0c;用于将源代…

【CANoe示例分析】EthernetCanGW_Test_CN

1、工程路径 此示例工程来自于Vector官网:EthernetCanGW_Test_CN 感兴趣的可以自行下载! 2、示例目的 如何在CANoe中创建一个网关,实现转发以太网报文到多个CAN网络中。该使用案例是对CAN网络进行压力测试 3、示例内容 本示例通过执行Test Module里的测试用例Bus_load…

《电路/电路原理》—戴维宁(南)定理实战演练

前言战前准备什么是戴维南定理&#xff1f;戴维南定理&#xff08;Thevenins theorem&#xff09;标准解释&#xff1a;含独立电源的线性电阻单口网络N&#xff0c;就端口特性而言&#xff0c;可以等效为一个电压源和电阻串联的单口网络。电压源的电压等于单口网络在负载开路时…

CSS预处理器、移动端适配

1、预处理器概念 1.1、CSS编写的痛点 CSS作为一种样式语言, 本身用来给HTML元素添加样式是没有问题的。 但是目前前端项目已经越来越复杂, 不再是简简单单的几行CSS就可以搞定的, 我们需要几千行甚至上万行的CSS来完成页面的美化工作。 随着代码量的增加, 必然会造成很多的…

LeetCode-26. 删除有序数组中的重复项

目录题目分析双指针理解代码实现题目来源 26. 删除有序数组中的重复项 题目分析 解法&#xff1a; 双指针 首先注意数组是有序的&#xff0c;那么重复的元素一定会相邻。 要求删除重复元素&#xff0c;实际上就是将不重复的元素移到数组的左侧。 考虑用 2 个指针&#xff0c;…

拉伯证券|7900亿芯片巨头狂跌,发生了什么?

全球芯片巨子忽然爆雷。 英特尔刚刚交出了一份“十分糟糕”的财报。美东时间1月26日美股盘后&#xff0c;英特尔公布的2022第四季度及全年财报显现&#xff0c;第四季度的营收为140亿美元&#xff0c;同比大幅下降32%&#xff0c;不及商场预期&#xff1b;第四季度净亏损7亿美元…

【项目精选】基于SpringBoot和Vue开发的功能强大的图书馆系统(附源码)

功能介绍 图书馆系统功能包括&#xff1a; 1、读者端&#xff1a; 1.智能推荐图书 2.读者在线预约座位 3.读者借阅归还图书 4.图书详情 5.图书评论、评星 6.用户登录、注册、修改个人信息 7.用户自定义图书标签 8.用户报名活动参加活动 9.书架展示和添加删除 10.用户邮件登录…

Win11的两个实用技巧系列之u盘怎么设置密码?

Win11系统u盘怎么设置密码?Win11设置u盘密码的方法win11U盘怎么设置密码&#xff1f;今天小编就为大家带来了Win11设置u盘密码的方法&#xff0c;需要的朋友一起看看吧现在还是有很多用户都在使用U盘来存储一些重要的文件和数据&#xff0c;而为了更好的保护里面的安全&#x…

mongodb的索引操作

Mongodb的索引操作 学习目标 掌握 mongodb索引的创建&#xff0c;删除操作掌握 mongodb查看索引的方法掌握 mongodb创建唯一索引的方法 1. 为什么mongdb需要创建索引 加快查询速度进行数据的去重 2. mongodb创建简单的索引方法 语法&#xff1a;db.集合名.ensureIndex({属…

【手写 Promise 源码】第八篇 - 完善 Promise 并通过 promise-aplus-tests 测试

一&#xff0c;前言 上一篇&#xff0c;实现 Promise 对返回值 x 各种情况的分析和处理&#xff0c;主要涉及以下几个点&#xff1a; 回顾了相关的 Promise A 规范内容&#xff1b;根据 Promise A 规范描述和要求&#xff0c;实现了核心解析方法&#xff1a;resolvePromise&a…

BUUCTF-Reverse Writeup【持续更新】

本文示例程序可见 BUUCTF 官网或者 github easyre | 入门级 方法一&#xff1a;WinHex 打开 easyre.exe&#xff0c;浏览一下字符串&#xff0c;发现有flag方法二&#xff1a;IDA Pro 打开 easyre.exe&#xff0c;能直接看到flag&#xff0c;或者 F5 反汇编看到逻辑是输入两个…

怎么把多个JPG合并成一个PDF?还不快来学

我们通常在处理工作文件时会有很多JPG图片需要传输&#xff0c;不过JPG图片数量一般都非常多&#xff0c;我们需要一张一张的进行传输&#xff0c;不仅会浪费很多时间&#xff0c;还很不方便查看&#xff0c;所以我们就可以及将JPG图片合并到一个PDF文件中&#xff0c;这样就可…

直流电机控制器设计

导读:本文主要介绍了DC-motor电流环和速度环的PI控制器参数的设计,并且简单介绍了设计控制器所需要的背景知识,相关仿真文件的下载地址在文章末尾可供大家下载。 DC-motor 的数学模型 直流电机电枢绕组的电压方程为:

阿里紧急辟谣,全球总部始终在杭州,造谣者请放过民营经济吧

树欲静&#xff0c;而风不止。春节期间又一则关于阿里的谣言&#xff0c;再次广泛传播。谣言称&#xff0c;“阿里在新加坡筹建全球总部”。这则谣言前后&#xff0c;网络上还有许多关于阿里早期创始人移民的各种传言。2023年1月27日下午&#xff0c;阿里集团相关负责人进行了辟…

SparkSQL中4个排序的区别

常用的四个排序BY ORDER BYSORT BYDISTRIBUTE BYCLUSTER BY 此文只是结合官方文档和案例做一下说明下功能 数据集描述 数据如上所示,并手动将分区数设定在2个,默认以 id 字段作为分区依据 原始数据分布 情况如下 相同id的数据都分到了同一个分区内 ORDER BY子句 官网说明: …

JavaScript 执行上下文

什么是执行上下文 JavaScript是一种客户端脚本语言&#xff0c;通常在Web浏览器中执行。当您在浏览器中加载网页时&#xff0c;浏览器会解析HTML文档并创建文档对象模型 (DOM)。在这个过程中&#xff0c;浏览器会寻找包含JavaScript代码的script标签并执行这些代码。 当浏览器…

46.Isaac教程--在机器人应用Deepstream

在机器人应用Deepstream ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录在机器人应用Deepstream技术组件工具技术 NVIDIA DeepStream SDK 为基于 AI 的视频和图像感知以及多传感器处理提供了完整的流分析工具包。 DeepStream 是 NVIDIA…

NUXT学习笔记【part1】nuxt的安装、自定义布局、路由跳转

一、NUXT概述 NUXT 是一个基于 Vue.js 的轻量级应用框架&#xff0c;可用来创建服务端渲染 (SSR) 应用&#xff0c;也可充当静态站点引擎生成静态站点应用&#xff0c;具有优雅的代码结构分层和热加载等特性。NUXT使用服务端渲染技术&#xff0c;可以获得更快的内容到达时间&a…

markdown 写微信公众号,排版交给 mdnice

mdnice 墨滴软件&#xff08; https://product.mdnice.com/ &#xff09;&#xff0c;提供了以面向微信公众号内容排版为主的辅助工具 Markdown Nice[1]&#xff0c;效果堪称完美&#xff0c;极大的提升了发布微信公众号文章的效率。 使用其在线编辑器&#xff08; https://e…

L4 Latent Variable Model

Lecture4 Latent Variable Model 在之前我们所介绍的Autoregressive Model和Flow Model中&#xff0c;讨论的都是observable的数据&#xff0c;及一切数据都是可以观测到的。这一讲主要讨论的是latent variable model&#xff0c;即有些变量我们是无法直接观测的。 Latent Va…