websocket在vue项目和nginx中的代理配置

场景:

前端实现AB控的需求,一架无人机,在多个pc用户之间移交控制权,同一时间,只有一个用户拥有控制权。有控制权的用户可以选择用户移交控制权,没有控制权的用户可以申请控制权。这个过程中存在一个通信问题,如下:

代码:

javascript 复制代码
const initWebSocket = () => {
    console.log('初始化websocket连接---------------------------')
    if ('WebSocket' in window) {
      // websocket.value = new WebSocket("ws://192.168.144.61:18823/droneai/v1/api/websocket/role?userId=" + localStorage.getItem('userId'));
      websocket.value = new WebSocket("/web/websocket/role?userId=" + localStorage.getItem('userId'));
    } else {
      alert('当前浏览器 Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.value.onerror = function () {
      console.log("WebSocket连接发生错误");
    };
    //连接成功建立的回调方法
    websocket.value.onopen = function () {
      console.log("WebSocket连接成功");
    }
    //接收到消息的回调方法
    websocket.value.onmessage = function (event) {
      console.log("收到消息?????????????????????????:", event.data);
      let socketData = JSON.parse(event.data);
      // sseData.value = JSON.parse(event.data);
      let type = socketData.operationType;  //type 1:申请控制权 2:控制权移交
      let isNotice = socketData.isNotice;//isNotice 1:通知 
      console.log('socketData-----------------------------------------', socketData)
      console.log('isNotice-----------------------------------------', socketData.isNotice, isNotice, isNotice != '1')
      if (isNotice != '1') {
        //接收到推送,需要给服务端回应
        ElMessageBox.confirm(
          type == '1' ? '另一用户向你申请控制权,是否接受?' : '另一用户将控制权移交给你,是否接受?',
          '提示',
          {
            confirmButtonText: '接受',
            cancelButtonText: '取消',
            type: 'warning',
          }
        ).then(() => {
          // let params = {
          //   clientId: localStorage.getItem('userId'),
          //   type: status.value ? '2' : '1'
          // }
          confirmMessage(localStorage.getItem('userId')).then(res => {
            ElMessageBox.alert(
              type == '1' ? '控制权已被移交给另一用户' : '控制权已被移交给你',
              '通知',
              {
                // if you want to disable its autofocus
                // autofocus: false,
                confirmButtonText: '确认',
                callback: (action: Action) => {
                  //修改状态
                  status.value = !status.value;
                  localStorage.setItem('isControl', status.value ? '1' : '0')
                },
              })
          })
        })
          .catch(() => {
            ElMessage({
              type: 'info',
              message: '已取消',
            })
          })
      } else {
        //接收到推送,只是通知,前端需要手动改状态
        ElMessageBox.alert(
          socketData.isControl == '1' ? '控制权已被移交给你' : '控制权已被移交给另一用户',
          '通知',
          {
            // if you want to disable its autofocus
            // autofocus: false,
            confirmButtonText: '确认',
            callback: (action: Action) => {
              //修改状态
              status.value = socketData.isControl == '1' ? true : false
              localStorage.setItem('isControl', socketData.isControl)
            },
          })
      }
    }
    //连接关闭的回调方法
    websocket.value.onclose = function (event) {
      console.log("WebSocket连接关闭", event);
      // if(event.code != 1000){
      //   initWebSocket();
      // }
    }
  }

Vue的代理配置:

nginx代理配置:

javascript 复制代码
server {
       listen       443 ssl;
       server_name  localhost;

       ssl_certificate      D://nginx-1.26.1//ssl//test.crt;
       ssl_certificate_key  D://nginx-1.26.1//ssl//test.key;

       ssl_session_cache    shared:SSL:1m;
       ssl_session_timeout  5m;

       ssl_ciphers  HIGH:!aNULL:!MD5;
       ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }

    location / {
            root   html/dist;
			try_files $uri $uri/ /index.html;
            index  index.html index.htm;
        }
		location /api/ {
            proxy_pass http://192.168.144.61:18823/droneai/v1/api/;
        } 
        location /web/ {
            # 转发到后台真实 WebSocket 地址(注意路径拼接:后端基础地址 + /websocket/)
            proxy_pass http://192.168.144.61:18823/droneai/v1/api/;
            
            # 核心:启用 WebSocket 协议升级(缺一不可)
            proxy_http_version 1.1; # WebSocket 要求 HTTP/1.1
            proxy_set_header Upgrade $http_upgrade; # 告知 Nginx 升级为 WebSocket
            proxy_set_header Connection "upgrade"; # 标记为升级连接
            
            # 可选配置(优化稳定性和安全性)
            proxy_set_header Host $host; # 传递当前域名到后台
            proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端 IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_read_timeout 600s; # 延长超时时间(避免长时间无数据断开连接,根据需求调整)
            proxy_send_timeout 600s;
        }
    }
相关推荐
LuHang16 小时前
从天地图切换到高德地图:一次真实的底图迁移实战
前端·vue.js·cesium
枫叶轻语16 小时前
【Nginx 从入门到实战 07】root 与 alias:资源路径到底怎样对应?
nginx·全栈
ruanno_top20 小时前
Vue 3 后台权限路由:我漏掉了按钮级裁剪,还把 403 写成了 404
vue.js
acd1200920 小时前
Nginx 反向代理的缓冲区坑:后端响应大时接口偶发 502
java·运维·nginx
栉甜20 小时前
Vue2学习内容(上)
前端·javascript·vue.js·学习
Thanks_ks20 小时前
常见 HTTP 状态码的坑:301/302、401/403、500/502 之间差的那一个词
计算机网络·nginx·http·面试·状态码·后端开发·浏览器缓存
QianhangQianping1 天前
WebSocket实时推送+ HTTP 定时轮询:一块大屏两套取数怎么不打架
前端·websocket·网络协议·http·低代码·架构·数据可视化
小郎君6581 天前
(六)el-cascader 的展示值为什么不能直接 join:emitPath、路径还原与多选去重
vue.js·算法
用户093671755411 天前
用 4500 行 TypeScript 复刻了童年方格纸上的海战棋
前端·vue.js
行走的陀螺仪1 天前
Claude Code 从入门到实战(一):安装、登录与第一个Vue项目
前端·javascript·vue.js