SpringBoot 使用WebSocket功能

实现步骤:

1.导入WebSocket坐标。

在pom.xml中增加依赖项:

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

2.编写WebSocket配置类,用于注册WebSocket的Bean。

package com.rc114.config;

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

/**
 * WebSocket配置类,用于注册WebSocket的Bean
 * @author Administrator
 */
@Configuration
public class WebSocketConfiguration {

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

}

3.编写WebSocketServer类。

package com.rc114.websocket;

import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * WebSocket服务
 * @author Administrator
 */
@Component  //  交给spring容器管理
@ServerEndpoint("/ws/{sid}")    //  路径请求
public class WebSocketServer {

    //存放会话对象
    private static Map<String, Session> sessionMap = new HashMap();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端:" + sid + "建立连接");
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("收到来自客户端:" + sid + "的信息:" + message);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClient(String message) {
        Collection<Session> sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

4.测试WebSocket

编写一个测试WebSocket的html页面:

<html>

<head>
    <title>WebSocket测试页面</title>
    <style type="text/css">
        * {
            font-size: 14px;
            line-height: 22px;
        }

        .main {
            border: 0px solid #ccc;
            width: 60%;
            margin: 0 auto;
            padding: 10px;
        }

        .main-table {
            width: 100%;
            border: 1px solid #ccc;
            border-collapse: collapse;
        }

        .main-table td {
            border: 1px solid #ccc;
            padding: 5px;
        }

        .td-left {
            text-align: right;
        }

        input[type="text"] {
            border: 1px solid #ccc;
            padding: 5px;
            outline: none;
            width: 200px;
        }

        input[type="button"] {
            border: 1px solid #ccc;
            padding: 3px 10px;
            outline: none;
        }

        .green {
            color: green;
        }

        .red {
            color: red;
        }

        #msg {
            font-size: 12px;
            line-height: 22px;
        }
    </style>
</head>

<body>
    <div class="main">
        <table class="main-table">
            <tr>
                <td colspan="2" style=" text-align: center;font-weight: bold;">WebSocket测试</td>
            </tr>
            <tr>
                <td style="width: 100px;" class="td-left">服务器地址</td>
                <td><input type="text" id="server" value="ws://localhost:8080/ws/"></td>
            </tr>
            <tr>
                <td class="td-left">客户端名称</td>
                <td><input type="text" id="clientId">
                    <input type="button" value="随机生成" onclick="GenerateClientId()" />
                </td>
            </tr>
            <tr>
                <td> </td>
                <td>
                    <input type="button" value="连接" onclick="ConnectServer()" />
                </td>
            </tr>
            <tr>
                <td class="td-left">连接状态</td>
                <td> <span id="status"><span class='red'>未连接</span></span></td>
            </tr>
            <tr>
                <td class="td-left">发送消息</td>
                <td>
                    <input type="text" id="txt">
                </td>
            </tr>
            <tr>
                <td> </td>
                <td>
                    <input type="button" value="发送" onclick="SendMsg()" />
                    <input type="button" value="清空" onclick="ClearLog()" />
                </td>
            </tr>
            <tr>
                <td class="td-left">日志</td>
                <td>
                    <div id="msg"></div>
                </td>
            </tr>
        </table>

        <script type="text/javascript">
            var websocket = null;
            var clientId = "";

            //随机生成客户端编号
            function GenerateClientId() {
                clientId = Math.random().toString().substr(2);
                document.getElementById("clientId").value = clientId;
            }
            GenerateClientId();

            //连接到服务器
            function ConnectServer() {
                var clientId = document.getElementById("clientId").value;
                if (clientId == "") {
                    alert("客户端编号不能为空!");
                } else {
                    if ("WebSocket" in window) {
                        websocket = new WebSocket("ws://localhost:8080/ws/" + clientId);

                        websocket.onerror = function () {
                            ShowMsg("<span class='red'>ERROR</span>");
                        }
                        websocket.onopen = function () {
                            document.getElementById("status").innerHTML = "<span class='green'>已连接</span>";
                            ShowMsg("<span class='green'>连接成功!</span>");
                        }
                        websocket.onmessage = function (event) {
                            ShowMsg(event.data);
                        }
                        websocket.onclose = function () {
                            ShowMsg("<span class='red'>断开连接</span>");
                        }

                    }
                    else {
                        alert("NOT SUPPORT WEBSOCKET!");
                    }
                }
            }



