SpringBoot 使用WebSocket功能

news2024/11/15 22:55:48

实现步骤:

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的转发规则。

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

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

相关文章

查看 npm的一些命令,以及npm config set registry x x x 不生效 解决方案

在 Mac 上查看自己的 npm 源&#xff0c;可以使用以下命令&#xff1a; 打开终端应用程序&#xff08;Terminal&#xff09;。 运行以下命令来查看当前的 npm 配置&#xff1a; npm config list这会显示 npm 的配置信息&#xff0c;包括当前使用的源&#xff08;registry&am…

FCIS 2023:洞悉网络安全新前沿,引领未来安全创新狂潮

在数字化浪潮席卷全球的今天&#xff0c;网络安全问题愈发凸显其重要性。 FCIS 2023网络安全创新大会作为业界瞩目的盛会&#xff0c;不仅汇聚了国际顶尖的网络安全专家&#xff0c;更展示了最前沿的安全技术与研究成果。那么&#xff0c;参与这场大会&#xff0c;我们究竟能学…

MySQL-DQL(Data Query Language)数据查询语言

文章目录 1. DQL定义2. 基础查询3. 条件查询&#xff08;WHERE&#xff09;4. 分组查询&#xff08;GROUP BY&#xff09;5. 过滤分组&#xff08;HAVING&#xff09;6. 排序&#xff08;ORDER BY&#xff09;7. 限制查询结果的条数&#xff08;LIMIT&#xff09;8. 多表查询8.…

OG Trade在ZKX揭幕:一家基于Starknet的游戏化永续合约交易所

ZKX的 OG Trade通过内置游戏化和30分钟交易竞赛&#xff0c;为所有交易者创造机会&#xff0c;革新了永续合约交易模式。 2024年1月30日 — ZKX宣布推出OG Trade&#xff0c;这是一家基于Starknet的游戏化永续合约交易所&#xff0c;旨在满足短期交易者、高水平交易者和波段交易…

数据可视化工具之选,三选一?

在数据可视化的世界中&#xff0c;选择一款合适的工具对于提升工作效率和洞察力至关重要。本文将对三款主流数据可视化工具进行详细比较&#xff0c;包括山海鲸可视化、Echarts和D3.js&#xff0c;以帮助您做出明智的选择。 山海鲸可视化 山海鲸可视化是一款免费且功能强大的…

全面掌握Django的web框架Django Rest_Framework(一)

文章目录 Django Rest_Framework1. DRF介绍2.DRF特点3.环境安装与配置&#xff08;1&#xff09;DRF需要以下依赖&#xff08;2&#xff09;创建django项目 4.序列化器的使用&#xff08;1&#xff09;创建序列化器 5. 反序列化器使用 Django Rest_Framework 1. DRF介绍 Djan…

phar反序列化漏洞

基础&#xff1a; Phar是一种PHP文件归档格式&#xff0c;它类似于ZIP或JAR文件格式&#xff0c;可以将多个PHP文件打包成一个单独的文件&#xff08;即Phar文件&#xff09;。 打包后的Phar文件可以像普通的PHP文件一样执行&#xff0c;可以包含PHP代码、文本文件、图像等各…

Web中的转发与重定向

转发与重定向 一、转发和重定向的概念1.转发2.重定向 二、JavaWeb 中的转发和重定向三、SpringMVC 中的转发和重定向1.转发(1) 默认的方式(2) 完整的方式 2.重定向 四、总结 一、转发和重定向的概念 在 Web 应用中&#xff0c;转发和重定向都是用于将请求从一个页面传递到另一…

asp.net吃了么销售系统

asp.net吃了么销售系统 用户功能有首页购买商品 购物车 我的订单 后台管理员可以进行用户管理 菜品管理 订单管理 销售统计 asp.net吃了么销售系统是一个功能完善的在线购物平台&#xff0c;用户可以在首页浏览并购买各类商品。通过购物车功能&#xff0c;用户可以方便地管理…

ElasticSearch 应用实践 笔记

概述 介绍 ES 是一个开源的高扩展的分布式全文搜索引擎&#xff0c;是整个Elastic Stack技术栈的核心。它可以近乎实时的存储&#xff0c;检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数据。ElasticSearch的底层是开源库Lu…

