springboot集成websocket给前端推送消息

一般通常情况下,我们都是前端主动朝后端发送请求,那么有没有可能,后端主动给前端推送消息呢?这时候就可以借助websocket来实现。下面给出一个简单的实现样例。

首先创建一个websocketDemo工程,该工程的整体结构如下:

(1)修改POM文件,增加相关依赖

XML 复制代码
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mycompany</groupId>
    <artifactId>websocketDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

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

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

</project>

(2)新增application.properties文件,增加端口配置信息,并设置端口为8085

XML 复制代码
server.port=8085

(3)新增socket处理器MyWebSocketHandler

java 复制代码
package com.mycompany.handler;

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.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class MyWebSocketHandler extends TextWebSocketHandler {

    private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        System.out.println("连接建立");
        sessions.put(session.getId(), session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        System.out.println("连接关闭");
        sessions.remove(session.getId());
    }

    public void sendToAll(String message) {
        sessions.forEach((id, session) -> {
            if (session.isOpen()) {
                try {
                    session.sendMessage(new TextMessage(message));
                } catch (Exception e) {
                    System.out.println("出现异常,原因" + e);
                    sessions.remove(id);
                }
            } else {
                sessions.remove(id);
            }
        });
    }
}

(5)新增socket配置类

java 复制代码
package com.mycompany.config;

import com.mycompany.handler.MyWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
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 {

    @Autowired
    private MyWebSocketHandler myWebSocketHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWebSocketHandler, "/ws")
                .setAllowedOrigins("*");
    }
    
}

(6)新增控制器类,我们编写了一个接口,用来触发推消息的功能,也就当调用/api/push接口时,就会给浏览器推送消息,推送的消息内容为msg字段的值

java 复制代码
package com.mycompany.controller;

import com.mycompany.handler.MyWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PushController {

    @Autowired
    private MyWebSocketHandler myWebSocketHandler;

    @GetMapping("/api/push")
    public String push(String msg) {
        myWebSocketHandler.sendToAll(msg);
        return "推送成功";
    }

}

(7)编写启动类WebsocketApplication

java 复制代码
package com.mycompany;

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

@SpringBootApplication
public class WebsocketApplication {

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

(8)编写一个index.html页面,注意其中的端口需要和application.properties中的端口保持一致

html 复制代码
<!DOCTYPE html>
<script>
const socket = new WebSocket('ws://localhost:8085/ws');
socket.onmessage = (e) => {
    console.log('收到推送:', e.data);
    document.getElementById('msg').innerHTML += e.data + '<br>';
};
</script>
<div id="msg"></div>

(9)验证测试。首先启动项目WebsocketApplication,然后通过浏览器打开index.html页面

然后我们在浏览器地址栏输入localhost:8085/api/push?msg=你好呀,然后我们会看到浏览器中的index.html页面会显示收到推送的内容。我们可以多次刷新/api/push接口,然后会看到index.html页面也打印多次推送的信息,如下图。

相关推荐
打小就很皮...10 分钟前
dnd-kit 实现表格拖拽排序
前端·react.js·表格拖拽·dnd-kit
Ulyanov14 分钟前
从静态到沉浸:打造惊艳的Web技术发展历程3D时间轴
前端·javascript·html5·gui开发
打小就很皮...24 分钟前
React 19 + Vite 6 + SWC 构建优化实践
前端·react.js·vite·swc
Highcharts.js27 分钟前
使用Highcharts与React集成 官网文档使用说明
前端·react.js·前端框架·react·highcharts·官方文档
这是个栗子27 分钟前
AI辅助编程(二) - 通译千问
前端·ai·通译千问
VT.馒头38 分钟前
【力扣】2625. 扁平化嵌套数组
前端·javascript·算法·leetcode·职场和发展·typescript
数研小生1 小时前
Full Analysis of Taobao Item Detail API taobao.item.get
java·服务器·前端
Shirley~~1 小时前
Vue-skills的中文文档
前端·人工智能
毎天要喝八杯水1 小时前
搭建vue前端后端环境
前端·javascript·vue.js
计算机程序设计小李同学2 小时前
幼儿园信息管理系统的设计与实现
前端·bootstrap·html·毕业设计