SpringBoot整合WebSocket实现订阅消息推送

news2024/10/7 19:22:32

目录

  • 一、什么是WebSocket
    • 1.HTTP协议
    • 2.WebSocket协议
  • 二、WebSocket使用场景
    • 1.消息推送
    • 2.实时聊天
    • 3.弹幕
    • 4.实时数据更新
  • 三、SpringBoot整合WebSocket(以实现消息推送为例)
    • 1.添加依赖
    • 2.创建消息类
    • 2.WebSocket配置类
    • 3.工具类
    • 4.测试连接
    • 5.服务调用

一、什么是WebSocket

1.HTTP协议

Http协议是一种无状态的超文本传输协议,由客户端向服务器发送请求,服务器向客户端发出响应,特点是一问一答的形式,如果需要服务端主动向客户端发送消息就不适用了。
在这里插入图片描述

2.WebSocket协议

WebSocket是一种计算机通信协议,通过单个 TCP 连接提供双向数据传输的协议。

  • 双向性: 使用 WebSocket 客户端或服务器可以发起消息发送,不必像Http协议,只能由客户端发起请求,因此WebSocket适合服务器单方向客户端发起推送的业务场景。
  • 轻量级: 与 http 相比,WebSocket 消息数据交换要轻得多,因此,在WebSocket客户端和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。
  • 数据类型: WebSocket传输支持文本类型、二进制类型(图片、动画等),还可以传输自定义的消息类型。
  • 单个 TCP 连接 : 初始连接使用 HTTP,然后将此连接升级到基于套接字的连接。然后这个单一连接用于所有未来的通信。

在这里插入图片描述

二、WebSocket使用场景

HTTP 不适用于两个应用程序之间的长时间实时工通信,但是WebbSocket允许服务端主动向客户端推送数据,并且不用遵循一问一答的规则,具有良好的互动性和时效性。

1.消息推送

公告、新闻推送

2.实时聊天

对话框实时通信

3.弹幕

4.实时数据更新

股票报价、体育比赛分数刷新

三、SpringBoot整合WebSocket(以实现消息推送为例)

来源:spring官方网站给予使用websocket的demo:https://spring.io/guides/gs/messaging-stomp-websocket/

这个项目demo是官网给的示例demo,直接pull下来复制一下就完全可以用了,以下是我把示例demo集成到自己项目的过程:

1.添加依赖

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

2.创建消息类

就是你想要的消息是怎么样的,有哪些字段和值,例如我的消息类是这样设计的

{
	# 用户连接ID
	"clientId":"36人7829",
	# 消息编码:可进行自定义,例如001是消息通告,002是广告
	"messageCode":"001",
	# 消息内容
	"messageContent":"好消息,打折了",
}
package com.cloud.springnacos9001.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @author caicai
 */
@Data
@AllArgsConstructor
public class WebSocketMessage {

    /**
     * 用户ID
     */
    private String clientId;

    /**
     * 消息编码:可进行自定义,例如001是消息通告,002是广告
     */
    private String messageCode;

    /**
     * 消息内容
     */
    private String messageContent;
}

2.WebSocket配置类

package com.cloud.springnacos9001.config;

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

/**
 * WebSocket配置类
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig {

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

}

3.工具类

package com.cloud.springnacos9001.controller;

import com.cloud.springnacos9001.entity.WebSocketMessage;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.ConcurrentHashMap;


/**
 *
 * @author caicai
 * @date
 * @ServerEndpoint
 */
@Component
@Slf4j
@ServerEndpoint(value = "/websocket")
public class WebSocketServer {
    /**
     * 某个客户端连接的session
     */
    private Session session;

    private static ConcurrentHashMap<String,Session> clientMap = new ConcurrentHashMap<>();

    /**
     * 建立连接后调用的方法
     * @param session
     */
    @OnOpen
    public void onOpen(Session session){
        log.info("-----websocket成功连接------");
        this.session = session;
        clientMap.put(this.session.getId(),this.session);
    }

    /**
     * 处理客户端失败连接
     */
    @OnClose
    public void onClose(){
        clientMap.remove(this.session.getId());
        log.info("客户端失去连接,其sessionID为:"+this.session.getId());
    }

    /**
     * 连接报错时的处理方式
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("消息发生错误:"+session.getId());
        error.printStackTrace();
    }

    /**
     * 如果需要服务器接受客户端的消息就在这里写了
     * @param text
     */
    @OnMessage
    public void onMessage(String text){
        log.info("接受到客户端传来的消息:"+text);
    }

