WebSocket整合spring 一文全部搞定

news2024/11/25 11:00:15

文章声明

本文简单整合了webSocket 组件,涉及到的源码分解,原理什么的以后再说,本文只适合入门小白体验,不涉及复杂业务逻辑。

文章目录

        • 1 引入webSocket依赖包
        • 2 声明式整合WebSocket(这是一道硬菜)
          • 2.1 webSocket 配置类
          • 2.2 websocket 业务处理的主体部分
        • 测试
        • 3 客户端连接
        • 4 客户端连接测试用例
        • 关于WebSocket ip地址用域名替换,出现连接不上的问题

1 引入webSocket依赖包

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

2 声明式整合WebSocket(这是一道硬菜)

spring 给WebSocket整合提供了一套比较简单的声明式注解完成开发任务。

2.1 webSocket 配置类
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;

@EnableWebSocket
@Configuration
public class WebSocketConfig {

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

将此ServerEndpointExporter Bean对象注入到springBean 容器中,作用是检测带有@ServerEndpoint注释的Bean对象,并进行注册。

2.2 websocket 业务处理的主体部分

服务器通过webSocket 推送给客户端的消息就再次类中处理,本文的主体部分

import com.ruoyi.common.annotation.Anonymous;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

@Slf4j
@Component
@ServerEndpoint(value = "/ws/")
public class SocketController {

    private Session session;// 当前连接会话的客户端

	// 存放连接会话的全部客户端
    private static final CopyOnWriteArraySet<WarningSocketController> webSocketServers=new CopyOnWriteArraySet<>();

    @OnMessage
    public void onMessage(String message,Session session){
//        log.info("接收客户端的消息:{}",message);
    }

//获取连接的客户端信息
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
        webSocketServers.add(this);
        this.session=session;
    }

// 关闭连接
    @OnClose
    public void onClose(Session session, CloseReason closeReason){
        webSocketServers.remove(this);

    }
// 连接报错
    @OnError
    public void onError(Session session,Throwable throwable){
        throwable.printStackTrace();
        log.error("服务已断开");
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
    	// 给当前客户端推送消息
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 群发消息
     */
    public static void sendInfo(String message) {
        for (SocketController item : webSocketServers) {
            item.session.getAsyncRemote().sendText(message);
        }
    }
}

下面我就详细的讲一下各个注解的作用,和注解下的方法为什么参数这么写,都是有原因的。

第一个问题:private Session session;这个变量这么定义的含义是什么?
回答: 获取连接服务器的当前客户端。

第二个问题: private static final CopyOnWriteArraySet<WarningSocketController> webSocketServers=new CopyOnWriteArraySet<>(); 为什么缓存所有连接到本服务器的客户端?
**回答:**主要为了给全部客户端推送消息用。

测试

截止到目前,webSocket 服务端已经搭建完毕,可以测试了,基本格式ws://IP:port/,在线测试网站http://wstool.js.org/,我写的Demo测试样例:在这里插入图片描述,按照这个格式来。端口号,按照你的服务来。

3 客户端连接

本文封装了socket.js文件,提供了websocket连接,心跳,接收服务器消息等功能。

class WebSocketService {
  constructor(url) {
    this.url = url
    this.websocket = null
    this.reconnectInterval = 5000 // 重连间隔时间
    this.heartBeatInterval = 3000 // 心跳间隔时间
    this.heartBeatTimer = null
    this.connect()
  }

  websocket=null;


  connect() {
    this.websocket = new WebSocket(this.url)
    this.websocket.onopen = () => {
      console.log("WebSocket connected")
      this.startHeartBeat()
    }

    this.websocket.onclose = () => {
      console.log("WebSocket disconnected")
      this.stopHeartBeat()
      setTimeout( () => {
        console.log("WebSocket reconnecting…")
        this.connect()
      },this.reconnectInterval)
    }
    this.websocket.onerror = (error) => {
      console.log("WebSocket error:", error)
      this.websocket.close()
    }
    return this.websocket;
  }

   getMessage(fun){
    this.websocket.onmessage=function(message) {
      if(fun){
        fun(message.data);
      }
    }
  }

  startHeartBeat() {
    this.heartBeatTimer = setInterval ( () => {
      if(this.websocket.readyState === WebSocket.OPEN) {
        this.websocket.send("websocket  ping heartBeat")
      }
    }, this.heartBeatInterval)
  }

