基于STOMP 协议的 WebSocket 实现传输长字符串方案

为了通过 STOMP 协议的 WebSocket 实现传输长字符串(如超过 1MB 的消息),我们需要从前端到后端的多个方面进行配置和优化,包括心跳检测、消息分块、Tomcat 超时设置等。以下是一个完整的方案,涵盖前端和后端的配置,以及长字符串的传输处理。

方案要点:

  1. 前端分块传输大字符串:WebSocket 可能对单条消息大小有限制,因此需要将大字符串分块传输。
  2. 心跳检测:通过心跳检测来保持 WebSocket 连接的活跃性,防止长时间无消息传输时连接断开。
  3. Tomcat 配置:确保 Tomcat 的连接超时时间超过心跳间隔,避免因超时导致的连接断开。
  4. 自动重连机制:在连接断开时自动重连,确保连接的稳定性。
  5. 代理服务器配置:如果有代理服务器(如 NGINX),确保配置允许长时间连接和大消息传输。

完整方案:

1. 前端:分块传输长字符串,心跳检测和自动重连

为了确保前端能够稳定地发送大消息(如超过 1MB 的字符串),我们可以将大消息分块,每次发送一个较小的块(如 128KB),并通过心跳机制保持连接的活跃性。如果连接断开,前端可以自动尝试重连。

前端代码:
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
<script src="https://cdn.jsdelivr.net/sockjs/1.5.1/sockjs.min.js"></script><script>// 启动 WebSocket 连接并启用心跳检测和自动重连function connect() {const socket = new SockJS('http://your-server-address/ws');const stompClient = Stomp.over(socket);// 启用心跳检测,每10秒发送/接收心跳stompClient.connect({}, function(frame) {console.log('Connected: ' + frame);}, function(error) {console.log('Connection lost, retrying...');setTimeout(connect, 5000);  // 5秒后自动重连}, {heartbeatIncoming: 10000,  // 每10秒接收心跳heartbeatOutgoing: 10000   // 每10秒发送心跳});// 分块发送大字符串function sendLargeData(stompClient, destination, message) {const chunkSize = 128 * 1024;  // 每块128KBlet offset = 0;// 分块发送消息while (offset < message.length) {const chunk = message.substring(offset, offset + chunkSize);stompClient.send(destination, {}, chunk);  // 发送每块数据offset += chunkSize;}}// 示例:模拟发送1MB以上的大消息const largeMessage = 'A'.repeat(1024 * 1024 + 100);  // 创建超过1MB的字符串sendLargeData(stompClient, "/app/destination", largeMessage);}// 启动连接connect();
</script>
2. 后端:Spring Boot WebSocket 和 STOMP 配置

在 Spring Boot 中,通过 WebSocket 和 STOMP 实现消息的接收和处理,并启用心跳检测,确保长时间保持连接。

后端配置(WebSocketConfig.java):
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
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", "/queue").setHeartbeatValue(new long[]{10000, 10000});  // 每10秒发送和接收心跳config.setApplicationDestinationPrefixes("/app");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {// 配置STOMP终端,允许跨域并启用SockJS支持registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();}@Overridepublic void configureWebSocketTransport(WebSocketTransportRegistration registration) {registration.setMessageSizeLimit(5 * 1024 * 1024);   // 设置最大消息大小为5MBregistration.setSendBufferSizeLimit(10 * 1024 * 1024); // 设置发送缓冲区为10MBregistration.setSendTimeLimit(20000);  // 设置发送时间限制为20秒}// 配置心跳调度器public TaskScheduler heartBeatScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(1);scheduler.setThreadNamePrefix("wss-heartbeat-thread-");scheduler.initialize();return scheduler;}
}
3. Tomcat 超时配置

确保 Tomcat 的连接超时时间大于心跳间隔时间,以防止连接过早断开。假设心跳间隔为 10 秒,我们可以将连接超时时间设置为 30 秒或更长。

application.properties 中配置:
# 设置Tomcat的连接超时时间为30秒
server.tomcat.connection-timeout=30000
server.xml 文件中配置(如果使用独立的 Tomcat):
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="30000"  <!-- 30秒超时 -->redirectPort="8443" />
4. 代理服务器(NGINX)配置

如果你使用 NGINX 作为代理服务器,确保 NGINX 的超时配置允许长时间的 WebSocket 连接。增加 proxy_read_timeoutproxy_send_timeout