    /**
     * 推送消息
     * getAsyncRemote获取异步端点(推荐使用这个)
     * getBasicRemote获取阻塞端点(不推荐,如果第一次发送失败,就会一直阻塞,影响后面的进行)
     * @param message
     */
    public static void sendMessage(WebSocketMessage message){
        // 遍历向所有用户发送消息
        clientMap.entrySet().stream().forEach(item ->{
            item.getValue().getAsyncRemote().sendText(message.getMessageContent());
        });
    }

    /**
     * 将消息发送给特定的用户
     */
    public static void sendToSpecClient(String clientId,WebSocketMessage webSocketMessage){
        if(clientMap.contains(clientId)){
            clientMap.get(clientId).getAsyncRemote().sendText(webSocketMessage.getMessageContent());
        }else{
            clientMap.remove(clientId);
            // throw new RuntimeException("特定用户消息发生错误,请稍后重试");
        }
    }


}

4.测试连接

用于测试ws的网站:http://www.jsons.cn/websocket/
本机联调的时候可以用
在这里插入图片描述

5.服务调用

 @PostMapping("message")
 public String sendWebSocketMessage(@Param("message") String message){
     String content = "向所有用户推送消息:"+message;
     WebSocketServer.sendMessage(new WebSocketMessage(null,"001",content));
     return "SUCCESS";
 }

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

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

相关文章

JAVA基础9:Debug

1.Debug概述 Debug:是供程序员使用的程序调试工具&#xff0c;它可以用于查看程序的执行流程&#xff0c;也可以用于追踪程序执行过程来调试程序。 2.Debug操作流程 Debug调试&#xff0c;又被称为断点调试&#xff0c;断点其实是一个标记&#xff0c;告诉我们从哪里开始查看…

自动化接口差异测试-diffy 回归测试 charles rewrite 请求

1、前言 大家好&#xff0c;今天小编向大家介绍一款自动化接口diff平台–diffy。diffy是twitter的开源项目&#xff0c;通过同时运行新/老代码&#xff0c;对比运行结果&#xff0c;发现潜在bug。diffy的原理是作为代理&#xff0c;截取请求并发送至所有运行的服务实例&#x…

【thop.profile】thop.profile计算网络参数量和计算效率

&#x1f34b;&#x1f34b;1.安装thop 安装thop有两种方式。 &#x1f3c6;第一种 pip install thop &#x1f3c6;第二种 用源码编译安装 从官网下载【github】thop安装压缩包下载压缩文件&#xff0c;解压到虚拟环境的site-packages文件下激活进入自己的虚拟环境cd到压缩…

Django实战项目-学习任务系统-任务完成率统计

接着上期代码内容&#xff0c;继续完善优化系统功能。 本次增加任务完成率统计功能&#xff0c;为更好的了解哪些任务完成率高&#xff0c;哪些任务完成率低。 该功能完成后&#xff0c;学习任务系统1.0版本就基本完成了。 1&#xff0c;编辑urls配置文件&#xff1a; ./mysi…

在windows上利用vmware17 搭建centos7 mini版本服务器

安装centos7mini 修改名称和安装路径 也可以点击自定义硬件&#xff0c;进行硬件配置修改 设置内存 设置处理器 点击下图按钮进行设置 点击done 点击开始安装 点击设置root密码 设置成功&#xff0c;点击done &#xff0c;root密码设置的简单的话需要按两次done 等待安装完成…

前端算法面试之堆排序-每日一练

如果对前端八股文感兴趣&#xff0c;可以留意公重号&#xff1a;码农补给站&#xff0c;总有你要的干货。 今天分享一个非常热门的算法--堆排序。堆的运用非常的广泛&#xff0c;例如&#xff0c;Python中的heapq模块提供了堆排序算法&#xff0c;可以用于实现优先队列&#xf…

微服务nacos实战入门

注册中心 在微服务架构中&#xff0c;注册中心是最核心的基础服务之一 主要涉及到三大角色&#xff1a; 服务提供者 ---生产者 服务消费者 服务发现与注册 它们之间的关系大致如下&#xff1a; 1.各个微服务在启动时&#xff0c;将自己的网络地址等信息注册到注册中心&#x…

四、Ribbon负载均衡

目录 一、负载均衡流程 1、我通过浏览器直接访问userservice/user/1&#xff0c;无法访问&#xff0c;说明是负载均衡做了相应的处理 2、我们来看一下代码中负载均衡的流程是怎样的 3、图像流程 二、负载均衡策略 1、修改负载均衡策略 &#xff08;方式一&#xff09; &a…

D. Jumping on Walls bfs

