当前位置: 首页 > news >正文

在 Spring Boot 中实现 WebSockets

什么是 WebSockets?

WebSockets 是一种基于 TCP 的全双工通信协议,允许客户端和服务器之间建立持久的双向连接,用于实时数据交换。相较于传统的 HTTP 请求-响应模型,WebSockets 提供了低延迟、高效率的通信方式,特别适合需要实时更新的应用场景,如聊天应用、实时通知、在线游戏和股票价格更新。

核心特点
  1. 全双工通信:客户端和服务器可同时发送和接收数据。
  2. 持久连接:一次握手后,连接保持开放,减少重复建立连接的开销。
  3. 低延迟:适合实时性要求高的场景。
  4. 轻量协议:基于 HTTP 协议升级(通过 Upgrade 头),数据帧开销小。
  5. 跨平台支持:现代浏览器和服务器均支持 WebSockets。
工作原理
  1. 握手:客户端通过 HTTP 发送 WebSocket 握手请求(GET /ws HTTP/1.1Upgrade: websocket 头),服务器响应 101 Switching Protocols
  2. 连接建立:双方建立 WebSocket 连接,使用 ws://wss://(加密)协议。
  3. 数据交换:通过文本或二进制帧传输数据,连接保持开放直到一方关闭。
  4. 关闭:发送关闭帧,断开连接。
与 HTTP 和 AJAX 的对比
  • HTTP:单向、请求-响应模式,适合静态内容。
  • AJAX:通过轮询模拟实时性,增加服务器负载。
  • WebSockets:持久连接,低延迟,适合动态交互。
应用场景
  • 实时聊天(如 WhatsApp)。
  • 实时通知(如新消息提醒)。
  • 在线协作工具(如 Google Docs)。
  • 金融数据流(如股票价格)。
  • 多人游戏。
挑战
  • 资源消耗:持久连接占用服务器资源。
  • 复杂性:需要处理连接断开、重连等。
  • 安全性:需防止未授权访问(参考你的 Spring Security 查询)。
  • 集成:需与分页、Swagger、ActiveMQ、Spring Profiles、Spring Batch、FreeMarker、热加载、ThreadLocal、Actuator 安全性、CSRF、异常处理等协调。

Spring Boot 通过 Spring WebSocket 和 STOMP(Simple Text Oriented Messaging Protocol)简化 WebSocket 实现。以下是在 Spring Boot 中实现 WebSockets 的步骤,结合你的先前查询(分页、Swagger、ActiveMQ、Spring Profiles、Spring Security、Spring Batch、FreeMarker、热加载、ThreadLocal、Actuator 安全性、CSRF、异常处理)。

1. 环境搭建
  1. 添加依赖pom.xml):

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>
    <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.2.0</version>
    </dependency>
    
  2. 配置 application.yml

    spring:profiles:active: devfreemarker:template-loader-path: classpath:/templates/suffix: .ftlcache: falseactivemq:broker-url: tcp://localhost:61616user: adminpassword: admin
    server:port: 8081
    springdoc:api-docs:path: /api-docsswagger-ui:path: /swagger-ui.html
    
2. 实现 WebSocket 聊天应用