  stopHeartBeat() {
    clearInterval(this.heartBeatTimer)
  }
}

export default WebSocketService

4 客户端连接测试用例

// 初始化连接websocket
    initWebSocket(){
      this.warningSocket = new WebSocketService("ws://127.0.0.1:80/ws");
      this.warningSocket.connect();
      this.Message();
    },
    // 接收服务器推送的消息
    Message(){
      this.warningSocket.getMessage((data)=>{
        let row = JSON.parse(data)
        console.log(row)
      });
    }

浏览器打印在这里插入图片描述说明已经连接成功了。

关于WebSocket ip地址用域名替换,出现连接不上的问题

问题是域名在nginx配置的时候,并没有把websocket映射路径配置到nginx上,通过域名访问不到websocket 。

  location /ws {
                proxy_pass  http://155.255.255:80/ws; // 配置服务器IP地址,通过/ws转发访问到配置路径中。首先保证通过映射的服务器地址能够访问到websocket 不确定可以通过上面的网站测试
                proxy_set_header Host $host;
                proxy_set_header Upgrade 'websocket';
                proxy_set_header Connection 'Upgrade';
        }

测试用例:测试通过服务器访问websocket 在这里插入图片描述。全文终止,有时间在完善。

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

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

相关文章

Java 数据库时间返回前端显示错误(差8个小时)

文章目录 JsonFormat 与 DateTimeFormat 使用0 可能错误截图1 在属性上加自定义Json返回注释 JsonSerialize2 新建实体类 CustomDateTimeSerializer3 前端传后端格式转换&#xff08;ISO 日期格式&#xff09;转&#xff08;Data)4 一个注释解决双端转化问题 JsonFormat 与 Dat…

Java 本地缓存之王:Caffeine 保姆级教程

一、Caffeine介绍 1、缓存介绍 缓存(Cache)在代码世界中无处不在。从底层的CPU多级缓存&#xff0c;到客户端的页面缓存&#xff0c;处处都存在着缓存的身影。缓存从本质上来说&#xff0c;是一种空间换时间的手段&#xff0c;通过对数据进行一定的空间安排&#xff0c;使得下…

matplotlib 为图顶部和图右部的坐标轴添加标记label

Matplotlib 中&#xff0c;默认情况下&#xff0c;只有底部和左侧的坐标轴有标记 1 设置底部坐标轴标签 通过使用ax.xaxis.set_label_position() 调整标签的位置 import matplotlib.pyplot as plt# 创建一个图表 fig, ax plt.subplots()# 生成示例数据 x [1, 2, 3, 4, 5] …

激光焊接塑料多点测试全画面穿透率测试仪

工程塑料由于其具有高比强度、电绝缘性、耐磨性、耐腐蚀性等优点&#xff0c;已广泛应用于各个重要领域。另一方面&#xff0c;工程塑料还具有良好的焊接性&#xff0c;是制成复合材料的基体材料的优良选择&#xff0c;因此目前已成为国内外新型复合材料的研究热点。 工程塑料…

网络安全 Day27-运维安全项目-iptables防火墙

iptables防火墙 1. 防火墙概述2. 防火墙2.1 防火墙种类及使用说明2.2 必须熟悉的名词2.3 iptables 执行过程※※※※※2.4 表与链※※※※※2.4.1 简介2.4.2 每个表说明2.4.2.1 filter表 :star::star::star::star::star:2.4.2.2 nat表 2.5 环境准备及命令2.6 案例01&#xff1a…

c基础扫雷

和三子棋一样&#xff0c;主函数先设计游戏菜单界面&#xff0c;这里就不做展示了。 初始化棋盘 初级扫雷大小为9*9的棋盘&#xff0c;但排雷是周围一圈进行排雷(8格)&#xff0c;而边界可能会越界。数组扩大了一圈,行和列都加了2&#xff0c;所以我们用一个11*11的数组来初始化…

【论文阅读】基于深度学习的时序预测——Informer

系列文章链接 论文一&#xff1a;2020 Informer&#xff1a;长序列数据预测 论文二&#xff1a;2021 Autoformer&#xff1a;长序列数据预测 文章地址&#xff1a;https://arxiv.org/abs/2012.07436 github地址&#xff1a;https://github.com/zhouhaoyi/Informer2020 参考解读…

MySql之主从复制延时

MySql之主从复制延时 一、MySQL主从复制模型 一切都要从MySQL的主从复制模型开始说起&#xff0c;下图是最经典的MySQL主从复制模型架构图&#xff1a; 主从架构依赖于MySQL Binlog功能&#xff0c;Master节点上产生Binlog并将Binlog写入到Binlog文件中。 Slave节点上启动两…

java+springboot+mysql小区宠物管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的小区宠物管理系统&#xff0c;系统包含超级管理员&#xff0c;系统管理员、用户角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;用户管理&#xff1b;宠物分类&#xff1b;宠物管理&…

沁恒ch32V208处理器开发(二)工程配置

概述 MounRiver Studio在进行任何项目的开发时&#xff0c;为了提高效率&#xff0c;往往需要复用芯片厂家或第三方开发的成熟模块&#xff0c;这些模块通过一个.wvproj文件来进行组织&#xff0c;主要包含&#xff1a; 1&#xff09;MCU厂家提供的硬件接口文件&#xff0c;包…

20、stm32使用FMC驱动SDRAM(IS42S32800G-6BLI)

本文将使用安富莱的STM32H743XIH板子驱动SDRAM 引脚连接情况 一、CubeMx配置工程 1、开启调试口 2、开启外部高速时钟 配置时钟树 3、开启串口1 4、配置MPU 按照安富莱的例程配置&#xff1a; /* ********************************************************************…

用yum部署Zabbix(监控)!

目录 一、zabbix 是什么&#xff1f; 二、zabbix 监控原理 三、 安装 zabbix 3.1部署 zabbix 服务端 3.2 解决 zabbix-server Web页面中文乱码问题 3.2.1 解决问题 3.3 部署 zabbix 客户端 3.3.1服务端和客户端都配置时间同步 3.3.2客户端配置时区&#xff0c;与服务器保…

windows配置git公钥,读写远程git项目

首先Windows电脑需要下载并安装git&#xff1a; 从官网直接下载然后安装即可&#xff1a;https://git-scm.com/download/win 添加公钥 ssh-keygen -t rsa -C "xxxxxxx.com"注意&#xff1a;这个xxxxxxx.com与github注册的邮箱一致 然后一路回车&#xff0c;生成完…

centos7 安装wkhtmltopdf 0.12.6

最近恰好有html转图片的需要, 大约8年前也有使用过. 时间太久了, 也忘记, 以为有新技术出现, 百度了一圈, 都验证了下, 发现还是wkhtml功能最好用! 再次记录下, 方便使用的时候找的到, 也方便需要的小伙伴, 能更好的找到一份完整记录! wkhtmltopdf 看网上安装教程都是老版本的…

章节2:客户端的Cookie

章节2&#xff1a;客户端的Cookie 无状态的影响 现实&#xff1a;每个请求都是独立的 需求&#xff1a;保持会话 cookie内容 key/value 格式&#xff0c;例如&#xff1a; namewuya id99 islogin1 cookie怎么产生 Cookie格式 Set-Cookie&#xff1a;第一次访问&#…

MyBatis框架常见面试题

1、#{}和${}区别 ${}是Properties文件中的变量占位符&#xff0c;可以用于标签属性值和sql内部&#xff0c;属于静态文本替换&#xff0c;比如 : ${driver} 会被静态替换为com.mysql.jdbc.Driver #{}是 sql 的参数占位符&#xff0c;MyBatis 会将 sql 中的#{}替换为? 号&am…

【Echart地图】jQuery+html5基于echarts.js中国地图点击弹出下级城市地图(附完整源码下载)

文章目录 写在前面涉及知识点实现效果1、实现中国地图板块1.1创建dom元素1.2实现地图渲染1.3点击地图进入城市及返回 2、源码分享2.1 百度网盘2.2 123云盘2.3 邮箱留言 总结 写在前面 这篇文章其实我主要是之前留下的一个心结&#xff0c;依稀记得之前做了一个大屏项目的时候&…

springboot中@Async的简单用法

springboot中Async的简单用法 文章目录 springboot中Async的简单用法开启配置Async的使用无返回值调用带返回值的调用 开启配置 在配置文件或者入口文件上新增注解: EnableAsync即可 Async的使用 对应需要异步调用的方法上添加Async注解即可 无返回值调用 controller代码 …

中睿天下Coremail | 2023年第二季度企业邮箱安全态势观察

今日&#xff0c;中睿天下联合Coremail邮件安全发布《2023第二季度企业邮箱安全性研究报告》&#xff0c;对2023第二季度和2023上半年的企业邮箱的安全风险进行了分析。 一 垃圾邮件同比下降16.38% 根据监测&#xff0c;2023年Q2垃圾邮件数量达到6.47亿封&#xff0c;环比下降…

服务端本地图片存储 / 读取的方案

需求 将前端传递过来的图片存储到项目的一个指定目录中&#xff0c;并且将图片在项目中的相对路径存储到数据库中存储&#xff0c;前端获取相对路径后可以直接访问到该图片上 技术实现&#xff1a; 在SpringBoot项目中&#xff0c;我们可以在resource目录下创建一个 "sta…