什么样的评论更容易得到别人的关注

要发表吸引人的评论&#xff0c;可以注意这些个方面&#xff1a; 合适的软件&#xff1a;用DT浏览器的笔记本写文本&#xff0c;保存为图片&#xff0c;用图片的方式评论更容易得到别人的关注。 特别的观点&#xff1a;发表与众不同的观点&#xff0c;或者从不同的角度看待问…

上岸国考有多难?

国考笔试成绩已于2024年1月13日公布&#xff0c;听说宇宙的尽头是编制&#xff0c;今天用一份2024国考的数据帮大家探探路。数据来自和鲸平台&#xff0c;数据主要包括招考省市和部门、专业和学历要求、招考和报考人数。 经过一番探索&#xff0c;我发现一个上岸密码&#xff1…

成功解决AttributeError: ‘str‘ object has no attribute ‘keys‘

成功解决AttributeError: ‘str’ object has no attribute ‘keys’。 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;报错分析及解决方案&#x1f333;&#x1f333;字典对象的keys方法&#x1f333;&#x1f333;结尾&#x1f333; &…

01、全文检索 ------ 反向索引库 与 Lucene 的介绍

目录 全文检索 ------ 反向索引库 与 LuceneSQL模糊查询的问题反向索引库反向索引库的查询 Lucene&#xff08;全文检索技术&#xff09;Lucene能做什么Lucene存在的问题Solr 和 Elasticsearch 与 Lucene 的关系 全文检索 ------ 反向索引库 与 Lucene MySQL一些索引词汇解释 …

MIMIC-IV-ED数据集介绍

MIMIC-IV-ED v2.2 Abstract MIMIC-IV-ED 是一个大型的免费数据库&#xff0c;记录了2011年至2019年间急诊部门(ED)贝斯以色列女执事医疗中心的入院情况。该数据库包含约425,000个 ED 停留。生命体征&#xff0c;分类信息&#xff0c;药物协调&#xff0c;药物管理和出院诊断是…

android 自定义下拉框

一、 简介&#xff1a; 原生Android 提供的spinner下拉框不怎么方便&#xff0c;样式有点丑。修改起来麻烦&#xff0c;于是就自己动手写了一下拉列表。 实现原理使用的是&#xff0c;popwindow弹框&#xff0c;可实现宽高自定义&#xff0c;下拉列表使用listview. 二、pop弹框…

python爬虫2

1.table 是表格&#xff0c;tr是行&#xff0c;td是列 ul li是无序列标签用的较多&#xff0c;ol li是有序列标签 最基本的结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title> Title </title>…

《区块链简易速速上手小册》第6章:区块链在金融服务领域的应用(2024 最新版)

文章目录 6.1 金融服务中的区块链6.1.1 金融服务中区块链的基础6.1.2 主要案例&#xff1a;跨境支付6.1.3 拓展案例 1&#xff1a;去中心化金融&#xff08;DeFi&#xff09;6.1.4 拓展案例 2&#xff1a;代币化资产 6.2 区块链在支付系统中的作用6.2.1 支付系统中区块链的基础…

2024-02-01 Unity Shader 开发入门4 —— ShaderLab 语法

文章目录 1 材质和 Shader1.1 Unity Shader 和 Shader 的区别1.2 Unity 中的材质和 Shader1.3 创建材质1.4 创建 Shader 2 ShaderLab 的基本结构2.1 什么是 ShaderLab2.2 ShaderLab 的基本结构 3 Shader 名称4 Shader 属性4.1 Shader 属性的作用4.2 Shader 属性的基本语法4.3 数…

飞桨paddlespeech语音唤醒推理C INT8 定点实现

前面的文章&#xff08;飞桨paddlespeech语音唤醒推理C定点实现&#xff09;讲了INT16的定点实现。因为目前商用的语音唤醒方案推理几乎都是INT8的定点实现&#xff0c;于是我又做了INT8的定点实现。 实现前做了一番调研。量化主要包括权重值量化和激活值量化。权重值由于较小且…