SpringBoot 整合 Websocket 通信demo (附浏览器聊天窗口)

news2024/11/26 23:47:59

1. 依赖

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

2. 自动注册配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

    /**
     * ServerEndpointExporter 作用
     *
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

 
3. WebSocket服务类

import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;


/**
 * postman访问: ws://localhost:8080/ws/{userId}
 * 浏览器访问:  http://localhost:8080/ws
 */
@Component
@ServerEndpoint("/ws/{userId}")
public class WebSocketServer {

    private static int onlineCount = 0;
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
    private Session session;
    private String userId = "";

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        webSocketSet.add(this);     //加入set中
        addOnlineCount();           //在线数加1
        this.userId = userId;
        sendMessage(userId + "用户" + ", 连接成功 !");

        System.out.println("【websocket】 " + userId + "用户" + "已连接!当前在线人数为" + getOnlineCount());
    }

    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1

        System.out.println("【websocket】 " + userId +  "用户" +  "已关闭!当前在线人数为" + getOnlineCount());
    }

    @OnMessage
    public void onMessage(String message, Session session) {

        if(message.startsWith("target-")){
            int index = message.indexOf(":");
            String userId = message.substring(7,index);
            sendInfo(message.substring(index + 1), userId);
            return;
        }

        this.session = session;
        sendMessage("【websocket】 服务端收到来自窗口" + userId + "发送的消息:" + message);

    }

    @OnError
    public void onError(Session session, Throwable error) {
        this.session = session;
        error.printStackTrace();
    }

    private void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 群发消息
    /**
     * 群发自定义消息
     */
    public static void sendInfo(String message, @PathParam("userId") String userId) {
        System.out.println("【websocket】 推送消息给" + userId +  "用户" + ",推送内容:" + message);

        for (WebSocketServer item : webSocketSet) {
            //这里可以设定只推送给这个userId的,为null则全部推送
            if (userId == null) {
//                    item.sendMessage(message);
            } else if (item.userId.equals(userId)) {
                item.sendMessage(message);
            }
        }
    }


    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

    public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {
        return webSocketSet;
    }
}

4. 模拟通信

​
访问:http://localhost:8080/ws

可以打开多个

开始连接,一个客户端给另一个客户端发消息。

可以服务端推送消息给所有连接的客户端

POST:http://localhost:8080/push

任意内容

​

5. 需要完整代码的可私信我

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

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

相关文章

Timeline的使用心得

timeline使用教程 timeline使用主要分为一下几步&#xff1a; 1、新建表格&#xff1b; 2、设置数据 3、发布网址 4、修改表格样式&#xff1b; 5、快速预览 需要用到的几个网址&#xff1a; 1、timeline官网网址&#xff1a;timeline 2、本地图片转链接&#xff1a;图片转链…

创建react脚手架项目——demo(react18 + react-router 6)

创建react脚手架项目——demo&#xff08;react18 react-router 6&#xff09; 1. 安装 create-react-app1.1 执行安装命令1.2 安装遇到的问题1.2.1 问题1——npm ERR! code ENOTFOUND 2. 创建项目2.1 创建项目命令2.2 查看项目结构2.2.1 目录结构2.2.2 注意点 3. 启动项目4. …

分享一下在微信公众号上怎么实现表单功能

在微信公众号上实现表单功能可以帮助公众号运营者与用户进行互动&#xff0c;收集用户反馈&#xff0c;提供个性化服务&#xff0c;以及进行数据分析等。以下是在微信公众号上实现表单功能的一些步骤和建议。 一、了解微信公众号平台的功能 首先&#xff0c;你需要了解微信公众…

关于《考研数学高分公式》系列的后续及一点说明

写在前面 在昨天&#xff0c;当我再次登录CSDN时&#xff0c;我惊讶地发现《考研数学高分公式》这一系列的两篇文章竟然拥有超过数万次的阅读量。许多学弟学妹也通过私信向我询问&#xff0c;为什么不再继续更新这个系列了。 未及时回复他们&#xff0c;颇感惭愧。 我仔细考…

预约到家按摩小程序开发定制同城服务

随着生活节奏加快&#xff0c;生活压力也随之而来&#xff0c;很多人忙于工作与生计&#xff0c;身体和心理两方面都在承受重压。而按摩能够消除身体的疲惫&#xff0c;增强人的身体体质&#xff0c;在劳累过后放松身心按摩一会儿&#xff0c;可以快速恢复精神状态&#xff0c;…

智能3D人体导医系统源码 智能导诊系统源码

智能3D人体导医系统源码 医院智能导诊系统是在医疗中使用的引导患者自助就诊挂号&#xff0c;在就诊的过程中有许多患者不知道需要挂什么号&#xff0c;要看什么病&#xff0c;通过智能导诊系统&#xff0c;可输入自身疾病的症状表现&#xff0c;或选择身体部位&#xff0c;在…

云的灵魂是人工智能

在这个数字化飞速发展的时代&#xff0c;云计算已经成为了我们生活中不可或缺的一部分。而随着人工智能技术的不断进步&#xff0c;云的灵魂也逐渐被赋予了人工智能的色彩。让我们一起探讨这个新兴的话题&#xff0c;一起展望云计算与人工智能的融合所带来的巨大变革。 一、GPU…

