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.rhkb.cn/news/461318.html

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

相关文章

入门 | Kafka数据使用vector消费到Loki中使用grafana展示

一、Loki的基本介绍 1、基本介绍 Loki 是由 Grafana Labs 开发的一款水平可扩展、高性价比的日志聚合系统。它的设计初衷是为了有效地处理和存储大量的日志数据&#xff0c;与 Grafana 生态系统紧密集成&#xff0c;方便用户在 Grafana 中对日志进行查询和可视化操作。 从架构…

Golang | Leetcode Golang题解之第515题在每个树行中找最大值

题目&#xff1a; 题解&#xff1a; func largestValues(root *TreeNode) (ans []int) {if root nil {return}q : []*TreeNode{root}for len(q) > 0 {maxVal : math.MinInt32tmp : qq nilfor _, node : range tmp {maxVal max(maxVal, node.Val)if node.Left ! nil {q …

Vue3的router和Vuex的学习笔记整理

一、路由的基本搭建 1、安装 npm install vue-router --registryhttps://registry.npmmirror.com 2、配置路由模块 第一步&#xff1a;src/router/index.js创建文件 第二步&#xff1a;在src/view下面创建两个vue文件&#xff0c;一个叫Home.vue和About.vue 第三步&#x…

vue插件清除 所有console.log()

一、作用 1、提升性能console.log() 语句会消耗一定的性能&#xff0c;尤其是在频繁调用的情况下。在生产环境中移除这些语句可以提高应用的运行效率。 2、减少信息泄露console.log() 可以输出敏感信息&#xff08;如用户数据、API 响应等&#xff09;。在生产环境中&#xf…

vue项目中如何在路由变化时增加一个进度条

在 Vue.js 项目中&#xff0c;使用路由&#xff08;如 Vue Router&#xff09;时&#xff0c;为了提升用户体验&#xff0c;你可能会想要在路由变化时显示一个进度条。这可以通过多种方式实现&#xff0c;其中一种流行的做法是使用第三方库&#xff0c;如 vue-loading-bar 或 n…

python 模块和包、类和对象

模块 模块是包含 Python 代码的文件&#xff0c;通常用于组织相关的函数、类和其他语句。模块可以被导入并在其他 Python 文件中使用。 创建模块 假设你创建了一个名为 mymodule.py 的文件&#xff0c;内容如下&#xff1a; # mymodule.pydef greet(name): return f"…

图书管理系统汇报

【1A536】图书管理系统汇报 项目介绍1.用户登录注册功能1. 1用户角色管理2.图书管理功能2.1 添加图书2.2 编辑图书2.3 删除图书 3.图书搜索和筛选3.1 图书搜索3.2 图书筛选 4.图书借阅、图书归还4.1 图书借阅4.2 图书归还 5.用户信息管理5.1上传头像5.2修改头像5.3 修改密码 项…

执行Django项目的数据库迁移命令时报错:(1050, “Table ‘django_session‘ already exists“);如何破?

一、问题描述&#xff1a; 当我们写Django时&#xff0c;由于自己的操作不当&#xff0c;导致执行数据库迁移命令时报错&#xff0c;报错的种类有很多&#xff0c;例如&#xff1a; 迁移文件冲突&#xff1a;可能你有多个迁移文件试图创建同一个表。数据库状态与迁移文件不同…

蓝牙BLE开发——红米手机无法搜索蓝牙设备?

解决 红米手机&#xff0c;无法搜索附近蓝牙设备 具体型号当时忘记查看了&#xff0c;如果你遇到有以下选项&#xff0c;记得打开~ 设置权限

java设计模式之创建者模式(5种)

设计模式 软件设计模式&#xff0c;又称为设计模式&#xff0c;是一套被反复利用&#xff0c;代码设计经验的总结&#xff0c;他是在软件设计过程中的一些不断发生的问题&#xff0c;以及该问题的解决方案。 **创建者模式又分为以下五个模式&#xff1a;**用来描述怎么“将对象…