Problem - 199D - Codeforces 题目大意&#xff1a;有一个两个垂直的平行墙壁组成的一个峡谷。一个人初始是在左边墙壁第一层。在每个墙壁上有些障碍点&#xff0c;用X表示&#xff0c;这些障碍点不能被到达。&#xff0c;他可以执行以下三个操作&#xff1a; 向当前墙壁往上…

【ASP.NET】Hello World

文章目录 1. 几个概念2. 搭建开发环境2.1 .NET SDK2.2 IDE & Editor 3 First Project3.1 步骤3.2 模板3.3 项目结构3.4 请求的处理流程 Reference Link 1. 几个概念 .NET 是一个平台&#xff0c;包括 .NET Framework、.NET Core、ASP.NET、C#等&#xff0c;可以构建桌面、W…

文心一言 VS 讯飞星火 VS chatgpt (135)-- 算法导论11.3 1题

一、用go语言&#xff0c;假设我们希望查找一个长度为 n 的链表&#xff0c;其中每一个元素都包含一个关键字k并具有散列值h(k)。每一个关键字都是长字符串。那么在表中查找具有给定关键字的元素时&#xff0c;如何利用各元素的散列值呢? 文心一言&#xff1a; 在Go语言中&a…

若依前后分离版框架下Springboot java引入Mqtt接受发送消息

**这只是其中一种而且是粗浅的接、发消息。 同步机制还要跟搞物联网的同事沟通确认去看看能不能实现 或者是设备比较多的情况下 不会去使用同步机制 首先pom文件 引入依赖 ** <dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse…

spring cloud微服务中多线程下,子线程通过feign调用其它服务,请求头token等丢失

在线程池中&#xff0c;子线程调用其他服务&#xff0c;请求头丢失&#xff0c;token为空的情况 看了很多篇文章的处理方法和在自己亲测的情况下做出说明&#xff1a; 第一种&#xff1a; 这种方式只支持在主线程情况下&#xff0c;能够处理&#xff0c;在多线程情况下&#…

基于Python实现汽车销售数据可视化【500010086】

导入模块 import numpy as np import pandas as pd import plotly.graph_objects as go import plotly.express as px获取数据 df1 pd.read_excel(r"./data/中国汽车总体销量.xlsx") print(df1.head(5))df1.info()df1[年份] df1[时间].dt.year df1[月份] df1[时…

【论文阅读】GAIN: Missing Data Imputation using Generative Adversarial Nets

论文地址&#xff1a;[1806.02920] GAIN: Missing Data Imputation using Generative Adversarial Nets (arxiv.org)

【ML】欠拟合和过拟合的一些判别和优化方法(吴恩达机器学习笔记)

吴恩达老师的机器学习教程笔记 减少误差的一些方法 获得更多的训练实例——解决高方差尝试减少特征的数量——解决高方差尝试获得更多的特征——解决高偏差尝试增加多项式特征——解决高偏差尝试减少正则化程度 λ——解决高偏差尝试增加正则化程度 λ——解决高方差 什么是…

【Linux】Ubuntu16.04配置repo

Ubuntu16.04配置repo失败 在学习韦东山Linux嵌入式开发过程中&#xff0c;使用repo获取内核及工具链: git clone https://e.coding.net/codebug8/repo.gitmkdir -p 100ask_imx6ull-sdk && cd 100ask_imx6ull-sdk../repo/repo init -u https://gitee.com/weidongshan/m…

【Linux】gitee仓库的注册使用以及在Linux上远程把代码上传到gitee上的方法

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天为大家介绍一个在实际工作以及项目开发过程中非常实用的网站gitee&#xff0c;并教如何正确的使用这个网站以及常见问题的解决方案&#xf…

流量分析(信息安全铁人三项赛分区赛2-5.18)

题目描述 目录 题目描述 黑客的IP是多少 服务器1.99的web服务器使用的CMS及其版本号(请直接复制) 服务器拿到的webshell的网址(请输入url解码后的网址) 服务器1.99的主机名 网站根目录的绝对路径(注意最后加斜杠) 黑客上传的第一个文件名称是什么 黑客进行内网扫描&am…

实体门店创新神器曝光,拓世法宝AI智能直播一体机助力商家快速惊艳逆袭

在这个飞速变革的时代&#xff0c;传统实体门店面临着多重挑战。为了迎接市场的巨大变化&#xff0c;许多实体门店迫切寻求创新的方法来吸引顾客的眼球。数字化手段和新技术的引入成为实体门店应对市场需求的重要选择之一&#xff0c;是应对激烈竞争和不断变化的消费者行为的有…