中风失语 18 年,AI + 脑机接口帮她「意念发声」

人与人交往中&#xff0c;说话表达是最基本的能力和方式&#xff0c;可世界上有很多人&#xff0c;却「有口难言」。 「失语症」中&#xff0c;由中风引起的最为常见。他们的声音无法传达&#xff0c;他们的诉求不为人所知&#xff0c;他们遭受着社交孤立&#xff0c;他们的沉默…

“混合”引擎为通用子模块提供动力,实现嵌入式I / O灵活性

现成的组件对于嵌入式开发工程师而言并不是什么新鲜事物。但是&#xff0c;实际上没有人期望一种“一刀切”的解决方案&#xff0c;尤其是在涉及复杂的I / O要求的情况下。 但是&#xff0c;基于流行的夹层卡格式的具有成本效益的现场可编程门阵列&#xff08;FPGA&#xff09…

DALLE-2

扩散模型做图像生成使用clip预训练好的特征去做层级式的依托于文本的图像生成先生成小分辨率图像64*64然后利用一个模型上采样到256*256&#xff08;迭代&#xff09;先训练好一个clip模型&#xff0c;学习到图像文本对的关系 图像生成的模型 AEDAEVAEVQVAEDALL-E &#xff1…

Pycharm 配置python项目本地运行环境

1.打开Pycharm,打开Setting 2. 新建本地环境 3.如果报错如上图所示&#xff0c;请通过cmd来新建本地环境&#xff0c;具体步骤如下 在对应的代码路径下&#xff0c;通过virtualenv venv来创建虚拟路径 安装好之后&#xff0c;安装对应的依赖包即可 pip3 install -r ./require…

如何在windows环境下编译T

一&#xff0c; 安装MYSYS2 1. 去https://www.msys2.org下载 msys2-x86_64-xxxxx.exe; 2. 按照msys2.org主页提示的步骤安装; 3.安装完默认起来的是 UCRT的&#xff0c; 可以根据环境的需要选择&#xff0c; 我选择的 MSYS2 MINGW64 4. 搭建编译环境&#xff0c; 安装对应的软…

反常积分的概念与计算

目录 无穷区间上的反常积分 无界函数的反常积分 反常积分的敛散性 反常积分的计算 无穷区间上的反常积分 无穷区间上的反常积分(improper integral on infinite interval)是一种反常积分 设函数f(x)在(a,∞)上有定义&#xff0c;且f(x)在任意有限区间(a,A)(A>a)上可积&…

一生一芯15——jupyter notebook搭建与对应kernel的设置

本文参照 https://zhuanlan.zhihu.com/p/403183676?utm_id0 https://blog.csdn.net/moledyzhang/article/details/78850820 进入虚拟环境Chisel conda activate Chisel安装jupyter pip3 install jupyter查看内核 jupyter kernelspec list此处我已经安装好&#xff0c;否则…

大学生实习考勤打卡系统 微信小程序uniapp

本毕业设计的内容是设计实现一个学生实习考勤的打卡小程序。它是以 springboot框架&#xff0c;MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。学生实习考勤的打卡的功能已基本实现&#xff0c;主要包括学生、实习单位、实习打卡、考研申报、找工作申报…

AQS锁原理

文章目录 一、AQS是什么&#xff1f;二、AQS原理三、STATE&#xff1a;状态四、AQS共享资源的方式&#xff1a;独占式和共享式4.1 独占式实现4.1 共享式 总结 一、AQS是什么&#xff1f; AQS&#xff08;Abstract Queued Synchronizer&#xff09;是一个抽象的队列同步器&…

节距信号发生器(成缆变节距控制)

成缆机系统控制,请查看下面文章链接 ,这篇文章主要介绍节距信号发生器算法原理和代码,博途PLC信号发生器链接地址如下: PLC信号发生器(博途SCL)_RXXW_Dor的博客-CSDN博客信号发生器的应用请参看下面的博客文章,在演示滤波器的作用时,我们可能也会用到信号的叠加等。博途…

嵌入式学习笔记(29)轮询方式处理按键

X210开发板的按键接法 &#xff08;1&#xff09;查原理图&#xff0c;找到按键对应的GPIO&#xff1a;SW5:GPH0_2 SW6:GPH0_3 SW78910:GPH2_0123 &#xff08;2&#xff09;原理图上可看出&#xff1a;按下时是低电平&#xff0c;弹起时是高电平。 按键对应的GPIO模式设置 …

gcc/c++ 版本不一致问题导致的

1.问题 rk3566板子的系统是ubuntu20.04 focal&#xff0c; /etc/apt/source.list更换为阿里源 x86-67的pc主机系统的是ubuntu20.04 jammy /etc/apt/source.list 更换为清华源 按照rknpu2的开发教程Rockchip_Quick_Start_RKNN_SDK_V1.5.2_CN.pdf&#xff1a; 交叉编…

C语言--strcat函数

C语言–strcat函数 文章目录 C语言--strcat函数一、strcat函数是什么&#xff1f;二、使用示例二、模拟实现 一、strcat函数是什么&#xff1f; 作用是把源数据追加到目标空间 char * strcat ( char * destination, const char * source );源字符串必须以 ‘\0’ 结束。目标空…