首页 > 其他分享 >SpringBoot集成WebSocket实现消息推送

SpringBoot集成WebSocket实现消息推送

时间:2024-01-09 15:07:02浏览次数:44  
标签:websocket SpringBoot org springframework import WebSocket 推送 public

一、前言

WebSocket是一种新型的通信协议,它可以在客户端和服务端之间实现双向通信,具有低延迟、高效性等特点,适用于实时通信场景。它是一种基于TCP协议实现的全双工通信协议,使用它可以实现实时通信,不必担心HTTP协议的短连接问题。SpringBoot可以很方便的集成WebSocket实现高效实时的消息推送。

二、特点

1.WebSocket是HTML5的一种新的协议,本质上它是独立的、创建在TCP上的一种协议。

2.通过HTTP/1.1协议的101状态码进行握手。

3.为了达成WebSocket连接,需要浏览器发出请求后服务器进行回应,这个过程也称为握手。

4.WebSocket是一种持久化的协议。

5.WebSocket实现了浏览器和服务器之间全双工通信,能够更好的节省服务器资源和带宽,以此达到实时通讯的目的。

三、前端相关API

1.建立连接

使用new WebSocket(url)创建WebSocket连接。

var url = "ws://mywebsocket";
var websocket = new WebSocket(url);

2.推送消息

通过send方法向服务器发送消息。

websocket.send("hello");

3.接收服务器传过来的数据

websocket.onmessage = function (resp) {
     var data = resp.data;
}

4.监听WebSocket打开事件

websocket.onopen = function (event){
            // 开始通信事件
}

5.监听WebSocket关闭事件

websocket.onclose = function (event){
            // 监听关闭事件
}

6.监听WebSocket关闭事件

websocket.onclose = function (event){
            // 监听关闭事件
        }

7.WebSocket状态

我们可以通过readyState属性来获取WebSocket对象的状态。

CONNECTION(0):表示正在连接。

OPEN(1):表示已建立连接。

CLOSING(2):表示正在关闭连接。

CLOSED(3):表示已关闭连接。


四、SpringBoot集成WebSocket

1.添加依赖

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

2.添加WebSocket配置类

package com.example.nettydemo.config;

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

/**
 * @author qx
 * @date 2023/12/25
 * @des WebSocket配置
 */
@Configuration
public class WebSocketConfig {

    /**
     * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

3.创建WebSocketServer类,用来进行服务端和客户端之间的交互

package com.example.nettydemo.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author qx
 * @date 2023/12/25
 * @des WebSocket核心处理类
 */
@Component
@ServerEndpoint("/myWebsocket")
@Slf4j
public class WebSocketServer {


    private static List<Session> sessionList;

    @OnOpen
    public void onOpen(Session session) {
        sessionList = new ArrayList<>();
        sessionList.add(session);
        log.info("websocket建立连接成功");
    }

    @OnMessage
    public void onMessage(String message) {
        log.info("接收到客户端的数据:{}", message);
    }

    @OnError
    public void one rror(Throwable error) {
        log.info("连接客户端失败:{}", error.getMessage());
    }

    @OnClose
    public void onClose() {
        log.info("websocket断开连接");
    }

    /**
     * 实现服务端发送消息
     *
     * @param msg 消息内容
     * @throws IOException
     */
    public void sendMsg(String msg) throws IOException {
        sessionList.get(0).getBasicRemote().sendText(msg);
    }
}

我们用到了几个注解,分别解释一下它们的含义。

注解

作用

@ServerEndpoint

创建一个服务端的URL,客户端通过这个URL来连接服务端

@OnOpen

打开连接触发事件

@OnMessage

收到接收消息事件

@OnClose

关闭连接触发事件

@OnError

处理发生错误的事件


4.创建控制层

package com.example.nettydemo.controller;

import com.example.nettydemo.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;

/**
 * @author qx
 * @date 2023/12/25
 * @des
 */
@RestController
@RequestMapping("/websocket")
public class WebSocketController {

    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 跳转WebSocket通信页面
     */
    @GetMapping("/page")
    public ModelAndView toPage() {
        return new ModelAndView("webSocket");
    }

    /**
     * 服务端发送消息
     *
     * @param msg 消息内容
     * @throws IOException
     */
    @GetMapping("/send")
    public void sendData(String msg) throws IOException {
        webSocketServer.sendMsg(msg);
    }

}

5.创建前端页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>WebSocket测试</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<body>
<input type="text" id="msg" placeholder="请填写数据"/>
<button onclick="sendData()">发送数据</button>
<script>
    var websocket;
    if (typeof (WebSocket) === 'undefined') {
        alert("您的浏览器不支持WebSocket");
    } else {
        // 8090是服务器的端口
        websocket = new WebSocket("ws://localhost:8090/myWebsocket");

        websocket.onopen = function () {
            console.log("webSocket已连接")
        }
        websocket.onmessage = function (event) {
            console.log("接收到服务器的消息:" + event.data)
        }

        websocket.onclose = function () {
            console.log("WebSocket已关闭")
        }
        websocket.onerror = function () {
            console.log("WebSocket发生错误")
        }
    }

