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

苍穹外卖WebSocket连接问题

在调试过程中发现,当前端应用部署在Nginx下访问localhost时,WebSocket连接无法建立;而直接运行前端项目时则可以正常连接。通过浏览器F12排查问题后,发现是WebSocket的URL路径不同:我们实际需要的地址为ws://localhost/ws/,但Nginx转发的请求却指向了ws://localhost/,缺少了关键的/ws/路径前缀。为解决该问题,在Nginx配置文件中添加了相应的路径重写规则,于是在nginx.conf中配置以下代码:

# WebSocket location /ws/ { #proxy_pass http://localhost:8080/admin/; proxy_pass http://webservers/ws/; proxy_http_version 1.1; proxy_read_timeout 3600s; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "$connection_upgrade"; } ​ # WebSocket 没有 /ws 前缀 location ~ ^/([a-zA-Z0-9_-]{8,32})$ { proxy_pass http://webservers/ws/$1; proxy_http_version 1.1; proxy_read_timeout 3600s; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "$connection_upgrade"; }

调整配置后,Nginx能够正确地连接上WebSocket,但是请求却不是转发至/ws/路径,而是相当于重新转发至ws://localhost/,问题并没有被彻底解决。同时又发现新的问题:WebSocket连接成功建立后,当有订单到达时,有消息弹窗但是没有声音。在浏览器F12控制台中,发现了以下错误:

“Uncaught (in promise) NotAllowedError: play() failed because the user didn't interact with the document first.”

该错误源于现代浏览器的自动播放安全策略。浏览器要求用户必须先与页面进行交互(如点击、触摸等),才能允许音频或视频自动播放,以防止网站在用户未授权的情况下擅自播放媒体内容。

这个问题解决方案倒是相对简单:只需在页面上进行一次用户交互(例如点击任意区域),之后再触发消息弹窗时,音频即可正常播放。

回到websocket连接问题,在之前的Nginx配置中,使用正则表达式location ~ ^/([a-zA-Z0-9_-]{8,32})$可能会与其他路径产生冲突,因此需要从根源上解决问题。让我们到前端代码进行排查。前端项目路径为project-sky-admin-vue-ts\src\layout\components\Navbar\index.vue,其中webSocket方法的代码如下:

webSocket() { const that = this as any let clientId = Math.random().toString(36).substr(2) //let socketUrl = process.env.VUE_APP_SOCKET_URL + clientId // 使用硬编码的WebSocket URL let socketUrl = 'ws://localhost:8080/ws/' + clientId console.log(socketUrl, 'socketUrl') if (typeof WebSocket == 'undefined') { that.$notify({ title: '提示', message: '当前浏览器无法接收实时报警信息,请使用谷歌浏览器!', type: 'warning', duration: 0, }) } // ... 后续代码 }

通过测试发现,将 URL 硬编码为'ws://localhost:8080/ws/' + clientId后 WebSocket 能够正常连接,这表明问题出在process.env.VUE_APP_SOCKET_URL环境变量的取值上。尽管尝试了多种方法查找资料,依旧未能彻底解决环境变量配置不正确的问题。但至少目前功能可用。鉴于该问题依然存在,那就得请教一下各位了。

http://www.cnnetsun.cn/news/1337193.html

相关文章:

  • 游戏原画师福音:Kook Zimage真实幻想Turbo保姆级入门教程
  • 密码学数学基础 - 整数关系
  • 虚幻4网络通信必备:手把手教你用Va Rest插件对接SpringBoot后端
  • 金融问答合规最后窗口期:Dify 0.12+版本强制启用的3项新审计日志字段,错过将无法通过Q3银保监现场检查
  • WSL2后悔药教程:用export命令实现系统时光机(Ubuntu版)
  • 详解单链表(含链表的实现过程)
  • YOLO系列算法改进 | 主干改进篇 | 替换MobileViGv2可缩放图卷积网络 | 助力模型复杂场景下精细区分目标和理解空间关系 | CVPR 2024
  • 让照片活起来:Image-to-Video图像转视频生成器实战体验
  • Cosmos-Reason1-7B实战案例:教育AI助手解析物理实验视频并生成考题
  • Phi-3-vision-128k-instruct镜像免配置:Docker一键拉起+Chainlit前端自动对接
  • 2026企业级攻防实战全解析:从攻击链路到防御体系(附应急响应指南)
  • 基于STM32的NES游戏硬件扩展板设计
  • 电容感应式烙铁自动清洁器设计与实现
  • STM32F103C8循迹小车实战:IO口模式选择与PWM调参避坑指南
  • 【ROS2】从零开始构建你的第一个ROS2节点:基于RCLPY的实战指南
  • GD32VW553开发板I2C驱动SHT20温湿度传感器移植实战
  • 阿里云DataWorks:一站式大数据开发治理平台全景解析
  • Qwen2-VL-2B-Instruct在Unity游戏开发中的应用:智能NPC视觉感知系统
  • 3个强力方案解决Blender 3MF文件处理难题:Blender3mfFormat解决方案
  • Ubuntu服务器磁盘爆满?Ncdu命令行神器5分钟帮你找出空间黑洞
  • 从DAGGER到DAD:模仿学习中的数据聚合技术演进与最新应用案例
  • Python+Ollama构建本地AI文档分析流水线:从PDF智能解析到结构化Excel输出
  • ZYNQ SD卡驱动与FATFS文件系统实战:从硬件配置到数据读写
  • 重构C/C++开发效率:Red Panda Dev-CPP的技术突破与实践指南
  • HY-Motion 1.0部署指南:两种规格模型,如何根据显存选择?
  • 开箱即用:Hunyuan-MT 7B翻译镜像,原文输入→一键翻译→实时展示
  • Android逆向实战:用Frida-DexDump轻松脱壳(附详细命令解析)
  • Qwen3-14B部署避坑指南:vLLM日志分析、模型加载失败排查与修复方案
  • 梦幻动漫魔法工坊场景实战:一键生成洛丽塔风格壁纸
  • 特征提取新思路:为什么D2-Net在弱纹理场景下比传统方法更鲁棒?