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

使用SSE实现实时消息推送并语音播报:从后端到前端的完整指南

前言

在现代Web应用中,实时消息推送已成为提升用户体验的关键功能。无论是即时聊天、通知提醒还是实时数据更新,都需要一种高效的服务器到客户端的通信机制。本文将详细介绍如何使用Server-Sent Events (SSE)技术实现后端向前端的实时消息推送,并提供一个完整的实现方案。

什么是SSE?

Server-Sent Events (SSE) 是一种允许服务器向客户端推送实时更新的Web技术。与WebSocket不同,SSE是基于HTTP的单向通信(服务器→客户端),实现简单且天然支持断线重连,非常适合需要服务器推送但客户端不需要频繁发送数据的场景。

SSE的主要优势:

  1. 简单易用:基于标准HTTP协议,无需额外协议

  2. 自动重连:内置断线重连机制

  3. 轻量级:相比WebSocket更轻量

  4. 文本友好:特别适合推送文本消息

完整实现方案

下面我将通过一个完整的示例来展示如何实现SSE消息推送,包括后端服务和前端界面。

1. 后端实现

1.1 SSE服务核心类
@Service
public class SseService {private final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();private final ExecutorService executor = Executors.newCachedThreadPool();// 客户端订阅public SseEmitter subscribe(String clientId) {SseEmitter emitter = new SseEmitter(180_000L); // 3分钟超时// 设置各种回调emitter.onCompletion(() -> removeEmitter(clientId));emitter.onTimeout(() -> removeEmitter(clientId));emitter.onError(e -> removeEmitter(clientId));emitters.put(clientId, emitter);// 发送初始化事件try {emitter.send(SseEmitter.event().id("0").name("connect").data("Connected!"));} catch (IOException e) {removeEmitter(clientId);}return emitter;}// 广播消息给所有客户端public void broadcast(String message) {List<String> deadEmitters = new ArrayList<>();emitters.forEach((clientId, emitter) -> {executor.execute(() -> {try {if (emitter != null) {synchronized (emitter) {emitter.send(SseEmitter.event().id(String.valueOf(System.currentTimeMillis())).name("message").data(message));}}} catch (Exception e) {deadEmitters.add(clientId);}});});// 清理无效连接deadEmitters.forEach(this::removeEmitter);}// 移除指定客户端private synchronized void removeEmitter(String clientId) {SseEmitter emitter = emitters.remove(clientId);if (emitter != null) {try {emitter.complete();} catch (Exception e) {// 忽略关闭时的异常}}}// 应用关闭时清理资源@PreDestroypublic void destroy() {emitters.keySet().forEach(this::removeEmitter);executor.shutdownNow();}
}
1.2 SSE控制器
@RestController
@RequestMapping("/api/sse")
public class SseController {@Autowiredprivate SseService sseService;// 订阅接口@GetMapping("/subscribe")public SseEmitter subscribe(@RequestParam String clientId) {return sseService.subscribe(clientId);}// 测试发送消息接口@PostMapping("/send")public ResponseEntity<Void> sendMessage(@RequestParam String message) {try {sseService.broadcast(message);return ResponseEntity.ok().build();} catch (Exception e) {return ResponseEntity.internalServerError().build();}}
}

2. 前端实现

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>消息监听</title><style>#messageBox {height: 400px;overflow-y: auto;border: 1px solid #ccc;padding: 10px;margin-bottom: 10px;}.message {margin: 5px 0;padding: 5px;background-color: #f5f5f5;border-radius: 4px;}</style>
</head>
<body><h2>实时消息监听</h2><div id="messageBox"></div><div><label><input type="checkbox" id="enableVoice" checked>启用语音播报</label><button onclick="testVoice()">测试语音</button></div><script>const clientId = 'client_' + Math.random().toString(36).substr(2, 9);const messageBox = document.getElementById('messageBox');const enableVoiceCheckbox = document.getElementById('enableVoice');const synth = window.speechSynthesis;// 初始化语音合成function loadVoices() {voices = synth.getVoices();}loadVoices();if (speechSynthesis.onvoiceschanged !== undefined) {speechSynthesis.onvoiceschanged = loadVoices;}// 语音播报功能function speak(text) {if (!enableVoiceCheckbox.checked) return;synth.cancel(); // 取消之前的语音const utterance = new SpeechSynthesisUtterance(text);const chineseVoice = voices.find(voice => voice.lang.includes('zh'));if (chineseVoice) {utterance.voice = chineseVoice;}utterance.lang = 'zh-CN';utterance.onerror = (event) => {console.error('语音播报错误:', event);};synth.speak(utterance);}// 连接SSEfunction connectSSE() {const eventSource = new EventSource(`/api/sse/subscribe?clientId=${clientId}`);eventSource.addEventListener('message', function(event) {// 显示消息const messageDiv = document.createElement('div');messageDiv.className = 'message';messageDiv.textContent = event.data;messageBox.insertBefore(messageDiv, messageBox.firstChild);// 语音播报speak(event.data);});// 错误处理与重连eventSource.onerror = function(error) {console.error('SSE连接错误:', error);eventSource.close();setTimeout(connectSSE, 5000); // 5秒后重连};}// 启动连接connectSSE();// 页面隐藏时停止语音document.addEventListener('visibilitychange', function() {if (document.hidden) {synth.cancel();}});</script>
</body>
</html>

