WebSocket聊天室的简单制作指南
一、前言
最近在学习WebSocket技术,做了一个简单的聊天室Demo。这个项目虽然不大,但涵盖了WebSocket的核心功能实现。下面我将详细介绍这个聊天室的实现过程,希望能帮助到同样想学习WebSocket的朋友们。
二、技术选型
-
后端:Spring Boot + WebSocket
-
前端:SockJS + STOMP.js
-
通信协议:STOMP(简单的面向文本的消息协议)
三、后端实现
1. WebSocket配置类
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {// 设置消息代理前缀config.enableSimpleBroker("/topic");// 设置应用目的地前缀config.setApplicationDestinationPrefixes("/app");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {// 注册WebSocket端点registry.addEndpoint("/ws").setAllowedOriginPatterns("*").withSockJS(); // 支持SockJS}
}
2. 消息处理控制器
@Controller
public class WebSocketController {@MessageMapping("/hello")@SendTo("/topic/greetings")public String greeting(String message) {System.out.println("收到消息: " + message);return message;}
}
四、前端实现
完整代码:
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head><title>WebSocket Chat Demo</title><script src="https://cdn.jsdelivr.net/npm/sockjs-client@1.6.1/dist/sockjs.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script><style>:root {--primary-color: #4CAF50;--secondary-color: #45a049;--error-color: #f44336;--border-color: #ddd;}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;max-width: 800px;margin: 0 auto;padding: 20px;background-color: #f9f9f9;}h1 {color: #333;text-align: center;margin-bottom: 20px;}#chat-container {background-color: white;border-radius: 8px;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);overflow: hidden;}#message-container {height: 400px;overflow-y: auto;padding: 15px;border-bottom: 1px solid var(--border-color);background-color: #fafafa;}.message {margin-bottom: 12px;padding: 10px 15px;border-radius: 18px;max-width: 70%;word-wrap: break-word;animation: fadeIn 0.3s ease;}.user-message {background-color: var(--primary-color);color: white;margin-left: auto;border-bottom-right-radius: 4px;}.server-message {background-color: #e5e5ea;color: black;margin-right: auto;border-bottom-left-radius: 4px;}#status {padding: 10px 15px;background-color: #f8f8f8;font-size: 14px;color: #666;text-align: center;border-bottom: 1px solid var(--border-color);}#message-form {display: flex;padding: 15px;background-color: white;}#message-input {flex-grow: 1;padding: 12px;border: 1px solid var(--border-color);border-radius: 4px;font-size: 16px;outline: none;transition: border 0.3s;}#message-input:focus {border-color: var(--primary-color);}#send-btn {padding: 12px 20px;margin-left: 10px;background-color: var(--primary-color);color: white;border: none;border-radius: 4px;cursor: pointer;font-size: 16px;transition: background-color 0.3s;}#send-btn:hover {background-color: var(--secondary-color);}#send-btn:disabled {background-color: #cccccc;cursor: not-allowed;}@keyframes fadeIn {from { opacity: 0; transform: translateY(5px); }to { opacity: 1; transform: translateY(0); }}.connection-status {display: inline-block;width: 10px;height: 10px;border-radius: 50%;margin-right: 5px;}.connected {background-color: var(--primary-color);}.disconnected {background-color: var(--error-color);}.timestamp {font-size: 12px;color: #999;margin-top: 4px;text-align: right;}</style>
</head>
<body>
<h1>WebSocket Chat Demo</h1><div id="chat-container"><div id="status"><span id="connection-status" class="connection-status disconnected"></span><span id="status-text">正在连接服务器...</span></div><div id="message-container"></div><form id="message-form"><input type="text" id="message-input" placeholder="输入消息..." autocomplete="off" autofocus><button type="submit" id="send-btn" disabled>发送</button></form>
</div><script>// 全局变量const socket = new SockJS('http://localhost:8080/ws');const stompClient = Stomp.over(socket);let username = '用户' + Math.floor(Math.random() * 1000);// DOM元素const messageContainer = document.getElementById('message-container');const messageForm = document.getElementById('message-form');const messageInput = document.getElementById('message-input');const sendBtn = document.getElementById('send-btn');const statusText = document.getElementById('status-text');const connectionStatus = document.getElementById('connection-status');// 初始化连接function connect() {updateStatus('正在连接服务器...', 'disconnected');// 禁用调试信息(生产环境)stompClient.debug = null;stompClient.connect({},function(frame) {onConnectSuccess(frame);},function(error) {onConnectError(error);});}// 连接成功回调function onConnectSuccess(frame) {updateStatus('已连接', 'connected');sendBtn.disabled = false;// 订阅消息stompClient.subscribe('/topic/greetings', function(response) {const message = JSON.parse(response.body);// 检查是否是自己的消息if (message.username !== username) {showMessage(`${message.username}: ${message.content}`, 'server-message');}});// 发送欢迎消息sendSystemMessage(`${username} 加入了聊天室`);}// 连接错误回调function onConnectError(error) {console.error('连接错误:', error);updateStatus('连接失败,5秒后重试...', 'disconnected');sendBtn.disabled = true;// 5秒后自动重连setTimeout(connect, 5000);}// 更新状态显示function updateStatus(text, status) {statusText.textContent = text;connectionStatus.className = 'connection-status ' + status;}// 显示消息function showMessage(content, messageType) {const messageElement = document.createElement('div');messageElement.className = `message ${messageType}`;const contentElement = document.createElement('div');contentElement.textContent = content;const timestampElement = document.createElement('div');timestampElement.className = 'timestamp';timestampElement.textContent = new Date().toLocaleTimeString();messageElement.appendChild(contentElement);messageElement.appendChild(timestampElement);messageContainer.appendChild(messageElement);messageContainer.scrollTop = messageContainer.scrollHeight;}// 发送用户消息function sendUserMessage() {const content = messageInput.value.trim();if (!content) return;// 显示用户消息showMessage(content, 'user-message');// 发送到服务器stompClient.send("/app/hello",{},JSON.stringify({username: username,content: content,timestamp: new Date().getTime()}));messageInput.value = '';}// 发送系统消息function sendSystemMessage(message) {showMessage(message, 'server-message');}// 事件监听messageForm.addEventListener('submit', function(e) {e.preventDefault();sendUserMessage();});// 回车发送消息messageInput.addEventListener('keypress', function(e) {if (e.key === 'Enter' && !e.shiftKey) {e.preventDefault();sendUserMessage();}});// 初始化connect();// 窗口关闭前发送离开消息window.addEventListener('beforeunload', function() {if (stompClient.connected) {sendSystemMessage(`${username} 离开了聊天室`);}});
</script>
</body>
</html>
JavaScript核心代码
// 初始化连接
const socket = new SockJS('http://localhost:8080/ws');
const stompClient = Stomp.over(socket);// 连接成功回调
function onConnectSuccess(frame) {updateStatus('已连接', 'connected');sendBtn.disabled = false;// 订阅消息stompClient.subscribe('/topic/greetings', function(response) {const message = JSON.parse(response.body);// 检查是否是自己的消息if (message.username !== username) {showMessage(`${message.username}: ${message.content}`, 'server-message');}});
}// 发送消息
function sendUserMessage() {const content = messageInput.value.trim();if (!content) return;// 显示用户消息showMessage(content, 'user-message');// 发送到服务器stompClient.send("/app/hello",{},JSON.stringify({username: username,content: content,timestamp: new Date().getTime()}));
}
五、遇到的问题及解决方案
问题:消息重复显示
现象:自己发送的消息会显示两次
原因:
-
前端发送后立即显示
-
服务器广播后又显示一次
解决方案:
stompClient.subscribe('/topic/greetings', function(response) {const message = JSON.parse(response.body);// 只显示别人发的消息if (message.username !== username) {showMessage(`${message.username}: ${message.content}`, 'server-message');}
});
六、项目特点
-
简单易用:代码简洁,适合初学者理解WebSocket原理
-
实时通信:基于WebSocket实现真正的双向通信
-
自动重连:网络断开后会自动尝试重新连接
-
用户区分:每个用户有随机生成的唯一用户名
七、总结
这个简单的WebSocket聊天室Demo虽然功能不多,但涵盖了WebSocket的核心功能。通过这个项目,我学到了:
-
WebSocket的基本工作原理
-
STOMP协议的使用方法
-
前后端如何通过WebSocket进行实时通信
-
如何处理常见的消息回显问题
如果想扩展功能,可以考虑添加:
-
用户列表显示
-
私聊功能
-
消息历史记录
-
图片/文件传输
未来计划:
Ai 聊天室 --- 未来可期
相关文章:
WebSocket聊天室的简单制作指南
一、前言 最近在学习WebSocket技术,做了一个简单的聊天室Demo。这个项目虽然不大,但涵盖了WebSocket的核心功能实现。下面我将详细介绍这个聊天室的实现过程,希望能帮助到同样想学习WebSocket的朋友们。 二、技术选型 后端:Spri…...
非国产算力DeepSeek 部署中的常见问题及解决方案
随着大语言模型(LLM)在企业级应用场景中的快速推进,DeepSeek 一体机凭借其高性能推理能力和便捷的系统集成优势,正逐步成为多行业智能化转型的重要基础设施。然而,在实际部署过程中,技术团队常常会遭遇一系…...
大数据技术的主要方向及其应用详解
文章目录 一、大数据技术概述二、大数据存储与管理方向1. 分布式文件系统2. NoSQL数据库3. 数据仓库技术 三、大数据处理与分析方向1. 批处理技术2. 流处理技术3. 交互式分析4. 图计算技术 四、大数据机器学习方向1. 分布式机器学习2. 深度学习平台3. 自动机器学习(AutoML) 五、…...
Maven使用详解:Maven的概述(二)
一、核心定义与功能 Maven是由Apache软件基金会开发的开源项目管理工具,专为Java项目设计,主要用于自动化构建、依赖管理和项目标准化。其核心功能包括: 依赖管理:通过pom.xml文件声明依赖库,自动从中央仓库下载并管…...
在 Odoo 18 表单视图中使用 JS 类的方法
在 Odoo 18 表单视图中使用 JS 类的方法 一、模块结构创建 要为特定视图在 JavaScript 里注册一个类。后续在任意表单视图中添加相同类时,自定义视图就会被注入该表单。 具体要做的是: 把自定义视图创建出来当作模板。将视图注册成一个组件。把它和表…...
ubuntu 更新华为源
1. 备份配置文件 sudo cp -a /etc/apt/sources.list /etc/apt/sources.list.bak 2. 修改source.list 文件,将http://archive.ubuntu.com和http://security.ubuntu.com替换成http://repo.huaweicloud.com,可以参考如下命令: # 第一条指令 s…...
如何安装cuda版本的pytorch
为什么安装Cuda 对于做深度学习研究的小伙伴本,当我们处理大量的数据时,尤其是图像数据时,过量的数据会导致我们的CPU运行压力过大,占用大量的运行内存,而且用CPU进行模型训练,训练的时间会很长࿰…...
国际名校教育大模型的构建与教学应用实践
一、引言 全球AI数字教育正在快速发展,人工智能技术已成为推动教育变革的核心驱动力。从个性化学习到智能评测,从虚拟助教到自适应教学系统,AI正在重塑教育的形态。在此背景下,国际顶尖高校纷纷布局教育大模型,探索AI与教学的深度融合,以提升教育质量、优化学习体验。与…...
postgres的docker版本安装
postgres的docker版本安装 背景 测试和开发需要用到postgres,越快越好,想到了用docker进行安装。 sudo docker run -d -p 5432:5432 --restartalways -v /home/docker/postgre/data:/var/lib/postgresql/data -e POSTGRES_PASSWORD123456 --name p…...
知识蒸馏实战:用PyTorch和预训练模型提升小模型性能
在深度学习的浪潮中,我们常常追求更大、更深、更复杂的模型以达到最先进的性能。然而,这些“庞然大物”般的模型往往伴随着高昂的计算成本和缓慢的推理速度,使得它们难以部署在资源受限的环境中,如移动设备或边缘计算平台。知识蒸…...
【HTML 全栈进阶】从语义化到现代 Web 开发实战
目录 🌟 前言🏗️ 技术背景与价值🩹 当前技术痛点🛠️ 解决方案概述👥 目标读者说明 🧠 一、技术原理剖析📊 核心概念图解💡 核心作用讲解🔧 关键技术模块说明⚖️ 技术选…...
Transformer 模型与注意力机制
目录 Transformer 模型与注意力机制 一、Transformer 模型的诞生背景 二、Transformer 模型的核心架构 (一)编码器(Encoder) (二)解码器(Decoder) 三、注意力机制的深入剖析 …...
机器学习数据预处理回归预测中标准化和归一化
在机器学习的回归预测任务中,** 标准化(Standardization)和归一化(Normalization)** 是数据预处理的重要步骤,用于消除不同特征量纲和取值范围的影响,提升模型训练效率和预测性能。 一、标准化…...
B2C 商城转型指南:传统企业如何用 ZKmall模板商城实现电商化
在数字化浪潮席卷全球的当下,传统企业向电商转型已不再是选择题,而是关乎生存与发展的必答题。然而,缺乏技术积累、开发成本高、运营经验不足等问题,成为传统企业转型路上的 “拦路虎”。ZKmall模板商城以其低门槛、高灵活、强适配…...
FPGA:Lattice的FPGA产品线以及器件选型建议
本文将详细介绍Lattice Semiconductor的FPGA产品线,帮助你了解各系列的特点和适用场景,以便更好地进行选型。Lattice以低功耗、小尺寸和高性能为核心,产品覆盖低中端市场,广泛应用于通信、计算、工业、汽车、消费电子、嵌入式视觉…...
学习51单片机02
吐血了,板子今天才到,下午才刚开始学的,生气了,害我笔记都断更了一天。。。。 紧接上文...... 如何将HEX程序烧写到程序? Tips:HEX 文件是一种常用于单片机等嵌入式系统的文件格式,它包含了程序的机器码…...
武汉SMT贴片工艺优化与生产效能提升路径
内容概要 随着华中地区电子制造产业集群的快速发展,武汉SMT贴片行业面临工艺升级与效能提升的双重挑战。本文聚焦SMT生产全流程中的关键环节,从钢网印刷精度控制、回流焊温度曲线优化、AOI检测系统迭代三大核心工艺出发,结合区域产业链特点提…...
LineBasicMaterial
LineBasicMaterial 描述 用于绘制纯色线条的基础材质,支持颜色、线宽和纹理映射。常用于THREE.Line或THREE.LineSegments几何体。 构造函数 (Constructor) 构造函数参数描述LineBasicMaterial(parameters?: Object)parameters定义材质外观的对象,可…...
虚拟机安装达梦数据库
准备 关闭SELINUX # setenforce 0 # vi /etc/selinux/config 修改SELINUXdisabled 上传达梦ISO 接下下载的达梦安装包,里面包含一个ISO文件,将其上传到CentOS的/tmp路径下安装达梦所需图形类库 # yum install -y gtk2 libXtst xorg-x11-…...
小波变换+注意力机制成为nature收割机
小波变换作为一种新兴的信号分析工具,能够高效地提取信号的局部特征,为复杂数据的处理提供了有力支持。然而,它在捕捉数据中最为关键的部分时仍存在局限性。为了弥补这一不足,我们引入了注意力机制,借助其能够强化关注…...
科技项目验收测试对软件产品和企业分别有哪些好处?
科技项目验收测试是指在项目的开发周期结束后,针对项目成果进行的一系列验证和确认活动。其目的是确保终交付的产品或系统符合预先设定的需求和标准。验收测试通常包括功能测试、性能测试、安全测试等多个方面,帮助企业评估软件在实际应用中的表现。 科…...
ChatGPT到Claude全适配:跨模型Prompt高级设计规范与迁移技巧
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习内容,尽在聚客AI学院。 一. 迭代优化:基于反馈的Prompt进化策略 1.1 优化闭环设计 初始Prompt → 生成结果 → 人工评估 → 问题分析 → 改进Prompt 代码示例&#x…...
NexBot AI 1.9.3 | 专业AI写作助手,高自由度定制内容,支持中文设置
NexBot AI是一款强大的人工智能助手应用程序,旨在帮助用户快速生成符合其需求的内容。通过高自由度的关键词和短语合并功能,用户可以根据自己的具体要求定制内容。该应用能够迅速生成多种输出结果供用户选择,非常适合需要高效工作流程的专业人…...
foxmail - foxmail 启用超大附件提示密码与帐号不匹配
foxmail 启用超大附件提示密码与帐号不匹配 问题描述 在 foxmail 客户端中,启用超大附件功能,输入了正确的账号(邮箱)与密码,但是提示密码与帐号不匹配 处理策略 找到 foxmail 客户端目录/Global 目录下的 domain.i…...
eVTOL、无人机电机功耗图和电机效率图绘制测试
测功机是测量电机性能的绝佳工具。通过施加可控负载,测功机可表征电机扭矩、转速和功率。但这是获取电机性能全面理解的唯一途径吗?我们想知道,能否仅通过电机-螺旋桨动力测试台(而非传统制动测功机)实现电机性能测绘。…...
React中useMemo和useCallback的作用:
一、useMemo 基本用法: useMemo 是 React 提供的一个 Hook,用于性能优化,它通过"记忆"(memoization)计算结果来避免在每次渲染时进行不必要的复杂计算。 const memoizedValue useMemo(() > computeExpensiveValue…...
【Shell的基本操作】
文章目录 一、实验目的二、实验环境三、实验内容3.1 Shell变量与脚本基础3.2 定制终端提示符(PS1变量)3.3 文件查找与类型确认(find命令)3.4 管道命令实战(用户登录统计)3.5 交互式备份压缩脚本 四、总结4.…...
部署docker上的redis,idea一直显示Failed to connect to any host resolved for DNS name
参考了https://blog.csdn.net/m0_74216612/article/details/144145127 这篇文章,关闭了centos的防火墙,也修改了redis.conf文件,还是一直显示Failed to connect to any host resolved for DNS name。最终发现是腾讯云服务器那一层防火墙没…...
Android 中 显示 PDF 文件内容(AndroidPdfViewer 库)
PDFView 是一个用于在 Android 应用中显示 PDF 文档的库。它提供了丰富的功能和灵活的配置选项,使得开发者能够轻松地在应用中嵌入 PDF 阅读器。 一、 添加依赖 在模块的 build.gradle 文件中添加以下依赖: // pdfimplementation("com.github.bar…...
Linux 系统切换国内镜像源教程
在中国大陆使用 Linux 系统时,由于网络环境的原因,连接官方的软件包镜像源速度较慢,甚至可能出现连接失败的情况。此时,将系统配置为使用国内的镜像源可以显著提升软件包下载和更新的速度。 常见的国内镜像源 阿里云镜像站: htt…...
4.2.3 Thymeleaf标准表达式 - 2. 选择表达式
本实战通过 Thymeleaf 的选择表达式(*{})演示了如何在模板中操作和展示对象的属性与方法。首先,在控制器中创建了一个 User 对象,并将其添加到模型中。接着,在 test2.html 模板中,通过 th:object 声明了对象…...
C#学习第23天:面向对象设计模式
什么是设计模式? 定义:设计模式是软件开发中反复出现的特定问题的解决方案。它们提供了问题的抽象描述和解决方案。目的:通过提供成熟的解决方案,设计模式可以加快开发速度并提高代码质量。 常见的设计模式 设计模式通常分为三大…...
【数据结构】二分查找-LeftRightmost
查找: Leftmost(最左侧重复元素) package 二分查找;public class BinarySearch {public static void main(String[] args) {// TODO Auto-generated method stub}public static int binarySearchBasic(int[] a,int target) {int i0,ja.length-1; //设置指针初值in…...
汽车装配又又又升级,ethernetip转profinet进阶跃迁指南
1. 场景描述:汽车装配线中,使用EtherNet/IP协议的机器人与使用PROFINET协议的PLC进行数据交互。 2. 连接设备:EtherNet/IP机器人控制器(如ABB、FANUC)与PROFINET PLC(如西门子S7-1500)。 3. 连…...
链表的中间结点数据结构oj题(力扣876)
目录 题目描述: 题目分析: 代码解决: 题目描述: 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 题目分析: 寻找中间节点这道题原理…...
LLM学习笔记(五)概率论
1. 随机变量与概率分布:模型输出的基础 在LLM中,随机变量最直观的体现就是模型预测的下一个token。每个时刻,模型都会输出一个概率分布,表示词汇表中每个token可能是"下一个词"的概率。 直观理解 想象模型在处理句子…...
归并排序:分治思想的优雅实现
归并排序(Merge Sort)以简洁而高效的分治思想,在众多排序算法中占据着重要的地位。今天,就让我们一同深入探索归并排序的奥秘。 一、归并排序简介 归并排序是一种基于分治策略的排序算法。它的核心思想是将一个大的问题分解成若…...
从小区到商场再到校园,AI智能分析网关V4高空抛物检测方案全场景护航
在城市化进程不断加速的背景下,高层建筑如雨后春笋般涌现,然而,高空抛物这一“悬在城市上空的痛”却严重威胁着人民群众的生命财产安全。传统的监控方式难以对高空抛物行为进行及时、准确地识别与预警,而AI智能分析网关V4搭载高空…...
WEB安全--Java安全--shiro550反序列化漏洞
一、前言 什么是shiro? shiro是一个Apache的Java安全框架 它的作用是什么? Apache Shiro 是一个强大且灵活的 Java 安全框架,用于处理身份验证、授权、密码管理以及会话管理等功能 二、shiro550反序列化原理 1、用户首次登录并勾选记住密码…...
现代计算机图形学Games101入门笔记(十一)
致敬两位大佬 面的细分、简化、正则化 Loop 不是循环,是这个算法的发明人家族名称是Loop. 新增点,白点是不更新前通过细分得到的点。通过加权平均4个点坐标,更新坐标就是最后细分点的坐标。 如果细分出新的点刚好在老点上。那一部分相信周围点…...
OAT 初始化时出错?问题可能出在 PAM 配置上|OceanBase 故障排查实践
本文作者:爱可生数据库工程师,任仲禹,擅长故障分析和性能优化。 背景 某客户在使用 OAT 初始化OceanBase 服务器的过程中,进行到 precheck 步骤时,遇到了如下报错信息: ERROR - check current session ha…...
现场血案:Kafka CRC 异常
一、背景 现场童鞋说客户的研发环境突然在近期间歇式的收到了CRC的相关异常,异常内容如下 Record batch for partition skywalking-traces-0 at offset 292107075 is invalid, cause: Record is corrupt (stored crc = 1016021496, compute crc = 1981017560) 报错完全没有…...
实时技术方案对比:SSE vs WebSocket vs Long Polling
早期网站仅展示静态内容,而如今我们更期望:实时更新、即时聊天、通知推送和动态仪表盘。 那么要如何实现实时的用户体验呢?三大经典技术各显神通: SSE(Server-Sent Events):轻量级单向数据流WebSocket:双向全双工通信Long Polling(长轮询):传统过渡方案假设目前有三…...
搭建游戏云服务器的配置要求包括哪些条件?
在游戏行业迅猛发展的背景下,越来越多的游戏团队、独立开发者、企业平台开始将服务器部署转向云端,尤其是在初期测试、公测阶段及全球发布期,云服务器所带来的弹性部署、全球覆盖、成本控制能力成为不可替代的优势。但问题随之而来࿱…...
Go语言八股文之Mysql锁详解
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...
1T 服务器租用价格解析
服务器作为数据存储与处理的核心设备,对于企业和个人开发者而言至关重要。当涉及到租用 1T 服务器时,价格是大家很为关注的要点。然而,1T 服务器租用一个月的费用并非固定不变,而是受到诸多因素的综合影响。 影响 1T 服务器租用…...
面试题:详细分析Arraylist 与 LinkedList 的异同
相同点 都是List接口的实现类: ArrayList和LinkedList都实现了Java集合框架中的List接口,因此它们都提供了对列表元素的操作方法。 都继承了Collection接口: 由于List接口继承了Collection接口,所以ArrayList和LinkedList也都继承…...
6 任务路由与负载均衡
一、任务路由核心机制 1.1 静态路由配置 # celeryconfig.pytask_routes {# 精确匹配任务路径payment.process_order: {queue: priority_payment},# 通配符匹配任务类型report.*: {queue: low_priority_reports},# 正则表达式匹配re.compile(r^video\.(encode|compress)): {q…...
前端精度问题全解析:用“挖掘机”快速“填平精度坑”的完美解决方案
写在前面 “为什么我的计算在 React Native 中总是出现奇怪的精度问题?” —— 这可能是许多开发者在作前端程序猿的朋友们都会遇到的第一个头疼问题。本文将深入探讨前端精度问题的根源,我将以RN为例,并提供一系列实用解决方案,让你的应用告别计算误差。 一、精度问题的…...
探索嵌入式硬件的世界:技术、应用与未来趋势
目录 一、什么是嵌入式硬件? 二、嵌入式硬件的核心组件与架构 1. 微处理器与控制器 2. 存储器设备 3. 输入/输出接口 4. 电源管理模块 5. 时钟芯片与时序控制 三、嵌入式硬件的设计原则与技术难点 1. 低功耗与能耗优化 2. 小型化与高度集成 3. 高可靠性和…...