最近进行项目开发,遇到需要代理 WebSocket视频流 的需求,记录一下配置过程。

1. Vue 开发环境配置代理

vue.config.jsdevServer.proxy 中增加 WebSocket 的代理配置:

1
2
3
4
5
6
7
8
'/video': {
target: "ws://localhost:8889", // WebSocket 服务地址
changeOrigin: true,
ws: true, // 开启 WebSocket 代理
pathRewrite: {
'^/video': '' // 将请求路径中的 /video 去掉
}
}

2. 前端 WebSocket 连接写法

在 Vue 中初始化 WebSocket 连接时,URI 必须这样写:

1
const socket = new WebSocket('ws://' + location.host + '/video/websocket/' + id);

注意事项

  1. 必须加上 ws:// 前缀
    WebSocket 协议需要明确写 ws://(或者 wss:// 用于 HTTPS)。

  2. 前缀必须是 location.host

    • 表示 WebSocket 访问的当前前端项目地址。

    • 不能直接写代理 key 值 /video 或后端端口。

  3. location.host 后面跟代理 key 值

    • 与代理配置中的 /video 保持一致。
  4. 剩余部分拼接后端 API 的具体路径

    • 例如 /video/websocket/{id}

3. Nginx 配置 WebSocket 反向代理

Nginx 中,WebSocket 的代理配置与普通 HTTP 不同:

  • proxy_pass 必须写 http://,而不是 ws://

  • 需要手动加上 WebSocket 升级头。

配置示例

1
2
3
4
5
6
7
8
location ^~ /video/ {
proxy_pass http://127.0.0.1:8889/;

proxy_http_version 1.1; # 强制 HTTP/1.1 才支持 Upgrade
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}

关键点说明

  1. proxy_pass http://127.0.0.1:8889/;

    • 不需要 ws://,因为 WebSocket 是基于 HTTP 协议升级的。

    • 正确写法就是 http://

  2. proxy_http_version 1.1

    • 默认 HTTP/1.0,不支持协议升级,必须显式声明 HTTP/1.1。
  3. proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";

    • 这两行是 WebSocket 握手的关键,缺少就会导致连接失败。

总结

  • Vue 开发环境中,需要在代理配置里启用 ws: true

  • 前端 WebSocket 连接必须写完整:ws:// + location.host + /代理key + /后端路径

  • Nginx 转发 WebSocket 时,proxy_passhttp://,并加上 Upgrade 头。

这样配置后,前端通过 代理 访问 WebSocket,就能正常握手并通信。