SpringSecurity框架(入门)

简介&#xff1a; Spring Security 是一个用于构建安全的 Java 应用程序的框架&#xff0c;尤其适用于基于Spring的应用程序。它提供了全面的安全控制&#xff0c;从认证&#xff08;Authentication&#xff09;到授权&#xff08;Authorization&#xff09;&#xff0c;以及…

广东网站设计提升你网站在搜索引擎中的排名

在当今网络盛行的时代&#xff0c;拥有一个设计优良的网站&#xff0c;对企业的在线发展至关重要。特别是对于广东地区的企业来说&#xff0c;网站设计不仅仅是美观的问题&#xff0c;更直接影响着搜索引擎中的排名。因此&#xff0c;精心策划和设计的网站&#xff0c;能够显著…

Cuebric:用AI重新定义3D创作的未来

一、简介 Cuebric 是一家成立于2022年夏天的好莱坞创新公司,致力于为电影、电视、游戏和时尚等行业提供先进的AI多模态SaaS平台。自2024年1月正式推出以来,Cuebric 已经在市场上获得了广泛的认可和积极的反馈。目前,该平台正处于1.0版本的beta测试阶段,已募集约50万美元的…

计算机的错误计算(一百四十)

摘要 探讨 MATLAB 中函数 的计算精度。 从计算机的错误计算&#xff08;一百三十九&#xff09;知&#xff0c;对于对数运算&#xff0c;当真数在 1 附近时&#xff0c;计算机的输出会出现较大误差。为此&#xff0c;IEEE 754-2019 中专门定义有函数 其目的就是当自变量在 …

《Python游戏编程入门》注-第4章2

《Python游戏编程入门》的“4.2.2 键盘事件”中介绍了通过键盘事件来监听键盘按键的方法。 1 键盘事件 玩家点击键盘中某个按键实际上包含了两个动作&#xff1a;点击按键和释放按键&#xff0c;也就是按键按下和松开。按键按下的对应的事件是KEYDOWN&#xff0c;按键松开对应…

《高频电子线路》 —— 高频谐振功放(2)

动态特性与负载特性 动态特性 静态特性是指&#xff0c;不考虑负载阻抗的时候获得的&#xff0c;即转移特性曲线和输出特性曲线。 考虑负载时&#xff0c;电流变化的时候&#xff0c;负载上的电压就会变化&#xff0c;管子上面的Vce也会变化。 考虑负载的反作用后&#xff0c…

SpringBoot 下的Excel文件损坏与内容乱码问题

序言 随着打包部署的方式的改变&#xff0c;原本正常运行的代码可能带来一些新的问题&#xff0c;比如我们现在使用SpringBoot 的方式生成Jar包直接运行&#xff0c;就会对我们再在Resource下的Excel文件产生影响&#xff0c;导入与预期不符的情况发生cuiyaonan2000163.com 比…

「Mac畅玩鸿蒙与硬件12」鸿蒙UI组件篇2 - Image组件的使用

在鸿蒙应用开发中,Image 组件用于加载和显示图片资源,并提供多种属性来控制图片的显示效果和适配方式。本篇将带你学习如何在鸿蒙应用中加载本地和远程图片、设置图片样式以及实现简单的图片轮播功能。 关键词 Image 组件图片加载本地资源远程图片图片轮播一、Image 组件基础…

上海亚商投顾:沪指缩量调整 华为概念股午后爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 市场全天震荡调整&#xff0c;沪指、深成指午后跌超1%&#xff0c;创业板指一度跌逾2%&#xff0c;尾盘跌幅有…

vim命令及shell命令

目录 vim命令 vim三种工作模式 光标的跳转 复制粘贴 剪切删除 撤销回滚替换 翻页 其他 shell编程命令 判断用户的参数 可用的整数比较运算符 常见的字符串比较运算符 if条件测试语句 for条件循环语句 vim命令 vim三种工作模式 Vim编辑器中设置了三种模式: 命令…