NGINX 配置示例:
http {client_max_body_size 10M;  # 允许传输最大消息体10MBproxy_read_timeout 3600s;  # 允许长时间的连接读取proxy_send_timeout 3600s;  # 允许长时间的连接发送server {listen 80;location /ws {proxy_pass http://backend-server;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;}}
}
5. 处理大消息的性能优化

在处理大消息时,除了网络传输问题,后端的性能优化也很重要。确保处理长消息时,服务器有足够的资源处理高并发请求,可以通过调整线程池大小、增加内存等方式进行优化。

增加 Spring Boot 中线程池大小:
server.tomcat.max-threads=300  # 增加Tomcat最大线程数

总结

通过这个完整的方案,你可以通过 STOMP 协议的 WebSocket 实现长字符串(超过 1MB)的稳定传输。关键点包括:

  1. 前端分块传输:将大字符串分块传输,避免单次传输过大。
  2. 心跳检测:通过前后端心跳配置,保持连接的活跃性。
  3. Tomcat 超时配置:确保 Tomcat 的连接超时时间大于心跳间隔时间。
  4. 代理服务器配置:如果使用 NGINX,确保代理服务器允许长时间的 WebSocket 连接。
  5. 性能优化:通过配置合适的线程池和资源来确保高并发和大消息处理。

通过以上优化,能够确保 WebSocket 长时间稳定连接,并顺利处理大数据传输。

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

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

相关文章

NFT Insider #151:The Sandbox 推出 Alpha 第4季;腾讯或将收购育碧

市场数据 加密艺术及收藏品新闻 Beeple 将于 11 月在南京德基美术馆举办个人首展 著名数字艺术家 Beeple 近日在X平台发布视频&#xff0c;宣布将于 2024 年 11 月 14 日在南京德基美术馆举办个人首次展览&#xff0c;名为《Beeple&#xff1a;来自合成未来的故事》。该展览将…

Django的请求与响应

Django的请求与响应 1、常见的请求2、常见的响应3、案例 1、常见的请求 函数的参数request是一个对象&#xff0c;封装了用户发送过来的所有请求相关数据。 get请求一般用来请求获取数据&#xff0c;get请求也可以传参到后台&#xff0c;但是传递的参数显示在地址栏。 post请求…

[自然语言处理]RNN

1 传统RNN模型与LSTM import torch import torch.nn as nntorch.manual_seed(6)# todo:基础RNN模型 def dem01():参数1&#xff1a;input_size 每个词的词向量维度&#xff08;输入层神经元的个数&#xff09;参数2&#xff1a;hidden_size 隐藏层神经元的个数参数3&#xff1a…

Linux基础-正则表达式

正则表达式概述 正则表达式是处理字符串的一种工具&#xff0c;可以用于查找、删除、替换特定的字符串&#xff0c;主要用于文件内容的处理。与之不同的是&#xff0c;通配符则用于文件名称的匹配。正则表达式通过使用特殊符号&#xff0c;帮助用户轻松实现对文本的操作。 一…

Python网络爬虫快速入门指南

Python网络爬虫快速入门指南 网络爬虫&#xff0c;也称为网络蜘蛛&#xff0c;是一种自动访问互联网并提取信息的程序。Python因其简洁明了的语法和丰富的库支持&#xff0c;成为开发网络爬虫的理想选择。在这篇博客中&#xff0c;我们将探讨如何快速入门Python网络爬虫技术&a…

windows7 32bit安装JDK以及EclipseEE

如果你的电脑是 Windows 7 32-bit 系统&#xff0c;那么需要下载并安装适用于 32-bit 系统的 JDK 和 Eclipse EE。以下是具体的步骤和下载链接&#xff1a; 1. 下载并安装适用于 Windows 32-bit 的 JDK 1.1 下载适用于 32-bit 的 JDK Oracle 不再提供最新版本的 32-bit JDK&…

物联网:一种有能力重塑世界的技术

物联网&#xff08;IoT&#xff09;近年来对我们的日常生活产生了如此积极的影响&#xff0c;以至于即使是不懂技术的人也开始相信它所带来的便利以及敏锐的洞察力。 物联网是一场数字技术革命&#xff0c;其意义甚至比工业革命更为重大。物联网是仍处于起步阶段的第四次工业革…

前端开发笔记--html 黑马程序员2

