websocket的使用

websocket的封装,面对后端为服务架构

// websocket.js
import Vue from 'vue';class WebSocketService {constructor() {this.socket = null;this.state = Vue.observable({isConnected: false,currentUrl: '',retries: 0,maxRetries: 5,reconnectInterval: 3000});this.timeoutId = null;this.onMessageCallback = null; // 用户自定义的 onmessage 处理函数this.onCloseCallback = null;   // 用户自定义的 onclose 处理函数}// 配置不同微服务的 WebSocket URLserviceUrls = {serviceA: 'ws://serviceA-url',serviceB: 'ws://serviceB-url',serviceC: 'ws://serviceC-url'};// 初始化 WebSocket 连接init(serviceName, onMessageCallback, onCloseCallback) {const url = this.serviceUrls[serviceName];if (!url) {console.error(`WebSocket URL for ${serviceName} is required`);return;}if (this.state.isConnected) {console.log('WebSocket already connected');return;}this.state.currentUrl = url;this.socket = new WebSocket(url);// 设置连接超时(10秒)this.timeoutId = setTimeout(() => {if (!this.state.isConnected) {this.close();console.warn('WebSocket connection timed out');}}, 10000);// 保存用户传递的回调函数this.onMessageCallback = onMessageCallback;this.onCloseCallback = onCloseCallback;// 监听 WebSocket 事件this.socket.onopen = () => {clearTimeout(this.timeoutId);this.state.isConnected = true;this.state.retries = 0;console.log('WebSocket connection opened');};this.socket.onmessage = (event) => {if (this.onMessageCallback) {this.onMessageCallback(event); // 调用自定义的消息处理函数} else {console.log('Message received:', event.data);}};this.socket.onerror = (error) => {console.error('WebSocket error:', error);this.reconnect(serviceName);};this.socket.onclose = () => {this.state.isConnected = false;console.log('WebSocket connection closed');if (this.onCloseCallback) {this.onCloseCallback(); // 调用自定义的关闭处理函数}this.reconnect(serviceName);};}// 发送消息sendMessage(message) {if (this.socket && this.socket.readyState === WebSocket.OPEN) {this.socket.send(message);} else {console.warn('WebSocket is not open');}}// 切换服务 URLchangeService(serviceName, onMessageCallback, onCloseCallback) {if (this.socket) {this.close();}this.init(serviceName, onMessageCallback, onCloseCallback);}// 关闭 WebSocket 连接close() {if (this.socket) {this.socket.close();}clearTimeout(this.timeoutId);}// 重连机制reconnect(serviceName) {if (this.state.retries < this.state.maxRetries) {this.state.retries += 1;console.log(`Attempting to reconnect... (${this.state.retries}/${this.state.maxRetries})`);setTimeout(() => this.init(serviceName, this.onMessageCallback, this.onCloseCallback), this.state.reconnectInterval);} else {console.error('Max retries reached, giving up on connection');}}get isConnected() {return this.state.isConnected;}get currentUrl() {return this.state.currentUrl;}
}// 创建单例
const webSocketService = new WebSocketService();export default {install(Vue) {Vue.prototype.$webSocket = webSocketService;}
};

使用示例

在组件中调用 init 方法时,可以传入自定义的 onmessageonclose 回调:

export default {mounted() {// 连接到 serviceA 的 WebSocket,并设置自定义的消息和关闭处理函数this.$webSocket.init('serviceA', this.handleMessage, this.handleClose);},methods: {handleMessage(event) {console.log('Custom message handler:', event.data);// 在这里处理接收到的消息},handleClose() {console.log('Custom close handler: WebSocket connection closed');// 在这里处理连接关闭后的操作},sendMessage() {this.$webSocket.sendMessage('Hello WebSocket');},changeToServiceB() {// 切换到 serviceB 的 WebSocket,并传递新的回调this.$webSocket.changeService('serviceB', this.handleMessage, this.handleClose);}},beforeDestroy() {this.$webSocket.close();}
};

这种方式使得前端在处理 onmessageonclose 时有更大的灵活性,可以根据实际需求自定义事件处理逻辑,而不是在插件内部固定处理。

使用场景

在 WebSocket 使用完之后就立即关闭,还是在页面离开时才关闭,取决于应用的具体需求。以下是两种情况的分析:

1. 使用完即关闭

  • 适用场景:WebSocket 仅在特定交互中需要,例如某个功能的实时数据流,在用户完成操作后就不再需要继续保持连接。
  • 优点:节省资源,因为 WebSocket 连接在不使用时即被关闭,避免了长时间空闲占用服务器连接。
  • 缺点:如果用户频繁进入和离开此功能模块,可能会多次重新连接,导致性能开销增大。

适合的应用场景:像股票行情、天气更新等功能,在用户切换页面或完成实时数据查询时,不再需要保持实时连接,使用完后立即关闭更为合理。

2. 页面离开时关闭

  • 适用场景:需要在整个页面会话中保持实时连接的数据,例如消息通知、实时聊天、后台数据监控等。
  • 优点:可以避免重复连接开销,用户在同一页面会话中始终保持实时数据的推送,提升用户体验。
  • 缺点:在页面空闲时仍然会占用连接资源,可能会影响性能,尤其是在大规模连接时。

适合的应用场景:例如聊天应用、实时监控平台等,页面保持实时更新更重要,用户在页面切换或关闭页面时才关闭连接更为合理。

综合建议

可以根据业务需求选择合适的方式,或结合两者,例如:

  • 按模块保持连接:在模块页面生命周期内保持连接,用户离开模块或页面时关闭 WebSocket。
  • 自动超时关闭:在 WebSocket 长时间未使用时,自动关闭以节省资源,并在需要时重新连接。

这种方式兼顾了资源使用和性能,且不影响用户体验。

ngixn做处理

Nginx 可以一定程度上控制 WebSocket 连接的生命周期,但它的控制范围较为有限。主要可以通过设置超时、连接数限制等方式来管理 WebSocket,但无法直接在前端实现“使用完即关闭”这样的逻辑。以下是 Nginx 在 WebSocket 控制方面的可行方式:

1. 超时设置

Nginx 提供超时配置,可以设置 WebSocket 在空闲一定时间后自动断开。常用的超时设置有:

  • proxy_read_timeout:指定 Nginx 在等待后端响应的最大时间。如果后端在指定时间内没有数据传输,Nginx 将关闭连接。
  • proxy_send_timeout:指定 Nginx 向后端发送请求的超时时间,类似地,如果超时则关闭连接。
  • proxy_connect_timeout:用于连接后端服务器的超时时间,如果连接超时则关闭连接。
location /websocket/ {proxy_pass http://backend_server;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";# 设置超时proxy_read_timeout 60s;      # 60秒内无数据传输则关闭proxy_send_timeout 60s;proxy_connect_timeout 10s;
}

这种超时机制适合控制空闲连接,但如果连接始终有数据传输,这些超时设置不会主动关闭 WebSocket。

2. 限制 WebSocket 连接数

可以通过 Nginx 限制每个客户端的最大连接数,避免同一个用户产生过多的 WebSocket 连接:

http {# 定义一个限制连接的 zonelimit_conn_zone $binary_remote_addr zone=ws_limit:10m;server {location /websocket/ {limit_conn ws_limit 10;  # 每个客户端的最大连接数为 10proxy_pass http://backend_server;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";}}
}

这可以有效防止单个用户产生大量连接,导致服务器资源浪费。

3. Nginx 配合应用层的自动断开策略

Nginx 还可以结合应用层设置,比如:

  • 当连接空闲或达到指定的业务条件时,前端可以通过应用逻辑通知后端关闭 WebSocket,Nginx 通过 proxy_read_timeout 触发连接超时来响应关闭。
  • 或者应用层后端可以根据业务需求实现连接管理,Nginx 负责保持连接代理。应用主动断开后,Nginx 也会相应地释放 WebSocket。

总结

Nginx 可以通过超时和连接数限制等措施控制 WebSocket 的资源使用,但它的控制相对被动。如果需要业务逻辑来判断关闭 WebSocket,还是需要在应用层处理。

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

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

相关文章

一分钟学会Python基础

Python 是一种广泛使用的高级编程语言&#xff0c;因其简洁和易读的语法而受到欢迎。下面是一些 Python 基础知识的概述&#xff1a; 1. 安装 Python 1.下载: 你可以从 Python 官网 下载适合你操作系统的版本。 2.安装: 安装过程中&#xff0c;确保勾选 "Add Python to …

vue下载安装

目录 vue工具前置要求&#xff1a;安装node.js并配置好国内镜像源下载安装 vue 工具 系统&#xff1a;Windows 11 前置要求&#xff1a;安装node.js并配置好国内镜像源 参考&#xff1a;本人写的《node.js下载、安装、设置国内镜像源&#xff08;永久&#xff09;&#xff…

ASP.NET Core 应用程序的Startup笔记

在 ASP.NET Core 中&#xff0c;Startup 类是用于配置应用程序的服务和请求管道的地方。 默认情况下&#xff0c;Visual Studio 2022 创建的 ASP.NET Core Web API 项目可能不再包含 Startup 类&#xff0c;而是直接在 Program.cs 中进行配置。这是因为从 .NET 6 开始&#xf…

计算机毕业设计——ssm基于Java的酒店管理系统的设计与实现演示录像2021

作者&#xff1a;程序媛9688开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等。 &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff08;免费咨询指导选题&#xff09;&#xff0…

Spring整合Mybatis过程

配置文件 springConfig --> [jdbcConfig mybatisConfig] jdbc配置文件进行基本的数据库连接池配置 mybatis配置文件进行SqlSessionFactory Bean 和 MapperScannerConfigurer Bean的创建 在Spring容器启动时&#xff0c;系统会根据配置创建并初始化所有MyBatis所需的Bean…

光纤中光的散射

什么现象是光的散射&#xff1f; 辐射在不均匀介质中传播时&#xff0c;会产生偏离光的入射方向的光。 背向散射光分为哪些&#xff1f; 瑞利散射、布里渊散射和拉曼散射。 瑞利散射的原理是&#xff1f; 瑞利散射是由微粒的弹性碰撞而产生的&#xff0c;所以散射前后光波…

Java Executor ScheduledFuture 源码

前言 相关系列 《Java & Executor & 目录》《Java & Executor & ScheduledFuture & 源码》《Java & Executor & ScheduledFuture & 总结》《Java & Executor & ScheduledFuture & 问题》 涉及内容 《Java & Executor &…

Kafka 客户端工具使用分享【offsetexplorer】

前言&#xff1a; 前面我们使用 Spring Boot 继承 Kafka 完成了消息发送&#xff0c;有朋友会问 Kafka 有没有好用的客户端工具&#xff0c;RabbitMQ、RocketMQ 都有自己的管理端&#xff0c;那 Kafka 如何去查看发送出去的消息呢&#xff1f; 本篇我们就来分享一个好用的工具…

远程控制项目第一天

使用C开发&#xff0c;git进行版本控制&#xff0c; 关于远程项目的思考 需求分析 文件需求 1.观察文件 2.打开文件 3.下载文件 4.删除文件 观察需求 1.远程监控 控制需求 1.鼠标控制 2.键盘控制 3.锁机/解锁 技术分析 服务器部署在被控端 网络编程 文件处理 鼠标处理 图像处…

antd 5X中 tree属性结构,自定义菜单,右键菜单实现方式

第一种方式 使用自定义渲染节点 titleRender <TreetitleRender{titleRender}autoExpandParent{autoExpandParent}fieldNames{fieldNames}treeData{treeData}></Tree> 重要代码 titleRender实现方式 const menu (<Menuitems{[{key: add,label: <span>新增…

flume系列之:flume机器做条带划分提高磁盘性能和吞吐量的详细步骤

flume系列之:flume机器做条带划分提高磁盘性能和吞吐量的详细步骤 磁盘条带划分新磁盘直接条带划分步骤有数据的磁盘做条带划分步骤磁盘条带划分 磁盘条带划分是将一个文件或数据块分散存储在多个物理磁盘上的技术。它可以提高磁盘的性能和吞吐量。以下是磁盘做了条带划分后可…

六、栈————相关算法探讨(持续更新中)

栈————相关算法探讨 前言一、有效的括号1.1 思路分析1.2 解法探讨1.2.1 一次 for 循环&#xff0c;左括号入栈1.2.2 一次 for 循环&#xff0c;左括号入栈&#xff08;使用字典&#xff09;1.2.3 一次 for 循环&#xff0c;右括号进栈1.2.4 一次 for 循环&#xff0c;右括号…

【日常记录-Java】Windows下查看Java进程完整的启动命令

1. 简介 jps是Java Virtual Machine Process Status Tool的缩写&#xff0c;其会列出所有正在运行的Java进程ID以及类名。 wmic是Windows Management Instrumentation Command-line的缩写&#xff0c;其允许用户与wmi服务进行交互&#xff0c;提供了一种标准化的方法来访问和操…

ctfshow(151->154)--文件上传漏洞--.user.ini

Web151 进入界面&#xff1a; 审计&#xff1a; 提示是前台校验。 存在图片上传。 思路&#xff1a; 先编写一个一句话木马文件&#xff1a; //shell.php <?php eval($_POST[1]); ?>既然是前端校验&#xff0c;我们查看页面源代码找到相关的校验内容&#xff1a…

Ubuntu使用Tesla P4配置Anaconda+CUDA+PyTorch

我们之前测试了在Windows系统如何安装Tesla M4&#xff08;成了&#xff01;Tesla M4Windows 10AnacondaCUDA 11.8cuDNNPython 3.11&#xff09;&#xff0c;前面安装好了Ubuntu 22.04.4的操作系统&#xff08;Ubuntu 22.04.4安装Docker引擎&#xff09;。今天&#xff0c;简单…

少儿编程参培意愿地图:一二线城市热情高涨,低线城市市场待挖掘

随着少儿编程的普及&#xff0c;编程教育逐渐走进越来越多家庭。然而&#xff0c;少儿编程的地域分布显示出明显的差异&#xff1a;在一二线城市中&#xff0c;家长对少儿编程的接受度和参与度显著高于低线城市。本文将通过对地域分布和家长态度的分析&#xff0c;探讨少儿编程…

基于SSM演出道具租赁系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;道具类型管理&#xff0c;道具出租管理&#xff0c;租赁订单管理&#xff0c;道具归还管理&#xff0c;系统管理 商家账号功能包括&#xff1a;系统首页&…

【Spring】Spring 核心和设计思想

Spring 核心和设计思想 1.什么是 Spring1.1 传统程序开发1.2 控制反转程序开发 2.理解 Spring IoC 1.什么是 Spring 我们通常所说的 Spring 指的是 Spring Framework&#xff08;Spring 框架&#xff09;&#xff0c;它是⼀个开源框架&#xff0c;有着活跃而庞大的社区&#x…

【Java】-- 内部类

文章目录 1. 静态内部类&#xff08;重要&#xff09;2. 实例内部类&#xff08;重要&#xff09;3. 局部内部类&#xff08;很少用&#xff09;4. 匿名内部类&#xff08;使用较多&#xff09;4.1 第一种写法&#xff08;类&#xff09;4.1 第二种写法&#xff08;接口) 当一个…

【C语言学习笔记】

C语言发展史&#xff1a; 1960 原型A语言->ALGOL语言 1963 CPL语言1967 BCPL1970 B语言1973 C语言 C语言特点&#xff1a; 基础性语言语法简洁 紧凑 方便 灵活(得益于指针)运算符 数据结构丰富结构化 模块化编程移植性好 执行效率…