与WebSocket的对比

特性SSEWebSocket
通信方向单向(服务器→客户端)双向
协议HTTP独立协议
断线重连内置支持需手动实现
二进制数据不支持支持
浏览器兼容性IE不支持更广泛
实现复杂度简单较复杂

适用场景

SSE特别适合以下场景:

  • 服务器向客户端推送通知

  • 实时数据更新(如股票价格、体育比分)

  • 新闻/社交媒体feed更新

  • 需要简单实现的实时功能

总结

SSE提供了一种简单高效的服务器推送技术方案,本文通过完整的代码示例展示了如何从零开始实现一个功能完善的SSE推送系统。相比WebSocket,SSE在实现简单性、自动重连等方面具有明显优势,是许多实时应用场景的理想选择。

希望本文能帮助你理解并应用SSE技术。如果你有任何问题或建议,欢迎在评论区留言讨论!

相关文章:

使用SSE实现实时消息推送并语音播报:从后端到前端的完整指南

前言 在现代Web应用中&#xff0c;实时消息推送已成为提升用户体验的关键功能。无论是即时聊天、通知提醒还是实时数据更新&#xff0c;都需要一种高效的服务器到客户端的通信机制。本文将详细介绍如何使用Server-Sent Events (SSE)技术实现后端向前端的实时消息推送&#xff…...

交通运输部4项网络与数据安全标准发布

近日&#xff0c;交通运输部审查通过并发布《交通运输数据安全风险评估指南》《交通运输行业网络安全实战演练工作规程》《交通运输电子证照数据交换与应用要求》《冷藏集装箱智能终端技术规范》等 4 项交通运输行业标准&#xff08;2025 年第 3 批&#xff09;。 ​其中&#…...

HarmonyOS-ArkUI V2装饰器: @Monitor装饰器:状态变量修改监听

Monitor作用 Monitor的作用就是来监听状态变量的值变化的。被Monitor修饰的函数,会在其对应监听的变量发生值的变化时,回调此函数,从而可以让您知道是什么值发生变化了,变化前是什么值,变化后是什么值。 V1版本的装饰器,有个叫@Watch的装饰器,其实也有监听变化的能力,…...

在Ubuntu系统中运行Windows程序

在Ubuntu系统中运行Windows程序可通过以下方法实现&#xff0c;根据使用场景和需求选择最适合的方案&#xff1a; 一、使用Wine兼容层&#xff08;推荐轻量级场景&#xff09; 原理&#xff1a;通过模拟Windows API环境直接运行.exe文件&#xff0c;无需安装完整系统。 步骤&a…...

七大数据库全面对比:ClickHouse、ES、MySQL等特性、优缺点及使用场景

七大数据库全面对比:ClickHouse、ES、MySQL等特性、优缺点及使用场景 引言 在数字化时代,数据库的选择对于业务的成功至关重要。本文将通过表格形式,对ClickHouse、Elasticsearch(ES)、MySQL、SQL Server、MongoDB、HBase、Cassandra这七大数据库进行特性、优缺点及使用…...

循环神经网络 - 门控循环单元网络之参数学习

GRU&#xff08;门控循环单元&#xff09;的参数学习与其他循环神经网络类似&#xff0c;主要依赖于梯度下降和反向传播通过时间&#xff08;BPTT&#xff09;算法。下面我们通过一个简单例子来说明 GRU 参数是如何在训练过程中“自适应”调整的。 一、GRU参数学习 假设我们的…...