文章目录 前端常用标签一、标题标签二、段落标签和换行标签和水平线标签三、文本格式化标签![请添加图片描述](https://i-blog.csdnimg.cn/direct/87583fa23fe04229b016912051f3fc45.png)四、盒子标签五、图像标签六、连接标签七、注释和特殊字符 八、表格标签的基本使用九、列…

原生 App 上架 Mac App Store 过程总结

随着 macOS 系统的普及&#xff0c;越来越多的开发者希望将他们的原生应用程序发布到 Mac App Store&#xff0c;以便触达更广泛的用户群体。在这篇文章中&#xff0c;我们将详细总结原生 App 上架 Mac App Store 的整个过程&#xff0c;包括必要的准备工作、开发流程、测试、申…

自动化运维:提升效率、降低风险的利器

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

如何批量从sql语句中提取表名

简介 使用的卢易表 的提取表名功能&#xff0c;可以从sql语句中批量提取表名。采用纯文本sql语法分析&#xff0c;无需连接数据库&#xff0c;支持从含非sql语句的文件文件中提取&#xff0c;支持各类数据库sql语法。 特点 快&#xff1a;从成百个文件中提取上千个表名只需1…

离岗睡岗预警系统 值班室离岗识别系统Python 结合 OpenCV 库

在众多工作场景中&#xff0c;存在着一些特殊岗位&#xff0c;这些岗位对于人员的专注度和警觉性有着极高的要求。然而&#xff0c;离岗睡岗现象却时有发生&#xff0c;给工作的正常开展和安全保障带来了严重的威胁。本文将深入探讨特殊岗位离岗睡岗的危害&#xff0c;以及如何…

Ubuntu安装Apache教程

系统版本&#xff1a;Ubuntu版本 23.04 Ubuntu是一款功能强大且用户友好的操作系统&#xff0c;而Apache是一款广泛使用的Web服务器软件。在Ubuntu上安装Apache可以帮助用户搭建自己的网站或者进行Web开发。为大家介绍如何在Ubuntu上安装Apache&#xff0c;并提供详细的教程和操…

Python 字典:解锁高效数据处理的秘密武器

引言 字典作为Python中一种内置的数据类型&#xff0c;以其灵活的数据存储能力和高效的查找性能而著称。无论是进行用户信息管理、缓存热数据还是构建复杂的算法模型&#xff0c;掌握字典的高级操作都是提升开发效率的关键所在。接下来&#xff0c;我们将从基础语法入手&#…

【HarmonyOS NEXT】实现页面水印功能

关键词&#xff1a;鸿蒙、水印、Watermark、页面、触摸问题 注&#xff1a;本期文章同样适用 OpenHarmony 的开发 在app开发过程中时常会出现敏感信息页面&#xff0c;为保护信息安全和及时的数据追踪&#xff0c;通常会采用给页面加水印的形式&#xff0c;那么本期文章会介绍…

【NLP自然语言处理】探索注意力机制:解锁深度学习的语言理解新篇章

目录 &#x1f354; 注意力机制介绍 1.1 注意力概念 1.2 注意力计算规则 1.3 常见的注意力计算规则 &#x1f354; 什么是注意力机制 &#x1f354; 注意力机制的作用 &#x1f354; 注意力机制实现步骤 4.1 步骤 4.2 代码实现 &#x1f354; 小结 学习目标 &#x1…

C++面试速通宝典——24

452. Linux进程地址空间 文本段&#xff1a;包含程序的可执行代码初始化数据段&#xff08;数据段&#xff09;&#xff1a;包含已初始化的全局变量和静态变量。未初始化数据段&#xff08;BSS段&#xff09;&#xff1a;包含未初始化的全局变量和静态变量。堆&#xff1a;动态…

计算机网络(十一) —— 数据链路层

目录 一&#xff0c;关于数据链路层 二&#xff0c;以太网协议 2.1 局域网 2.2 Mac地址 2.3 Mac帧报头 2.4 MTU 三&#xff0c;ARP协议 3.1 ARP是什么 3.2 ARP原理 3.3 ARP报头 3.4 模拟ARP过程 3.5 ARP周边问题 四&#xff0c;NAT技术 4.1 NAT技术背景 4.2 NAT转…

C++11--右值引用

1.引用 右值引用是在C11中所引进的&#xff0c;在前面&#xff0c;我们已经了解并使用过了引用&#xff0c;引用的作用就是给某一个变量取别名&#xff0c;但实际上&#xff0c;我们使用的引用是左值引用&#xff0c;而我们现在要了解的是与左值引用相对应的右值引用。 无论左…

vue 判断页面是否刷新-技巧

前端实现 方法一 在 App.vue 文件中缓存下刷新时当前页面的路由 created() {this.currentPathLoad(); }, methods: {currentPathLoad() {window.addEventListener("current-path-load",()>{let path this.$route.path;sessionStorage.setItem(current-path-lo…