以下是一个简单的实时聊天应用示例,使用 STOMP over WebSocket。

  1. WebSocket 配置

    package com.example.demo.config;import org.springframework.context.annotation.Configuration;
    import org.springframework.messaging.simp.config.MessageBrokerRegistry;
    import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
    import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
    import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;@Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/topic"); // 广播消息config.setApplicationDestinationPrefixes("/app"); // 客户端发送消息前缀}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/chat").withSockJS(); // WebSocket 端点,兼容 SockJS}
    }
    
  2. 消息控制器

    package com.example.demo.controller;import org.springframework.messaging.handler.annotation.MessageMapping;
    import org.springframework.messaging.handler.annotation.SendTo;
    import org.springframework.stereotype.Controller;@Controller
    public class ChatController {@MessageMapping("/sendMessage")@SendTo("/topic/messages")public ChatMessage sendMessage(ChatMessage message) {return message; // 广播消息}
    }
    
  3. 消息实体

    package com.example.demo.controller;public class ChatMessage {private String content;private String sender;// Getters and Setterspublic String getContent() { return content; }public void setContent(String content) { this.content = content; }public String getSender() { return sender; }public void setSender(String sender) { this.sender = sender; }
    }
    
  4. FreeMarker 聊天页面src/main/resources/templates/chat.ftl):

    <!DOCTYPE html>
    <html>
    <head><title>实时聊天</title><script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.6.1/sockjs.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script><script>var stompClient = null;function connect() {var socket = new SockJS('/chat');stompClient = Stomp.over(socket);stompClient.connect({}, function(frame) {stompClient.subscribe('/topic/messages', function(message) {var msg = JSON.parse(message.body);document.getElementById('messages').innerHTML += '<p>' + msg.sender + ': ' + msg.content + '</p>';});});}function sendMessage() {var content = document.getElementById('content').value;var sender = document.getElementById('sender').value;stompClient.send('/app/sendMessage', {}, JSON.stringify({'content': content,'sender': sender}));document.getElementById('content').value = '';}window.onload = connect;</script>
    </head>
    <body><h1>实时聊天</h1><div><label>用户名: <input id="sender" type="text" value="User"/></label><label>消息: <input id="content" type="text"/></label><button onclick="sendMessage()">发送</button></div><div id="messages"></div>
    </body>
    </html>
    
  5. 控制器

    package com.example.demo.controller;import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;@Controller
    public class WebSocketController {@GetMapping("/chat")public String chat() {return "chat";}
    }
    
  6. 运行验证

    • 启动应用:mvn spring-boot:run
    • 访问 http://localhost:8081/chat,打开多个浏览器窗口。
    • 输入用户名和消息,发送后所有窗口实时显示消息。
3. 与先前查询集成