Java并发编程面试题:内存模型(6题)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

SpringBoot Starter自定义:创建可复用的自动配置模块

文章目录 引言一、自定义Starter基础知识二、创建自动配置模块2.1 项目结构搭建2.2 配置属性类2.3 服务接口及实现2.4 自动配置类2.5 spring.factories文件2.6 Maven依赖配置 三、创建Starter模块3.1 项目结构3.2 Maven依赖配置 四、使用自定义Starter4.1 添加依赖4.2 配置属性…...

服务器风扇故障导致过热问题的解决方案

# 服务器风扇故障导致过热问题的解决方案 ## 一、故障诊断与确认 ### 1. 确认风扇故障现象 bash # 检查系统日志中的硬件错误 dmesg | grep -i fan journalctl -b | grep -i thermal # 查看传感器数据&#xff08;需要安装lm-sensors&#xff09; sudo sensors-detect sudo …...

[OS] vDSO + vvar(频繁调用的处理) | 存储:寄存器(高效)和栈(空间大)| ELF标准包装规范(加速程序加载)

vDSO vvar 一、社区公告板系统&#xff08;类比 vDSO vvar&#xff09; 想象你住在一个大型社区&#xff0c;管理员&#xff08;内核&#xff09;需要向居民&#xff08;用户程序&#xff09;提供实时信息&#xff08;如天气预报、社区活动时间等&#xff09;。直接让每个居…...

SQL刷题日志(day1)

1、substring_index&#xff08;截取字符串&#xff09; 参数说明&#xff1a; profile&#xff1a;要处理的字符串字段。,&#xff1a;分隔符。-1&#xff1a;表示从字符串的右侧开始截取&#xff0c;第一个出现的分隔符后面的所有内容。 SELECT SUBSTRING_INDEX(profile, ,…...

