spring boot(学习笔记第十五课)

news2024/9/9 5:36:45

spring boot(学习笔记第十五课)

  • Spring boot的websocket(广播)

学习内容:

  • Spring boot的websocket(广播)

1. Spring boot的websocket(广播)

  1. 回顾下web server的进化
    在这里插入图片描述
      1. 第一代Web程序,使用整体页面刷新技术,对整个页面进行刷新。
        缺点:明明不需要的页面部分,也要全部刷新,对于网络带宽占用较大,而且效率很低。
      1. 第二代Web程序,使用ajax刷新技术,对页面进行局部刷新。
        优点:仅仅需要刷新页面的部分,向服务器发出请求,并将应答数据进行web页面局部刷新。
        缺点:只能浏览器主动pullweb server。不能实时realtime检测到web server的数据变化。
      1. 第二代Web程序,使用ajax刷新技术,对web server进行长轮训long polling
      1. 第三代Web程序,使用web socket刷新技术,让web clientweb server进行实时数据交互。在这里插入图片描述
  2. 开始练习spring boot上的web socket
    • spring boot添加必要的依赖(服务器端配置)
       <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-websocket</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.webjars</groupId>
                  <artifactId>webjars-locator-core</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.webjars</groupId>
                  <artifactId>sockjs-client</artifactId>
                  <version>1.1.2</version>
              </dependency>
              <dependency>
                  <groupId>org.webjars</groupId>
                  <artifactId>stomp-websocket</artifactId>
                  <version>2.3.3</version>
              </dependency>
              <dependency>
                  <groupId>org.webjars</groupId>
                  <artifactId>jquery</artifactId>
                  <version>3.3.1</version>
              </dependency>
      
    • 进行endPointmessageBroker以及destinationPrefixes初始化配置(服务器端配置)
      @Configuration
      @EnableWebSocketMessageBroker
      public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
          @Override
          public void configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry) {
              messageBrokerRegistry.enableSimpleBroker("/topic");
              messageBrokerRegistry.setApplicationDestinationPrefixes("/app");
          }
          @Override
          public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry){
              stompEndpointRegistry.addEndpoint("/chat").withSockJS();
          }
      }
      
      • addEndPoint
        web socketserverclient交互的端点。
      • setApplicationDestinationPrefixes
        web socket clientweb server发起请求的url
      • enableSimpleBroker
        web serverweb socket client发起请求的messageBroker
    • 配置controller(服务器端配置)
      @Controller
      public class WebSocketController {
          @MessageMapping("hello")
          @SendTo("/topic/greetings")
          public Message greeting(Message message) throws Exception {
              return message;
          }
      
      • Message message是从web socket client传递来的参数
      • @SendTo("/topic/greetings")是利用topic这个messageBroker讲消息在转发到web socket client
    • 配置客户端静态页面/static/chat.html
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>聊天</title>
          <script src="/webjars/jquery/jquery.min.js"></script>
          <script src="/webjars/sockjs-client/sockjs.min.js"></script>
          <script src="/webjars/stomp-websocket/stomp.min.js"></script>
          <script src="/app.js"></script>
      </head>
      <body>
      <div>
          <label for="name">请输入用户名:</label>
          <input type="text" id="name" placeholder="用户名">
      </div>
      <div>
          <button id="connect" type="button">连接</button>
          <button id="disconnect" type="button" disabled="disabled">断开</button>
      </div>
      <div id="chat" style="display:none;">
          <div>
              <label for="content">请输入聊天内容:</label>
              <input type="text" id="content" placeholder="聊天内容">
          </div>
          <button id="send" type="button">发送</button>
          <div id="greetings">
              <div id="conversation" style="display:none">群聊进行中</div>
          </div>
      </div>
      </body>
      </html>
      
      在这里插入图片描述
    • 配置客户端的javascript /static/app.js
      • web socket的连接处理

        function connect(){
            if(!$("#name").val()){
                return;
            }
            var socket = new SockJS('/chat'); //连接endPoint
            stompClient = Stomp.over(socket);
            stompClient.connect({},function (frame){
                setConnected(true); //渲染控件
                stompClient.subscribe('/topic/greetings',function(greeting){ //注册web server报文接收的callback
                    showGreeting(JSON.parse(greeting.body));
                });
            });
        }
        
      • 点击发送的处理函数

        function sendName(){
            stompClient.send("/app/hello",{},
            JSON.stringify({'name':$("#name").val(),'content':$("#content").val()}));
        }
        
      • 页面的初始化函数

        $(function(){
            $("#connect").click(function(){connect();});
            $("#discontent").click(function(){disconnect()});
            $("#send").click(function(){sendName()});
        });
        
      • /static/app.js的全体

        var stompClient = null;
        function setConnected(connected){
            $("#connect").prop("disabled",connected);
            $("#disconnect").prop("disabled",!connected);
            if(connected){
                $("#conversation").show();
                $("#chat").show();
            }else{
                $("#conversation").hide();
                $("#chat").hide();
            }
            $("#greetings").html("");
        }
        function connect(){
            if(!$("#name").val()){
                return;
            }
            var socket = new SockJS('/chat');
            stompClient = Stomp.over(socket);
            stompClient.connect({},function (frame){
                setConnected(true);
                stompClient.subscribe('/topic/greetings',function(greeting){
                    showGreeting(JSON.parse(greeting.body));
                });
            });
        }
        function disconnect(){
            if(stompClient != null){
                stompClient.disconnect();
            }
            setConnected(false);
        }
        function sendName(){
            stompClient.send("/app/hello",{},
            JSON.stringify({'name':$("#name").val(),'content':$("#content").val()}));
        }
        function showGreeting(message){
            $("#greetings").append("<div>" + message.name +
            ":" + message.content + "</div>");
        }
        $(function(){
            $("#connect").click(function(){connect();});
            $("#discontent").click(function(){disconnect()});
            $("#send").click(function(){sendName()});
        });
        
  3. 测试spring boot上的web socket
    在两个浏览器上测试,输入名字,连接之后开始聊天。
    在这里插入图片描述

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

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

相关文章

GPT-4o mini- 开发者的新宠儿

在人工智能的浪潮中,一颗新星正在冉冉升起。OpenAI最新发布的GPT-4o mini模型以其惊人的性能和极具竞争力的价格,正在成为开发者们的新宠儿。作为一名大数据开发者,我深深被这个"迄今为止最具成本效益的小模型"所吸引。让我们一起探索GPT-4o mini的魅力,看看它如何改…

一些问题 7/28

get post可以public吗 在Java Servlet中&#xff0c;doGet()和doPost()方法的访问修饰符通常是public&#xff0c;因为这些方法需要被Servlet容器&#xff08;如Tomcat&#xff09;调用。 如果将这些方法声明为private或protected&#xff0c;Servlet容器将无法访问它们&…

RocketMQ Server Windows安装

RocketMQ阿里开发 开源给apache 官网:RocketMQ 官方网站 | RocketMQ 下载后解压 配置环境变量 注意启动顺序 双击 注意 4.9.0这个版本必须 jdk 8 高了用不了 namesrv是注册中心的作用 broke是核心用于接收生产者消息 存储消息 发送给消费者消息 类似DubboZookeeper…

C++ 绘制画布标尺

目标 关键代码 CRulerDrawer::CRulerDrawer(QPainter& painter, QRect rect, int scalePercent): m_painter(painter), m_rect(rect), m_scalePercent(scalePercent) {m_palette qApp->palette();m_scaleUnitSize PixelRuler::Instance()->GetScaleUnitSize(); }vo…

【JS|第22期】深入理解跨域

日期&#xff1a;2024年7月6日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

Vue开发环境搭建

文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II VUE项目的基础配置2.1 制定不同的环境配置2.2 正式环境隐藏日志2.3 vscode常用插件引言 开发工具: node.js 、npm 开发编辑器:vscode 开发框架:VUE I 安装NVM…

react中zuStand状态管理工具使用

一、zuStand的基本使用 1.安装工具 npm install zustand 2.新建文件 在src下新建store文件夹&#xff0c;在store文件夹下新建zuStand.js文件 3.配置zuStand.js // 1.引入创建方法 import { create } from "zustand";// 2.创建store const useStore create((s…

未来不会使用 AI 的人真的会被淘汰吗?

AI 是今年大火的一个话题&#xff0c;随着 ChatGPT 之类的一系列大模型开始流行以后&#xff0c;有不少的培训机构宣称这样的口号: “未来不会使用 AI 的人将会被淘汰”。我觉得这个观点本身并没有错&#xff0c;但是关键在于那些培训机构出于自身的利益&#xff0c;故意忽略了…

(源码分析)springsecurity认证授权

了解 1. 结构总览 SpringSecurity所解决的问题就是安全访问控制&#xff0c;而安全访问控制功能其实就是对所有进入系统的请求进行拦截&#xff0c;校验每个请求是否能够访问它所期望的资源。 根据前边知识的学习&#xff0c;可以通过Filter或AoP等技术来实现&#xff0c;Spr…

Sparse Vector Coding稀疏矢量码介绍

需要MATLAB代码的小伙伴请通过微信公众号私信我~ 更多精彩内容请关注微信公众号 ‘优化与算法’ 前言 5G和6G无线通信期望带来更高的频谱效率和能量效率&#xff0c;为了达到这些目标&#xff0c;近年来已经提出了各种新技术。其中&#xff0c;索引调制IM&#xff08;Index …

「树形结构」基于 Antd 实现一个动态增加子节点+可拖拽的树

效果 如图所示 实现 import { createRoot } from react-dom/client; import React, { useState } from react; import { Tree, Input, Button } from antd; import { PlusOutlined } from ant-design/icons;const { TreeNode } Tree; const { Search } Input;const ini…

优选算法之位运算

目录 一、常见位运算总结 1.基础位运算 2.给定一个数 n&#xff0c;确定它的二进制表示中的第 x 位是 0 还是 1 3.将一个数 n 的二进制表示的第 x 位修改成1 4.将一个数 n 的二进制表示的第 x 位修改成 0 5.提取一个数 n 二进制表示中最右侧的1 6.干掉一个数 n 二进制表示…

分布式存储系统架构及应用

分布式存储系统概述&#xff08;详细、全面&#xff09; 【摘要】深度剖析分布式存储系统的可靠性、可用性、IO性能、数据存储效率、安全性及管理性&#xff0c;为寻求了解此领域的读者提供实用参考。 一、 内容总括 分布式存储系统&#xff0c;依托网络互联的多节点软硬件协同…

人脸识别又进化:扫一下 我就知道你得了啥病

未来&#xff0c;扫下你的脸&#xff0c;可能就知道你得啥病了。没在瞎掰&#xff0c;最近的一项研究成果&#xff0c;还真让咱看到了一点眉目。北大的一个研究团队&#xff0c;搞出来一个 AI &#xff0c;说是用热成像仪扫一下脸&#xff0c;就能检测出有没有高血压、糖尿病和…

工作纪实54-git使用ssh方式

很多居家的小伙伴要重新clone项目&#xff0c;但是忘记了密码&#xff0c;最恶心的是idea还会自动帮你记录密码&#xff0c;如果输错了&#xff0c;会很恶心&#xff0c;使用ssh则不会&#xff1b;还有一个好处就是&#xff0c;集团的密码一般都是几个月更新一次&#xff0c;ss…

基于Frp搭建Window-Linux内网穿透完整流程

什么是内网穿透? 内网穿透是我们在进行网络连接时的一种术语&#xff0c;也叫做NAT穿透&#xff0c;即在计算机是局域网内的时候&#xff0c;外网与内网的计算机的节点进行连接时所需要的连接通信&#xff0c;有时候就会出现内网穿透不支的情况。内网穿透的功能就是&#xff0…

只出现一次的数字-位运算

题目描述&#xff1a; 个人题解&#xff1a; 代码实现&#xff1a; class Solution { public:int singleNumber(vector<int>& nums) {int ret 0;for (auto e: nums) ret ^ e;return ret;} };复杂度分析&#xff1a; 时间复杂度&#xff1a;O(n)&#xff0c;其中 n…

19018 正则序列

这个问题可以通过排序和计数来解决。首先&#xff0c;我们将数组排序&#xff0c;然后我们遍历排序后的数组&#xff0c;对于每个元素&#xff0c;我们将它变为它应该在正则序列中的值&#xff0c;也就是它的索引加1。我们将这个变化的绝对值累加起来&#xff0c;这就是我们需要…

STM32智能农业灌溉系统教程

目录 引言环境准备智能农业灌溉系统基础代码实现&#xff1a;实现智能农业灌溉系统 4.1 数据采集模块 4.2 数据处理与分析模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;农业监测与优化问题解决方案与优化收尾与总结 1. 引言 智能农业灌溉系统通…

Sklearn实例:水果多分类

机器学习五步&#xff1a; 加载数据集分割数据集建立模型训练模型预测模型 导入库文件 import numpy as np #科学计算库 import matplotlib.pyplot as plt #绘图库可视化函数 import pandas as pd #数据处理库&#xff0c;数据分析库 import seaborn as sns #高级数据可视化…