WebSocket使用记录

news2024/10/7 20:27:39

使用视频地址

1、添加前端使用文件

在这里插入图片描述

2、后端配置

2.1添加依赖

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

2.2添加websocket配置类

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

/**
 * websocket配置类
 */
@Configuration
public class WebSocketConfig {

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


}

2.3 添加WebSocketServer

package com.example.websocket.webSocket;

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

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 */
@Slf4j
@ServerEndpoint(value = "/websocket/asset")
@Component
public class WebSocketServer {


    @PostConstruct
    public void init() {
        log.info("=============websocket 加载===================");
    }

    private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0);
    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。
     */
    private static final CopyOnWriteArraySet<Session> SESSION_SET = new CopyOnWriteArraySet<>();


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        SESSION_SET.add(session);
        // 在线数加1
        int cnt = ONLINE_COUNT.incrementAndGet();
        log.info("有连接加入,当前连接数为:{}", cnt);
        sendMessage(session, "连接成功");
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        SESSION_SET.remove(session);
        int cnt = ONLINE_COUNT.decrementAndGet();
        log.info("有连接关闭,当前连接数为:{}", cnt);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("来自客户端的消息:{}", message);
        sendMessage(session, "收到消息,消息内容:" + message);

    }

    /**
     * 出现错误
     *
     * @param session session
     * @param error  error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误:{},Session ID: {}", error.getMessage(), session.getId());
        error.printStackTrace();
    }

    /**
     * 发送消息,实践表明,每次浏览器刷新,session会发生变化。
     *
     * @param session session
     * @param message message
     */
    public static void sendMessage(Session session, String message) {
        try {
            session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)", message, session.getId()));
        } catch (IOException e) {
            log.error("发送消息出错:{}", e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 群发消息
     *
     * @param message  message
     * @throws IOException 异常
     */
    public static void broadCastInfo(String message) throws IOException {
        for (Session session : SESSION_SET) {
            if (session.isOpen()) {
                sendMessage(session, message);
            }
        }
    }

    /**
     * 群发消息
     *
     * @param code  code
     * @throws IOException 异常
     */
    public static void broadCastInfoByCode(int code) throws IOException {
        for (Session session : SESSION_SET) {
            if (session.isOpen()) {
                sendMessageByCode(session, code);
            }
        }
    }


    /**
     * 发送消息 返回编码
     * @param session  session
     * @param code  code
     */
    public static void sendMessageByCode(Session session, int code) {
        try {
            session.getBasicRemote().sendObject(code);
        } catch (IOException | EncodeException e) {
            log.error("发送消息出错:{}", e.getMessage());
            e.printStackTrace();
        }
    }
    /**
     * 指定Session发送消息
     *
     * @param sessionId sessionId
     * @param message message
     * @throws IOException 异常
     */
    public static void sendMessage(String message, String sessionId) throws IOException {
        Session session = null;
        for (Session s : SESSION_SET) {
            if (s.getId().equals(sessionId)) {
                session = s;
                break;
            }
        }
        if (session != null) {
            sendMessage(session, message);
        } else {
            log.warn("没有找到你指定ID的会话:{}", sessionId);
        }
    }

}

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

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

相关文章

NETSDK1141 无法解析位于 global.json 中指定的 .NET SDK 版本

1. 使用cmd命令 dotnet --info 查看自己使用的SDK版本 3.直接找到项目中的 global.json 文件&#xff0c;右键打开&#xff0c;直接修改版本为本机的SDK版本&#xff0c;就可以用了 微软文档也有详细说明: ​​​​​​NETSDK1141&#xff1a;无法解析 global.json 中指定的…

浅析CAS

CAS基本使用 以ReentrantLock为例&#xff0c;观察CAS基本使用。 class ReentrantLockExample {int a 0;// 非公平锁ReentrantLock lock new ReentrantLock(false);public void writer() {// 获取锁lock.lock();try {a;} finally {// 释放锁lock.unlock();}}public void re…

生产环境 kafka 平滑迁移之旅

文章目录 背景分析测试环境验证现实很残酷两种抉择-----leader分区切换方案选择实施步骤手工副本集增加步骤手工leader分区切换步骤 总结 背景 线上kafka集群&#xff0c;3台机器&#xff0c;3个broker&#xff1b;其中某台机器因为硬件故障&#xff0c;需要停机维修&#xff…

MSP432学习笔记12:MSP432时钟源与定时器A时钟源配置

今日深入学习一下MSP432的时钟源与配置&#xff0c; 可以结合之前的滴答计时器相关文章&#xff1a; MSP432学习笔记4&#xff1a;时钟与滴答计时器_NULL指向我的博客-CSDN博客 目录 MSP432有关时钟源系统的性能&#xff1a; 七种时钟源&#xff1a; 五种时钟&#xff1a; …

创新实践,复合机器人采摘运输教育沙盘案例研究

引言 在之前我们已经介绍了水果采摘和分拣机器人的应用场景&#xff0c;今天我们来介绍复合机器人水果采摘运输的场景。 作为最热门的技术领域&#xff0c;机器人技术正在彻底改变各行各业&#xff0c;推动全球创新。为了满足这一快速发展领域对专业技术人才日益增长的需求&a…

【Matlab】智能优化算法_广义正态分布优化算法GNDO

【Matlab】智能优化算法_广义正态分布优化算法GNDO 1.背景介绍2.数学模型2.1 局部开采2.2 全局勘探 3.文件结构4.伪代码5.参考文献 1.背景介绍 GNDO受到正态分布理论的启发。正态分布也称为高斯分布&#xff0c;是描述自然现象的一个非常重要的工具。正态分布可以定义如下。假设…

NLP Transformer的Decoder的输入输出都是什么?能解释一下每个部分都是什么?

要弄清楚Decoder的输入输出&#xff0c;关键在于图示三个箭头的位置&#xff1a; 以翻译为例&#xff1a; 输入&#xff1a;我爱中国输出&#xff1a; I Love China 因为输入&#xff08;“我爱中国”&#xff09;在Encoder中进行了编码&#xff0c;这里我们具体讨论Decoder的…

【工具推荐】企业微信、企业飞书接口调用工具

github地址: GitHub - fasnow/idebug: 企业微信、企业飞书接口调用工具。 简介 企业微信、企业飞书接口调用工具。 使用方法 wechat模块 使用use wechat 选择模块。 首先设置corpid和corpsecret&#xff0c;如有需要可以设置代理&#xff0c;之后再执行run命令。 导出通信…

飞行动力学 - 第6节-part3-风对航程的影响 之 基础点摘要

飞行动力学 - 第6节-part3-风对航程的影响 之 基础点摘要 1. 风对航程的影响2. 典型飞机航程3. 世界上最长航线4. 参考资料 1. 风对航程的影响 可以认为风移动的距离相当于飞机在静止空间移动的距离加上风移动的距离。 在物理上可以简单的理解为两个矢量叠加和。 回顾喷气式&…

WebGPU实战3D电商

在过去的几年里&#xff0c;我们一直在为 WebGPU 编写新版本的 Babylon.js 引擎。 随着下一代 Web 3D 即将在Chrome 102~103版本上公开WebGPU 1.0 &#xff0c;人们的兴奋情绪与日俱增。 在这篇博文中&#xff0c;我将快速概述这个新的 Babylon.js WebGPU 引擎&#xff0c;并将…

100种思维模型之安全边际思维模型-92

安全边际&#xff0c; 简而言之即距离某一件糟糕的事件发生&#xff0c;还有多大的空间&#xff0c;安全边际越高&#xff0c;我们就越安全&#xff01; 安全边际思维模型一个 让生活变得更从容 的 思维模型。 01、何谓安全边际思维模型 一、安全边际思维 安全边际 源于…

千云探探监测到7月4日法国Facebook社交网络异常

针对法国近期出现的骚乱游行&#xff0c;法国司法部长莫雷蒂7月1日时候表示&#xff0c;法国检察官要求互联网运营商提供在社交平台Snapchat上号召骚乱年轻人的IP地址。 法国总统马克龙7月4日表示&#xff1a;“如果事态失控&#xff0c;我们可能需要监管或关闭它们&#xff0…

idea 添加类库

打开项目中的独立环境文件夹&#xff0c;右键打开终端输入安装类库的命令&#xff1a; pip install requests pip3 install BeautifulSoup4 检查这里是否把类库加进来了&#xff0c;加进来就完成&#xff01;

第十二章 kafka

Producer:Producer即生产者,消息的产生者,是消息的入口。 kafka cluster: Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等…… 主…

Windows如何恢复已删除的Word文档?

案例&#xff1a;可以恢复已删除的Word文档吗&#xff1f; “大家好&#xff0c;我遇到了一个问题&#xff0c;需要大家的帮助。昨天我编辑了一个Word文档并保存到了桌面上&#xff0c;但当我今天再次打开电脑时&#xff0c;它就不见了&#xff01;昨天工作完成后&#xff…

mysql数据库以及管理流程

目录 1.基本概念 2.DBMS工作模式 3.关系型数据库和非关系型数据库 4.数据库管理 sql语句 5.一些命令 6.增删改查命令 DDL DML 7.案例 创建表 删除 DML管理表中内容 增加内容 改内容 删内容 DCL具体应用 1.基本概念 1.数据 描述事物的符号记录(数字 文字 图像等) …

【报错记录】解决CentOS免密失败的问题,以及解决免密问题的排查流程

前言 本文相当于对之前的文章进行的补充【原创】三台CentOS7非root用户间实现相互间的免密登录_DCTANT的博客-CSDN博客 现场遇到一台旧服务器与其他服务器免密失败的问题&#xff0c;明明.ssh目录中authorized_keys中的公钥设置都是正确的&#xff0c;但是别的服务器连它都得…

基础篇--STM32原理图设计

学会查看数据手册 芯片数据手册获取方式 ST官网&#xff1a;https://www.st.comST中文社区网&#xff1a;https://www.stmcu.org.cn/ 数据手册内容概要 芯片的基本参数&#xff08;STM32F103ZET6为例&#xff09; 主频/FLASH/SRAM &#xff1a; 72MHz/512KB/64KB工作电压/…

vue3 + axios 实现带进度条的下载对话框

文章目录 问题实现采用axios实现下载请求写一个进度下载对话框调用对话框 参考链接 问题 上传下载是前端经常面临的两大需求&#xff0c;当文件比较大时&#xff0c;下载进度显示能提升用户体验。本文结合vue3介绍下载对话框的实现。当点击页面中下载按钮后&#xff0c;会呈现…

在日常学习生活中,究竟该如何保持稳定的情绪呢?

方向一&#xff1a;分享工作中让你有强烈情绪波动的事情 编程仅仅是工程的过程实践化&#xff0c;投入进去确实会出现精神集中&#xff0c;出现问题排查过程会绞尽脑汁&#xff0c;甚至抓耳挠腮&#xff0c;当发现问题无法解决时不如放下来想一想&#xff0c;是不是知识点掌握不…