    function sendData() {
        if (websocket != null) {
            websocket.send($("#msg").val());
        } else {
            alert("您的浏览器不支持WebSocket");
        }
    }
</script>
</body>

</html>

6.测试

我们打开WebSocket测试页面,控制台显示已成功连接的日志。

SpringBoot集成WebSocket实现消息推送_WebSocket

接着我们发送数据给服务端,点击发送按钮后,服务端控制台日志显示收到来自客户端的数据。

SpringBoot集成WebSocket实现消息推送_WebSocket_02

2023-12-25 10:48:50.735  INFO 4660 --- [nio-8090-exec-4] c.e.nettydemo.websocket.WebSocketServer  : 接收到客户端的数据:我是客户端数据

最后我们调用服务端发送消息给客户端的方法。

SpringBoot集成WebSocket实现消息推送_WebSocket_03

在客户端的控制台日志上我们看到了来自服务端的消息。

SpringBoot集成WebSocket实现消息推送_WebSocket_04


标签:websocket,SpringBoot,org,springframework,import,WebSocket,推送,public
From: https://blog.51cto.com/u_13312531/9138547

相关文章

  • springboot通过自定义注解@Log实现日志打印
    springboot通过自定义注解@Log实现日志打印效果图实操步骤注意,本代码在springboot环境下运行,jdk1.81.引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency>......
  • 【Spring技术专题】「实战开发系列」保姆级教你SpringBoot整合Mybatis框架实现多数据
    Mybatis是什么Mybatis是一个基于JDBC实现的,支持普通SQL查询、存储过程和高级映射的优秀持久层框架,去掉了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。Mybatis主要思想是将程序中大量的SQL语句剥离出来,配置在配置文件中,以实现SQL的灵活配置。在所有ORM框......
  • 基于SpringBoot+Vue的航班订票管理系统设计实现(源码+lw+部署文档+讲解等)
    (文章目录)前言:heartpulse:博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌:heartpulse:......
  • Java+springboot开发医院智能导诊小程序源码
    智慧医院如何实现智能导诊服务?1、数据收集和整合:医院需要收集和整合患者的医疗数据,包括病历、化验结果、影像资料等。同时,还可以整合相关的医学数据库和知识库,以便为导诊提供支持。2、患者信息采集:在患者来院时,可以通过智能问诊系统收集患者的基本信息、症状描述、病史等。这可以......
  • 在现有SpringBoot项目中,快速添加所需依赖项
    如果在SpringBoot项目开发过程中,缺少某些依赖项,如SpringWeb、MybatisFramwork等····,不用手动在pom.xml文件中导入依赖前提:创建的项目为正常的SpringBoot项目,我用的版本是3.2.11.可以直接在pom.xml文件中,找到<dependencies>标签,会发现有个提示2.点击后会出现跟创建项目时添加......
  • SpringBoot: 通过MyBatis访问ClickHouse
    一、ClickHouse中建表,添加数据二、SpringBoot项目添加mybatis、clickhouse、druid相关依赖<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version><......
  • springboot集成swagger knife4j 最详细的步骤 手把手教你继承swagger
    springboot集成swaggerknife4j最详细的步骤手把手教你继承swagger效果图Knife4j介绍Knife4j的前身是swagger-bootstrap-ui,前身swagger-bootstrap-ui是一个纯swagger-ui的ui皮肤项目一开始项目初衷是为了写一个增强版本的swagger的前端ui,但是随着项目的发展,面对越来越多的个性......
  • SpringBoot 接口:响应时间优化9个技巧!
    今天聊聊SpringBoot接口:响应时间优化的9个技巧。在实际开发中,提升接口响应速度是一件挺重要的事,特别是在面临大量用户请求的时候。好了,咱们直接切入正题。本文,已收录于,我的技术网站ddkk.com,有大厂完整面经,工作技术,架构师成长之路,等经验分享在SpringBoot应用中,接口响应时间的优......
  • 光速爱购--靠谱的SpringBoot项目
    简介这是一个靠谱的SpringBoot项目实战,名字叫光速爱购。从零开发项目,视频加文档,十天就能学会开发JavaWeb项目。教程路线是:搭建环境=>安装软件=>创建项目=>添加依赖和配置=>通过表生成代码=>编写Java代码=>代码自测=>前后端联调=>准备找工作。学完即可成为合格的Java开发,心......
  • springboot项目中,Mapper接口映射xml文件出错问题,显示Invalid bound statement
    在进行springboot开发过程中遇到的一个问题,显示org.apache.ibatis.binding.BindingException:Invalidboundstatement(notfound);大概意思应该就是找不到Mapper接口对应的xml映射文件,检查了以后,发现应该是没有正确扫描到映射文件的路径。1.保证java文件夹下面的Mapper接口包名称......