爬虫:一文掌握 curl-cffi 的详细使用(支持 TLS/JA3 指纹仿真的 cURL 库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、curl-cffi 概述1.1 curl-cffi介绍1.2 主要特性1.3 适用场景1.4 使用 curl-cffi 的注意事项1.5 与 requests 和 pycurl 对比1.6 curl-cffi 的安装二、基本使用2.1 同步请求2.2 异步请求三、高级功能3.1 模拟浏览器指…...

前端开发基础:HTML 与 CSS 入门详解

目录 一、HTML 基础 &#xff08;一&#xff09;HTML 概述 &#xff08;二&#xff09;HTML 标签 标签分类 常用标签详解 &#xff08;三&#xff09;HTML 注释 二、CSS 样式 &#xff08;一&#xff09;CSS 概述 &#xff08;二&#xff09;CSS 引入方式 &#xff0…...

实时语音交互数字人VideoChat,可自定义形象与音色,支持音色克隆,首包延迟低至3s

简介 实时语音交互数字人&#xff0c;支持端到端语音方案&#xff08;GLM-4-Voice - THG&#xff09;和级联方案&#xff08;ASR-LLM-TTS-THG&#xff09;。用户可通过麦克风或文本输入&#xff0c;与数字人进行语音或视频交互。 目前支持的功能 支持自定义形象TTS模块添加音…...

25.OpenCV中的霍夫圆变换

OpenCV中的霍夫圆变换 在图像处理与计算机视觉中&#xff0c;圆形检测是一项常见的任务&#xff0c;应用场景包括车牌识别、瞳孔检测、交通标志识别等。霍夫圆变换&#xff08;Hough Circle Transform&#xff09;是一种高效且鲁棒的算法&#xff0c;通过在参数空间中寻找局部…...

OpenTiny使用指南

最近项目里用到了一个新的组件库——OpenTiny&#xff0c;但是官方文档的使用指南的描述很复杂&#xff0c;花了一些时间尝试才正常使用。下面是一个使用步骤的描述&#xff0c;可放心食用&#xff1a; 一、安装 TinyVue 组件库同时支持 Vue 2.0 和 Vue 3.0 框架&#xff0c;…...

Uniapp: 大纲

目录 一、基础巩固1.1、Uniapp:下拉选择框ba-tree-picker 二、项目配置2.1、Uniapp&#xff1a;修改端口号2.2、Uniapp&#xff1a;本地存储 一、基础巩固 1.1、Uniapp:下拉选择框ba-tree-picker 二、项目配置 2.1、Uniapp&#xff1a;修改端口号 2.2、Uniapp&#xff1a;本…...

A2A协议实现详解及示例

A2A协议概述 A2A (Agent2Agent) 是Google推出的一个开放协议&#xff0c;旨在使AI智能体能够安全地相互通信和协作。该协议打破了孤立智能体系统之间的壁垒&#xff0c;实现了复杂的跨应用自动化。[1] A2A协议的核心目标是让不同的AI代理能够相互通信、安全地交换信息以及在各…...

HTTP协议入门

文章目录 1. 概述2. 请求协议2.1 Get 方式请求协议2.2 POST 方式的请求2.3 获取请求数据 3. 响应协议3.1 响应数据格式3.2 设置响应数据 1. 概述 概念 &#xff1a;Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则…...

远程控制Android手机(web-scrcpy)

最近有web远程查看和控制Android手机的需求&#xff0c;研究了一下scrcpy&#xff0c;发现还是比较容易实现远程控制&#xff0c;所以自己就用flask写了一个web远程控制的scrcpy&#xff0c;算是推荐一下自己的作品&#xff0c;作品地址&#xff1a;https://github.com/baixin1…...

在AWS EC2上部署网站的完整步骤指南

本文详细介绍如何从零开始在AWS EC2实例上部署静态/动态网站&#xff0c;涵盖实例创建、安全组配置、环境搭建及域名绑定等关键步骤。 一、准备工作 AWS账号&#xff1a;访问 AWS官网 注册账号并完成信用卡绑定 本地工具&#xff1a; SSH客户端&#xff08;Mac/Linux自带终端&…...

CentOS下,Xftp中文文件名乱码的处理方式

乱码原因 中文版Windows默认使用GBK编码&#xff0c;现代Linux发行版&#xff08;如CentOS、Ubuntu等&#xff09;默认使用UTF-8编码。Windows下正常的编码&#xff0c;可能在linux下无法识别&#xff0c;例如&#xff1a;Windows的GBK字节0xD6D0被Linux用UTF-8解码时&#xf…...

Linux vagrant 导入ubuntu到virtualbox

前言 vagrant 导入ubuntu虚拟机 前提要求 安装 virtualbox 和vagrant<vagrant-disksize> (Linux 方式 Windows 方式) 创建一键部署ubuntu虚拟机 /opt/vagrant 安装目录/opt/VirtualBox 安装目录/opt/ubuntu22/Vagrantfile &#xff08;可配置网络IP&#xff0c;内存…...

2025高频面试算法总结篇【动态规划】

文章目录 直接刷题链接直达编辑距离最长回文子串完全平方数最长递增子序列正则表达式匹配零钱兑换鸡蛋掉落单词拆分 直接刷题链接直达 动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种通过拆解子问题并利用子问题的最优解来构建整体问题的最优解的方法&#x…...

FPGA_UART

1.UART 概述 &#xff08;通用异步收发传输器&#xff09; 1. 基本定义 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;是一种常见的串行通信协议&#xff0c;用于在设备间通过异步串行通信传输数据。它不依赖独立的时钟信号&#xff0c;而是通过预…...

绿算轻舟系列FPGA加速卡:驱动数字化转型的核心动力

在数字化浪潮席卷全球的今天&#xff0c;算力已成为推动企业创新和行业升级的核心引擎。绿算轻舟系列FPGA加速卡凭借其高性能、低延迟、高能效比的独特优势&#xff0c;正成为各领域智能化转型的“隐形加速器”。它以灵活的硬件架构和强大的并行计算能力&#xff0c;为复杂场景…...

gitee基本使用

git实用手册 git全局设置 git config --global user.name "yourname" git config --global user.email "youremail"推代码时的账号&#xff08;email) 版本回退 git loggit reset –hard <码>git push -f HTTPS步骤(上传) 拉取项目 1、新建一个…...

最短路径介绍

最短路径是图论中的算法&#xff0c;下面将列举几个常见的算法&#xff1a; &#x1f697; 一、单源最短路径&#xff08;一个起点到所有点&#xff09; 1. Dijkstra 算法 适用图&#xff1a;非负权图&#xff08;不能有负权边&#xff09; 思路&#xff1a;贪心 最小堆&am…...

VRRP 基础全解析:从结构到配置

目录 VRRP基本概述 VRRP基本结构 状态机 ​编辑 负载分担 &#xff08;多个VRRP&#xff09; VRRP基本概述 VRRP能够在不改变组网的情况下&#xff0c;将多台路由器虚拟成一个虚拟路由器&#xff0c;通过配置虚拟路由器的IP地址为默认网关&#xff0c;实现网关的备份。协…...

【NIO番外篇】之组件 Buffer

目录 一、Buffer&#xff1a;数据界的“快递小哥”/“临时仓库管理员” &#x1f609;什么是 Buffer&#xff1f;它的作用是什么&#xff1f; 二、Buffer 的“三围”和“书签”&#x1f4cc;&#xff1a;核心属性1. Capacity (容量)&#xff1a;2. Position (位置)&#xff1a;…...

Python基础知识(一、基础语法)

Python基础知识&#xff08;一、基础语法&#xff09; 字面量注释单行注释多行注释 变量数据类型数据类型查看数据类型转换 标识符命名规范不可使用关键字 运算符算数运算符赋值运算符 字符串字符串的定义方式字符串拼接占位拼接数字精度控制快速格式化 数据输入逻辑运算比较运…...

C语言题目自增在前与在后

一、题目引入 谨记真言: i的值最终都会改变 只是表达式的值不同 二、分析题目 if判断语句里面要条件为真执行时 printf语句 i 变量在前 使用i的当前值是1 i的值就是1与1相等 所以&&左边的为真 但是&&存在 必须前后都为真才为真 所以还要看&&后面…...

【口腔粘膜鳞状细胞癌】文献阅读

写在前面 看看文章&#xff0c;看看有没有思路 文献 The regulatory role of cancer stem cell marker gene CXCR4 in the growth and metastasis of gastric cancer IF:6.8 中科院分区:1区 医学WOS分区: Q1 目的&#xff1a;通过 scRNA-seq 结合大量 RNA-seq 揭示癌症干细胞…...

如何撤回刚提交的 commit

如何撤回刚提交的 commit 如果刚刚执行了 git commit 但想撤销这个提交&#xff0c;有几种方法可以实现&#xff0c;具体取决于你想达到的效果&#xff1a; 1. 撤销 commit 但保留更改&#xff08;修改回到暂存区&#xff09; git reset --soft HEAD~1这会撤销最后一次提交提…...

deepin使用autokey添加微信快捷键一键显隐ctrl+alt+w

打开deepin商店&#xff0c;搜索快捷键&#xff0c;找到autokey 快捷键管理&#xff0c;点击安装 点击右键新建文件夹 点击右键新建脚本 打开脚本并添加以下内容 import subprocess import time# ------------------ 配置项 ------------------ WM_CLASS "wechat…...

开源微调混合推理模型:cogito-v1-preview-qwen-32B

一、模型概述 1.1 模型特点 Cogito v1-preview-qwen-32B 是一款基于指令微调的生成式语言模型&#xff08;LLM&#xff09;&#xff0c;具有以下特点&#xff1a; 支持直接回答&#xff08;标准模式&#xff09;和自我反思后再回答&#xff08;推理模式&#xff09;。使用 I…...

【uniapp-兼容性处理】swiper在iOS上偶发出现后几张图片白屏情况

【日期】2025-04-14 【问题】 swiper在iOS上偶发出现后几张图片白屏情况 swiper内部的几个swiper-item垂直排列&#xff0c;各自进行滚动&#xff0c;样式方面兼容性出现问题 【原因】&#xff1a; 原代码&#xff1a;&#xff08;不应在swiper-item添加style属性&#xf…...

go中new和make有什么异同?

相同点&#xff1a;都是给变量分配内存 不同点&#xff1a; 作用类型不同。new通常给int、string、数组类型的变量分配内存&#xff0c;而make通常给slice、map、channel分配内存。返回值类型不同。new返回指向变量的指针&#xff0c;make返回的是变量本身new分配内存空间后&…...

RabbitMQ 深度解析:从基础到高级应用的全面指南

&#x1f430; RabbitMQ 深度解析&#xff1a;从基础到高级应用的全面指南 前言&#x1f4d8; 一、RabbitMQ 简介⚙️ 二、核心特性可靠性 &#x1f512;灵活路由 &#x1f504;高可用性 &#x1f310;多协议支持 &#x1f30d;多语言客户端 &#x1f4bb;插件机制 &#x1f50…...

动手强化学习之马尔可夫决策(机器人篇)

1 马尔可夫决策过程 马尔可夫决策过程&#xff08;Markov Decision Process, MDP&#xff09;是一种数学框架&#xff0c;用于建模智能体&#xff08;agent&#xff09;在随机环境中做决策的问题。它假设环境的状态转换具有马尔可夫性质&#xff0c;即未来的状态只依赖于当前状…...

【RabbitMQ】核心概念和工作流程

文章目录 RabbitMQ 工作流程流程图 Producer 和 ConsumerConnecting 和 ChannelVirtual hostQueueExchangeRabbitMQ 工作流程 RabbitMQ 工作流程 流程图 RabbitMQ 就是一个生产者/消费者模型 Producer 就是生产者、Consumer 就是消费者Broker 是 RabbitMQ 服务器生产者和消费…...

Windows 操作系统 - Windows 10 磁盘管理无法为 C 盘选择扩展卷

Windows 10 磁盘管理无法为 C 盘选择扩展卷 在 Windows 10 的磁盘管理中&#xff0c;无法为 C 盘选择扩展卷&#xff08;选项灰色不可用&#xff09;&#xff0c;主要原因是未分配空间没有紧邻 C 盘的右侧 补充&#xff1a;Windows 10 磁盘管理打开方式 1. 按下快捷键【Win …...

数据结构——双向链表

首先我们要介绍一下链表的分类 链表的分类 链表说明&#xff1a; 虽然有这么多种链表结构&#xff0c;但是我们实际中用的还是两种结构&#xff1a;单链表&#xff08;单向不带头不循环&#xff09;和 双向带头循环链表 。 单链表&#xff08;单向不带头不循环&#xff09;&…...

Git报错remote: Verify fatal: Authentication failed for ***

解决 Git 拉取代码时报错&#xff1a;fatal: Authentication failed 在使用 Git 时&#xff0c;执行如下命令&#xff1a; git pull origin master出现报错&#xff1a; remote: Verify fatal: Authentication failed for ***一、问题原因分析 1. 使用 HTTP 协议访问&#…...

八、自动化函数

1.元素的定位 web自动化测试的操作核心是能够找到页面对应的元素&#xff0c;然后才能对元素进行具体的操作。 常见的元素定位方式非常多&#xff0c;如id,classname,tagname,xpath,cssSelector 常用的主要由cssSelector和xpath 1.1 cssSelector选择器 选择器的功能&#x…...

websoket 学习笔记

目录 基本概念 工作原理 优势 应用场景 HTTP协议与 webSoket协议之间的对比 消息推送场景 1. 轮询&#xff08;Polling&#xff09; 2. 长轮询&#xff08;Long Polling&#xff09; 3. 服务器发送事件&#xff08;Server-Sent Events, SSE&#xff09; 4. WebSocket…...

正版金币捕鱼海洋管家APP源码结构解析与运行环境说明

这是一款基于成熟运营逻辑开发的休闲类互动娱乐游戏《海洋管家》&#xff0c;采用金币流通体系&#xff0c;双端源码完整&#xff0c;结构清晰&#xff0c;适合用于结构学习、本地部署测试或功能参考。 整体玩法围绕捕鱼为主线&#xff0c;并融合了排行榜、VIP、签到、道具商城…...

大语言模型深度思考与交互增强

总则&#xff1a;深度智能交互的全面升级 在主流大语言模型&#xff08;LLM&#xff09;与用户的每一次交互中&#xff0c;模型需于回应或调用工具前&#xff0c;展开深度、自然且无过滤的思考进程。当模型判断思考有助于提升回复质量时&#xff0c;必须即时进行全方位的思考与…...

Vue.js 项目中 vue.config.js 常用配置项解析

Vue.js 项目中 vue.config.js 常用配置项解析 摘要 在 Vue CLI 创建的项目中&#xff0c;vue.config.js 是核心配置文件&#xff0c;用于定制化构建、开发和部署流程。本文详细解析了该文件的常用配置项&#xff0c;包括基础路径、开发服务器、Webpack 配置、CSS 预处理、插件…...

Javascript逗号操作符

这段代码是一个使用了生成器函数&#xff08;Generator Function&#xff09;的无限循环&#xff08;for (;;)&#xff09;&#xff0c;内部通过switch语句控制流程。代码中有很多逗号分隔的语句&#xff0c;这其实是利用了JavaScript的逗号操作符&#xff08;comma operator&a…...