结合你的查询(分页、Swagger、ActiveMQ、Spring Profiles、Spring Security、Spring Batch、FreeMarker、热加载、ThreadLocal、Actuator 安全性、CSRF、异常处理):

  1. 分页与排序

    • 实时显示分页用户数据:
      @MessageMapping("/fetchUsers")
      @SendTo("/topic/users")
      public Page<User> fetchUsers(@Payload UserFilter filter) {return userService.searchUsers(filter.getName(), filter.getPage(), filter.getSize(), "id", "asc");
      }
      
      public class UserFilter {private String name;private int page;private int size;// Getters and Setters
      }
      
  2. Swagger

    • 文档化 REST API,非 WebSocket:
      @Operation(summary = "获取用户列表")
      @GetMapping("/api/users")
      public Page<User> getUsers(@RequestParam String name, @RequestParam int page, @RequestParam int size) {return userService.searchUsers(name, page, size, "id", "asc");
      }
      
  3. ActiveMQ

    • 记录聊天消息:
      @Controller
      public class ChatController {@Autowiredprivate JmsTemplate jmsTemplate;@MessageMapping("/sendMessage")@SendTo("/topic/messages")public ChatMessage sendMessage(ChatMessage message) {jmsTemplate.convertAndSend("chat-log", message.getSender() + ": " + message.getContent());return message;}
      }
      
  4. Spring Profiles

    • 配置开发/生产环境:
      # application-dev.yml
      spring:freemarker:cache: false
      logging:level:root: DEBUG
      
      # application-prod.yml
      spring:freemarker:cache: true
      
  5. Spring Security

    • 保护 WebSocket 连接:
      @Configuration
      public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(auth -> auth.requestMatchers("/chat").authenticated().anyRequest().permitAll()).formLogin().and().csrf().ignoringRequestMatchers("/chat"); // WebSocket 端点禁用 CSRFreturn http.build();}
      }
      
  6. Spring Batch

    • 批量推送用户数据:
      @Component
      public class BatchConfig {@Beanpublic Step pushUsers(@Autowired SimpMessagingTemplate messagingTemplate) {return stepBuilderFactory.get("pushUsers").<User, User>chunk(10).reader(reader()).processor(user -> {messagingTemplate.convertAndSend("/topic/users", user);return user;}).writer(writer()).build();}
      }
      
  7. FreeMarker

    • 已使用 FreeMarker 渲染聊天页面。
  8. 热加载

    • 启用 DevTools:
      spring:devtools:restart:enabled: true
      
  9. ThreadLocal

    • 清理 WebSocket 上下文:
      @Service
      public class UserService {private static final ThreadLocal<String> CONTEXT = new ThreadLocal<>();public Page<User> searchUsers(...) {try {CONTEXT.set("WS-" + Thread.currentThread().getName());// 逻辑} finally {CONTEXT.remove();}}
      }
      
  10. Actuator 安全性

    • 保护 /actuator/**,允许 /actuator/health
  11. CSRF

    • WebSocket 端点禁用 CSRF(见 SecurityConfig)。
  12. 异常处理

    • 处理 WebSocket 异常:
      @ControllerAdvice
      public class WebSocketExceptionHandler {@ExceptionHandler(MessagingException.class)public void handleMessagingException(MessagingException ex, SimpMessageHeaderAccessor headerAccessor) {headerAccessor.getSessionAttributes().put("error", ex.getMessage());}
      }
      
4. 运行验证
  • 开发环境

    java -jar demo.jar --spring.profiles.active=dev
    
    • 访问 http://localhost:8081/chat,登录后发送消息,验证实时性。
    • 检查 ActiveMQ chat-log 队列。
  • 生产环境

    java -jar demo.jar --spring.profiles.active=prod
    
    • 确认安全性和模板缓存。

原理与性能

原理
  • WebSocket 协议:基于 TCP,使用 HTTP 握手升级。
  • STOMP:在 WebSocket 上添加消息路由,支持订阅/发布。
  • Spring WebSocket:管理连接、消息路由和广播。
性能
  • 连接建立:50ms(单用户)。
  • 消息传输:1-2ms/消息。
  • 并发:1000 用户,延迟 <10ms(8 核 CPU,16GB 内存)。
测试
@Test
public void testWebSocketPerformance() {WebSocketClient client = new StandardWebSocketClient();client.doHandshake(new TextWebSocketHandler(), "ws://localhost:8081/chat");// 测试消息发送
}

常见问题

  1. 连接失败

    • 问题:WebSocket 握手失败。
    • 解决:检查端点路径,禁用防火墙。
  2. 消息丢失

    • 问题:客户端未收到消息。
    • 解决:确认订阅 /topic/messages
  3. ThreadLocal 泄漏

    • 问题:/actuator/threaddump 显示泄漏。
    • 解决:清理 ThreadLocal。

总结

WebSockets 提供实时双向通信,Spring Boot 通过 STOMP 简化实现。示例展示了聊天应用及与分页、Swagger、ActiveMQ 等集成。针对你的查询(ThreadLocal、Actuator、热加载、CSRF),通过清理、Security 和 DevTools 解决。

相关文章:

在 Spring Boot 中实现 WebSockets

什么是 WebSockets&#xff1f; WebSockets 是一种基于 TCP 的全双工通信协议&#xff0c;允许客户端和服务器之间建立持久的双向连接&#xff0c;用于实时数据交换。相较于传统的 HTTP 请求-响应模型&#xff0c;WebSockets 提供了低延迟、高效率的通信方式&#xff0c;特别适…...

stone 3d v3.3.0版本发布,含时间线和连接器等新功能

1.新加了时间线&#xff08;timeline&#xff09;编辑器&#xff0c;可以类似blender一样给对象制作动画 2.新加了度量&#xff08;metrics&#xff09;系统&#xff0c;通过scene对象检测器中的useMetrics属性来启用或禁用&#xff0c;启用时所选物体将显示三维度量数据 新加了…...

Parasoft C++Test软件单元测试_对函数打桩的详细介绍

系列文章目录 Parasoft C++Test软件静态分析:操作指南(编码规范、质量度量)、常见问题及处理 Parasoft C++Test软件单元测试:操作指南、实例讲解、常见问题及处理 Parasoft C++Test软件集成测试:操作指南、实例讲解、常见问题及处理 进阶扩展:自动生成静态分析文档、自动…...

Safety Estimands与Efficacy Estimands的差异剖析

1. 研究目标差异 1.1 安全性估计目标 1.1.1 关注潜在风险 安全性估计目标着重于治疗可能引发的不良事件(AE)、严重不良事件(SAE)或实验室指标异常,如化疗药物导致中性粒细胞减少症的发生率,这些指标直接关联到患者治疗过程中的健康风险。 这些潜在风险的评估对于确保治…...

HTML 详解:从基础结构到语义标签

目录 一、HTML 是什么&#xff1f;二、HTML 的基本结构✅ 简要说明&#xff1a; 三、常见 HTML 标签讲解3.1 标题标签 <h1> ~ <h6>3.2 段落和换行3.3 超链接3.4 图像插入3.5 列表无序列表&#xff1a;有序列表&#xff1a; 3.6 表格结构 四、HTML 语义化标签详解五…...

联合索引`ABC`,使用`B=... AND C=... AND A=...`会走索引吗?

在MySQL中&#xff0c;联合索引ABC的查询使用B... AND C... AND A...时&#xff0c;是否使用索引取决于查询条件的顺序和优化器的处理。 一、索引使用原理 最左前缀原则 联合索引的底层存储和查询优化遵循最左前缀匹配原则&#xff0c;即查询条件必须从索引的最左侧列开始连续匹…...

HTML 模板技术与服务端渲染

HTML 模板技术与服务端渲染 引言 在现代前端开发生态中&#xff0c;HTML模板技术与服务端渲染(SSR)构成了连接前后端的重要桥梁。当单页应用(SPA)因其客户端渲染特性而面临首屏加载速度慢、白屏时间长和SEO不友好等问题时&#xff0c;服务端渲染技术提供了一种优雅的解决方案…...

MySQL的MVCC【学习笔记】

MVCC 事务的隔离级别分为四种&#xff0c;其中Read Committed和Repeatable Read隔离级别&#xff0c;部分实现就是通过MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09; 版本链 版本链是通过undo日志实现的&#xff0c; 事务每次修改…...

linux安装单节点Elasticsearch(es),安装可视化工具kibana

真的&#xff0c;我安装个es和kibana&#xff0c;找了好多帖子&#xff0c;问了好几遍ai才安装成功&#xff0c;在这里记录一下&#xff0c;我相信&#xff0c;跟着我的步骤走&#xff0c;99%会成功&#xff1b; 为了让大家直观的看到安装过程&#xff0c;我把我服务器的es和ki…...

(Go Gin)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收

1. 路由 gin 框架中采用的路优酷是基于httprouter做的 HttpRouter 是一个高性能的 HTTP 请求路由器&#xff0c;适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用&#xff0c;特别适合需要高性能和简单路由的应用场景。 主要特点 显式匹配&#xff1a;与其他路由…...

纯HTMLCSS静态网站——元神

《原神》主题网页介绍 以对该网页的详细介绍 网页整体结构 头部&#xff08;header&#xff09;&#xff1a;包含网站的 logo 和导航栏。logo 部分展示了 “原神” 字样&#xff0c;点击可返回首页。导航栏提供了多个页面链接&#xff0c;包括首页、音乐、视频、壁纸、世界、…...

嵌入式开发:基础知识介绍

一、嵌入式系统 1、介绍 以提高对象体系智能性、控制力和人机交互能力为目的&#xff0c;通过相互作用和内在指标评价的&#xff0c;嵌入到对象体系中的专用计算机系统。 2、分类 按其形态的差异&#xff0c;一般可将嵌入式系统分为&#xff1a;芯片级&#xff08;MCU、SoC&am…...

华为VRP系统简介配置TELNET远程登录!

1.华为 VRP 系统概述 1.1 什么是 VRP VRP&#xff08;Versatile Routing Platform 华为数通设备操作系统&#xff09;是华为公司数据通信产品的通用操作系统平台&#xff0c;从低端到核心的全系列路由器、以太网交换机、业务网关等产品的软件核心引擎。 1.2 VRP 的功能 统一…...

【高频考点精讲】CSS accent-color属性:如何快速自定义表单控件的颜色?

用CSS accent-color属性3分钟搞定表单控件换肤,原来这么简单! 前几天有个学员问我,checkbox和radio这些表单控件默认样式太丑了,有没有什么办法能快速改颜色?" 我一看这问题就乐了——这不正是CSS accent-color属性的拿手好戏吗?今天咱们就来好好聊聊这个被低估的C…...

【Git】连接github时的疑难杂症(DNS解析失败)

大家好&#xff0c;我是jstart千语。最近在将项目推送到github的时候&#xff0c;突然github就拒绝访问了&#xff0c;即使挂了VPN&#xff0c;网页也进不去&#xff0c;通过git也不能把代码推送上去。 即使后面看别人的一些解决方案&#xff0c;比如取消代理啊、更换ssh的方式…...

成熟的前端vue vite websocket,Django后端实现方案包含主动断开websocket连接的实现

可参考实现方式点击进入查看 具体实现方案如下所示&#xff1a; import { useWebsocketMsessageStore } from /stores/websocketMsessageStore.js import {ElMessage} from "element-plus"; import {useUserStore} from "/stores/userStore.js"; // impo…...

广州 3D 展厅开启企业展示新时代​

为了突破传统展厅的局限&#xff0c;满足企业日益增长的展示需求&#xff0c;3D 展厅应运而生。3D 展厅是利用虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff09;和三维建模等先进技术&#xff0c;构建出的一个高度逼真的数字化展示空间 。它打破了传统展…...

【Django】新增字段后兼容旧接口 This field is required

背景 我在Django模型里新增了两个字段后&#xff0c;旧的接口由于没有同时新增这两个字段的处理&#xff0c;因此旧的接口就报&#xff1a; This field is required 解决 把序列化时的 required 的字段设置为False即可 class ServiceSerializer(DynamicFieldsModelSerializ…...

基于AIGC的3D场景生成实战:从文本描述到虚拟世界构建

一、3D AIGC技术解析 1.1 技术挑战与突破 挑战维度 传统方案局限 AIGC创新方案 建模效率 人工建模耗时数天 文本到3D秒级生成 细节丰富度 重复使用素材库 无限风格化生成 物理合理性 手动调整物理参数 自动符合物理规律 多平台适配 需手动优化模型 自适应LOD生成 1.2 主流技术路…...

手写Java线程池与定时器:彻底掌握多线程任务调度

​ 目录 一、线程池 1.1、什么是线程池 1.2、Java标准库中的线程池 1.3、ThreadPoolExecutor的七大参数 1.4、模拟实现线程池 1.4.1、submit () 1.4.2、构造方法 1.4.3、运行结果 二、定时器​ 2.1、标准库中的定时器 2.2、模拟实现定时器 2.2.1、MyTimerTask类 2…...

【科研绘图系列】R语言绘制区间点图(dot plot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理画图1画图2输出图片系统信息介绍 【科研绘图系列】R语言绘制区间点图(dot plot) 加载R包 library(tidyverse) library(ggtext) library(r…...

【Agent实战】从0到1开发一个Python 解释器 MCP SSE Server

写在前面 想象一个场景:LLM Agent(如 AutoGPT、MetaGPT 或我们自己构建的 Agent)在规划任务后,决定需要运行一段 Python 代码来处理数据或调用某个 API。它不能直接在自己的环境中执行(通常不具备这个能力,也不安全),而是需要将这段代码发送给一个专门的外部服务来执行…...

C语言大写转小写2.0

一、阐述关系 上一次的题目是大写转小写,这一次代码不一样,运行的结果也不一样,这次的代码在此基础之上改动了一下,虽然看起来相似,但实际上运行结果不一样 二、题目展示 下面代码中,运行的结果是多少? 三、分析过程 首先,进入main函数,先声明了一个字符型数组是"012…...

pnpm常见报错解决办法

PS D:\code\gitlab\manus-web> pnpm add -D types/framer-motion --save-exact --config.strict-peer-depsfalse Debugger attached.  WARN  deprecated eslint8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other op…...

【Linux网络】:套接字之UDP

一、UDP和TCP协议 TCP &#xff08;Transmission Control Protocol 传输控制协议&#xff09;的特点&#xff1a; 传输层协议有连接&#xff08;在正式通信前要先建立连接&#xff09;可靠传输&#xff08;在内部帮我们做可靠传输工作&#xff09;面向字节流 UDP &#xff08;U…...

量子威胁下的安全革命:后量子密码学技术路线与迁移挑战全解析

引言 量子计算技术的快速发展正在重塑现代密码学的安全版图。随着Shor算法对传统公钥密码体系的根本性威胁[1]&#xff0c;全球范围内后量子密码学&#xff08;Post-Quantum Cryptography, PQC&#xff09;的研究与标准化进程已进入关键阶段。 本文基于权威文献分析&#xff0c…...

多模态大语言模型(MLLM)- kimi-vl technical report论文阅读

前言 kimi-vl是月之暗面团队于2025年4月10日发布的多模态大模型。 代码链接&#xff1a;https://github.com/MoonshotAI/Kimi-VL 背景 随着人工智能技术的快速发展&#xff0c;人们对AI助手的需求已从单一文本交互转向多模态理解。新一代多模态模型如GPT-4o和Gemini虽展现…...

ai聊天流式响应,阻塞式和流式响应 nginx遇到的坑

问题 现在做ai的流式请求&#xff0c;在开发环境使用代理访问接口&#xff0c;显示是正常的。上到正式环境&#xff0c;代理通过nginx配置可以访问到流式接口。在本地测试postman请求流式接口&#xff0c;返回的东西是流式返回&#xff0c; 在正式环境里面使用postman请求流式…...

Linux安全模块:SELinux与AppArmor深度解析

引言 在Linux安全领域&#xff0c;SELinux和AppArmor就像两位忠诚的"系统保镖"&#x1f482;&#xff0c;为你的服务器提供强制访问控制(MAC)保护&#xff01;本文将深入解析这两大安全模块的工作原理、配置方法和实战技巧。无论你是要加固Web服务器&#xff0c;还是…...

FlinkJobmanager深度解析

1. JobManager 概述 Flink 是一个分布式流处理框架&#xff0c;其核心组件包括 JobManager、TaskManager 和客户端&#xff08;如 CLI 或 Web UI&#xff09;。JobManager 是 Flink 集群的“大脑”&#xff0c;负责协调作业的整个生命周期&#xff0c;包括作业调度、资源管理、…...

FlinkSql入门与实践

一、为什么需要 Flink SQL&#xff1f; 传统 SQL 是面向静态数据的查询语言&#xff0c;而现代实时业务要求对动态数据流进行即时分析。Flink SQL 应运而生&#xff0c;它让开发者无需编写复杂的状态管理代码&#xff0c;就能实现实时ETL、复杂事件处理&#xff08;CEP&#x…...

【物联网】基于LORA组网的远程环境监测系统设计(ThingsCloud云平台版)

演示视频: 基于LORA组网的远程环境监测系统设计(ThingsCloud云平台版) 前言:本设计是基于ThingsCloud云平台版,还有另外一个版本是基于机智云平台版本,两个设计只是云平台和手机APP的区别,其他功能都一样。如下链接: 【物联网】基于LORA组网的远程环境监测系统设计(机…...

C++中指针Ptr(一级指针、二级指针)的基本使用详解(1)

C 中的指针是非常强大的工具&#xff0c;理解一级指针、二级指针以及它们与数组的关系&#xff0c;对于写出高效且安全的程序非常重要。下面我将从基础讲起&#xff0c;详细解释 一级指针、二级指针 的使用&#xff0c;注意事项&#xff0c;以及它们和数组之间的联系与区别&…...

科技赋能建筑新未来:中建海龙模块化建筑产品入选中国建筑首批产业化推广产品

在建筑工业化浪潮中&#xff0c;中国建筑国际集团旗下中建海龙科技有限公司&#xff08;以下简称“中建海龙”&#xff09;致力以科技创新赋能传统建造转型升级&#xff0c;大力发展新质生产力&#xff0c;促进科技成果在建筑产业体系化、规模化应用&#xff0c;面向“产品化、…...

示例:Spring JDBC 声明式事务(xml配置形式)

声明式事务是指在不修改源代码的情况下通过配置applicationContext.xml自动实现事务控制&#xff0c;其本质是AOP环绕通知。它的触发时机为&#xff1a;1、当目标方法执行成功时自动提交事务&#xff0c;2、当目标方法抛出运行时异常时&#xff0c;自动事务回滚 核心步骤示例&a…...

java多线程(7.0)

目录 ​编辑 定时器 定时器的使用 三.定时器的实现 MyTimer 3.1 分析思路 1. 创建执行任务的类。 2. 管理任务 3. 执行任务 3.2 线程安全问题 定时器 定时器是软件开发中的一个重要组件. 类似于一个 "闹钟". 达到一个设定的时间之后, 就执行某个指定好的…...

sgpt在kali应用

Kali Linux 下 sgpt 渗透测试相关案例 1. 扫描目标主机存活 sgpt -s "使用 nmap 扫描 192.168.1.100 是否存活"示例命令&#xff1a; nmap -sn 192.168.1.1002. 扫描目标主机开放端口和服务 sgpt -s "使用 nmap 扫描 192.168.1.100 常见端口和服务"示例…...

小白电路设计-设计11-恒功率充电电路设计

介绍 作为电子信息工程的我&#xff0c;电路学习是一定要学习的&#xff0c;可惜目前作为EMC测试工程师&#xff0c;无法兼顾太多&#xff0c;索性不如直接将所学的知识进行运用&#xff0c;并且也可以作为契机&#xff0c;进行我本人的个人提升。祝大家与我一起进行提升。1.本…...

express的模板handlebars用app.engine()创建配置和用exphbs.create()的区别

在使用 express-handlebars 时&#xff0c;app.engine 和 exphbs.create 都可以用来配置 Handlebars 模板引擎&#xff0c;但它们的使用方式和功能有一些区别。以下是详细的对比和说明 app.engine 方法 app.engine 是 Express 提供的方法&#xff0c;用于注册一个新的模板引擎…...

【Python数据库与后端开发】从ORM到RESTful API

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1&#xff1a;SQLAlchemy模型定义案例2&#xff1a;FastAPI异步接口案例3&#xff1a;连接池配…...

数据结构(java)二叉树的基本操作

1.二叉树的性质&#xff1a; 1.若规定根结点的层数为1&#xff0c;则一棵非空二叉树的第i层上最多有2*-1(i>0)个结点 2.若规定只有根节点的二叉树的深度为1&#xff0c;则深度为K的二叉树的最大结点数是2都k次方-1 3.对于任何一个二叉树&#xff0c;如果其叶结点个数为 n…...

windows编程字符串处理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、windows常用字符出处理函数&#xff1f;二、测试代码总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; Windows编程中主要使用两…...

CentOS系统防火墙服务介绍

CentOS 系统使用的是 firewalld 防火墙服务&#xff08;从 CentOS 7 开始&#xff09;&#xff0c;它基于 zone&#xff08;区域&#xff09; 和 service&#xff08;服务&#xff09; 的机制来配置网络访问控制&#xff0c;替代了传统的 iptables。 iptables 是 Linux 系统中…...

59、微服务保姆教程(二)Nacos--- 微服务 注册中心 + 配置中心

Nacos— 微服务 注册中心 + 配置中心 一.什么是Nacos? Nacos是阿里的一个开源产品,是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案。 Nacos核心定位是“一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台”,也就是我们的注册中心和配…...

Git命令行中vim的操作

Git命令行用vim打开文件&#xff0c;或者用其他git命令打开了文件&#xff0c;需要编辑和保存文件等&#xff0c;有些命令表情奇怪&#xff0c;往往容易忘记这些命令。记录下。 下面这篇比较实用和简练&#xff1a; gitvim编辑文件命令 • Worktile社区https://worktile.com/…...

【分布式系统中的“瑞士军刀”_ Zookeeper】一、Zookeeper 快速入门和核心概念

在分布式系统的复杂世界里&#xff0c;协调与同步是确保系统稳定运行的关键所在。Zookeeper 作为分布式协调服务的 “瑞士军刀”&#xff0c;为众多分布式项目提供了高效、可靠的协调解决方案。无论是在分布式锁的实现、配置管理&#xff0c;还是在服务注册与发现等场景中&…...

【昇腾】【训练】800TA2-910B使用LLaMA-Factory训练Qwen

文章目录 1. 使用docker安装1.1 配置docker1. 2 拉取 LLaMA-Factory1.3 修改配置 2. 下载模型3. 准备训练数据3.1 下载数据集3.2 自定义数据集配置 4. 训练4.1 训练配置4.2 启动训练4.3 训练效果测试 5. 合并权重 更好的阅读体验&#xff1a;传送门 服务器&#xff1a;800TA2 芯…...

Python自动化解决滑块验证码的最佳实践

1. 引言&#xff1a;滑块验证码的挑战与自动化需求 滑块验证码&#xff08;Slider CAPTCHA&#xff09;是当前互联网广泛使用的反爬机制之一&#xff0c;它要求用户手动拖动滑块到指定位置以完成验证。这种验证方式可以有效阻止简单的自动化脚本&#xff0c;但对爬虫开发者来说…...

知识蒸馏和迁移学习的区别

知识蒸馏和迁移学习虽然都涉及知识的传递&#xff0c;但并不是同一个概念&#xff0c;它们在目的、方法和应用场景上有显著区别&#xff1a; 1. 定义与核心思想 迁移学习&#xff08;Transfer Learning&#xff09; 是一种广义的机器学习范式&#xff0c;核心是将从一个任务或领…...

二项分布详解:从基础到应用

二项分布详解&#xff1a;从基础到应用 目录 引言二项分布的定义概率质量函数及其证明期望与方差推导二项分布的重要性质常见应用场景与其他分布的关系知识梳理练习与思考 引言 概率论中&#xff0c;二项分布是最基础也是最常用的离散概率分布之一。它描述了在固定次数的独…...