            //网页关闭时,断开链接
            window.onbeforeunload = function () {
                websocket.close();
            }

            //显示日志
            function ShowMsg(msg) {
                document.getElementById("msg").innerHTML += Now() + " " + msg + "<br/>";
            }

            //发送消息
            function SendMsg() {
                var txt = document.getElementById("txt").value;
                websocket.send(txt);
                ShowMsg("<span class='green'>发送消息:" + txt + "</span>");
            }

            //断开链接
            function closeWebSocket() {
                websocket.close();
            }

            function Now() {
                const date = new Date();
                const year = date.getFullYear();
                const month = (date.getMonth() + 1).toString().padStart(2, '0');
                const day = date.getDate().toString().padStart(2, '0');
                const hour = date.getHours().toString().padStart(2, '0');
                const minute = date.getMinutes().toString().padStart(2, '0');
                const second = date.getSeconds().toString().padStart(2, '0');
                const format = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
                return format;
            }

            //清空日志
            function ClearLog() {
                document.getElementById("msg").innerHTML = "";
            }
        </script>
    </div>
</body>

</html>

运行效果:

注意:

如果使用了Nginx转发请求的,需在Nginx配置WebSocket的转发规则。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis学习——高级篇⑨

Redis学习——高级篇⑨ Redis7高级之Redlock算法和Redisson的使用&#xff08;十&#xff09; 10.1 Redlock 红锁算法1.解决手写分布式锁的单点故障问题2.设计理念3. 解决方案 10.2 Redisson进行代码改造10.3 多机案例&#xff08;解决单点故障&#xff09;10.4 R…

vue3使用is动态切换组件报错Vue received a Component which was made a reactive object.

vue3使用is动态切换组件&#xff0c;activeComponent用ref定义报错 Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with markRaw or using shallowRef ins…

代码随想录算法训练营29期|day36任务以及具体安排

第八章 贪心算法 part05 435. 无重叠区间 class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, (a,b)-> {return Integer.compare(a[0],b[0]);});if(intervals.length 1) return 0;int result 0;for(int i 1 ; i < interva…

结构体与共用体——共用体——C语言——day16

昨天介绍了下结构体&#xff0c;今天主要介绍共用体&#xff0c;枚举 共用体 概念&#xff1a;有时需要使几种不同类型的变量存放到同一段内存单元中。 例如&#xff0c;可把一个整型变量、一个字符型变量、一个浮点型变量放在同一个地址开始的内存单元中 。以上三个变量在内…

Python系列-字典

&#x1f308;个人主页: 会编程的果子君 ​&#x1f4ab;个人格言:“成为自己未来的主人~” ​ 目录 ​ 字典是什么 创建字典 查找key 新增/修改元素 删除元素 遍历字典元素 取出所有的key和value 合成的key类型 ​编辑 小结 字典是什么 字典是一种存储键值对的结…

云打印怎么收费?云打印需要付费吗?

随着云打印概念的火热发展&#xff0c;很多有打印需求的App或者个人用户都想使用易绘创云打印服务。那么易绘创云打印怎么收费&#xff1f;云打印需要付费吗&#xff1f;今天就带大家来了解一下。 云打印怎么收费&#xff1f;云打印需要付费吗&#xff1f; 很多有打印需求的小…

Linux网络状态查看与防火墙管理

网络状态查看 netstat [选项] Netstat是一款命令行工具&#xff0c;用于显示Linux系统中网络的状态信息&#xff0c;可以显示网络连接、路由表、连接的数据统计等信息。 使用 选项 -a&#xff1a;显示所有选项&#xff0c;包括监听和未监听的端口。 -t&#xff1a;仅显示tc…

IS-IS的LSP分片扩展

原理 IS-IS通过泛洪LSP来宣告链路状态信息,由于一个LSP能够承载的信息量有限,IS-IS将对LSP进行分片。每个LSP分片由产生该LSP的结点或伪结点的SystemID、PseudnodeID(普通LSP中该值为0,Pseudonode LSP中该值为非0)、LSPNumber(LSP分片号)组合起来唯一标识,由于LSPNumb…

微信小程序(二十四)简易的双向绑定

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.双向绑定实例 2.双向绑定的局限性 源码&#xff1a; index.wxml <!-- 1.placeholder:输入框为空时的占位提示语2.model:value 双向绑定&#xff08;其实就是在原先基础上加上了model:&#xff09; 3.目前双…

小白水平理解面试经典题目LeetCode 118 Pascal‘s Triangle【Java实现】

LeetCode 118 生成杨辉三角&#xff08;Pascal’s Triangle&#xff09; 小白渣翻译 给定一个非负整数 numRows&#xff0c;生成杨辉三角的前 numRows 行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 例子 这里是小白理解 那么这种题目一上来看&#xf…

C++进阶(九)哈希概念哈希函数哈希冲突

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、哈希概念1、哈希介绍2、哈希与哈希表 二、哈希冲突三、哈希函数四、 哈希冲突解决 一、哈…

ElementUI Form:Checkbox 多选框

ElementUI安装与使用指南 Checkbox 多选框 点击下载learnelementuispringboot项目源码 效果图 el-checkbox.vue &#xff08;Checkbox 多选框&#xff09;页面效果图 项目里el-checkbox.vue代码 <script> const cityOptions [上海, 北京, 广州, 深圳] export def…

react 之 UseMemo

useMemo 看个场景 下面我们的本来的用意是想基于count的变化计算斐波那契数列之和&#xff0c;但是当我们修改num状态的时候&#xff0c;斐波那契求和函数也会被执行&#xff0c;显然是一种浪费 // useMemo // 作用&#xff1a;在组件渲染时缓存计算的结果import { useState …

【C++干货铺】哈希结构在C++中的应用

目录 unordered系列关联式容器 unordered_map unordered_map的接口说明 1.unordered_map的构造 2. unordered_map的容量 3. unordered_map的迭代器 4. unordered_map的元素访问 5. unordered_map的查询 6. unordered_map的修改操作 7. unordered_map的桶操作 底层结构 …

Nijijourney V6版本动漫图像生成模型发布

简介 这是一个最先进的AI&#xff0c;可以绘制任何二次元风格的绘画&#xff01;这是一个由 Spellbrush 与 Midjourney 所共同设计开发的魔法般工具。无论您是在寻找可爱的Q版角色还是充满动感的动作场景&#xff0c;niji・journey 都能将您的想象变为现实。 功能介绍 - 增强…

深度解析:i++ 与 ++i,探究其性能差异与使用技巧

在编程世界中&#xff0c;经常会遇到对变量进行递增操作&#xff0c;而i和i这两个递增操作符就是我们常用的两种方式。这两者看似简单&#xff0c;但却有着微妙的性能区别和使用差异。 1. 性能差异的探究 首先&#xff0c;我们来研究i和i在性能上的微妙差异。这对于编写高效的…

搭建 idea 插件仓库私服

正常情况下&#xff0c;我们开发的 idea 插件会发布到 idea 官方商城中&#xff0c;这样用户就可以在 idea 的 Marketplace 中搜索安装。 但是在企业内部&#xff0c;有可能我们开发了很多内部插件&#xff0c;而不能发布到公共市场中&#xff0c;这种情况下我们就需要搭建一个…

子查询练习1

数据表 链接&#xff1a;https://pan.baidu.com/s/1dPitBSxLznogqsbfwmih2Q 提取码&#xff1a;b0rp --来自百度网盘超级会员V5的分享 子查询举例 子查询的分类 单行子查询 > > < < ! <> 单行子查询 WHERE中的子查询 查询工资大于149号…

智源成立5年,高层大变动!黄铁军不再担任院长,张宏江、唐杰、刘江均已离任

大家好&#xff0c;我是二狗。 就在刚刚&#xff0c;北京智源人工智能研究院官方微信公众号宣布&#xff1a;王仲远博士加入智源研究院&#xff0c;接任院长一职&#xff0c;全面负责研究院各项工作&#xff0c;黄铁军不再兼任智源研究院院长。 智源表示&#xff0c;黄铁军于2…

Dubbo之架构源码公共知识

1.ScopeModel 抽象这三个能力是为了实现 Dubbo 的多实例支持&#xff0c;FrameworkModel 是实现类似 JVM 租户级别的隔离&#xff0c;ApplicationModel 是为了实现一个机器上发布多个应用&#xff08;如 demo-application1 和 demo-application2 一起发布&#xff09;&#xff…