【问题标题】:Angular websocket proxy failing on upgrade to websocket protocolAngular websocket 代理在升级到 websocket 协议时失败
【发布时间】:2018-10-30 16:01:18
【问题描述】:

我的 Angular 聊天应用程序在端口 4200 上提供服务,我的后端 API(同时提供 REST 和 websocket 流量)在端口 3000 上运行。

为避免弄乱 CORS 问题,我通过端口 4200 代理所有内容,并为我的所有 REST API 调用使用路径 /api。此 REST API 代理运行良好。 websocket 代理 几乎 工作正常,但我很确定它在尝试“升级”到 WS 时失败了,在阅读了网络上的所有内容以及关于这个主题的所有内容之后,我仍然卡住了。

我正在使用 angular-cli 和 socket.io,启动我的 API 在端口 3000 上运行,然后使用“ng serve --proxy-config proxy.conf.json”启动我的应用程序(this SO post 帮助了我一开始就很多)...

这是我的 proxy.conf.json:

{
    "/api/*": {
      "target": "http://localhost:3000",
      "secure": false,
      "logLevel": "debug",
      "changeOrigin": true
    },
    "/sock/*": {
      "target": "http://localhost:3000/socket.io/",
      "secure": false,
      "logLevel": "debug",
      "ws": true,
      "changeOrigin": true
    }
}

相关的客户端代码驻留在一个角度服务中,我在构造函数中创建一个 websocket 以便客户端与后端对话

const SERVER_URL = 'http://localhost:4200';

@Injectable()
export class WebSocketService {
    private socket;

    constructor() {
        console.log(`WebSocketService: initializing (URL ${SERVER_URL})`);
        this.socket = socketIo(SERVER_URL, {
            path: '/sock',
            autoConnect: true,
            transportOptions: {
              polling: {
                extraHeaders: {
                  'Authorization': 'Bearer abc'
                }
              }
            }
        });
    }
...
}

这是我在服务器端所做的事情

import * as socketIo from 'socket.io';

export default class WebSocketServer {
    private server: Server;
    private io: SocketIO.Server;

    constructor(server: Server) {
        this.server = server; 
        this.io = socketIo(this.server,{ 
          serveClient: false, 
          pingInterval: 10000, 
          pingTimeout: 5000, 
          cookie: false 
        });
        this.io.use((socket, next) => {
          let header = socket.handshake.headers['authorization'];
          console.log(`WebSocketServer: socket ${socket.id}, auth: ${header}`);
          if (true) {
            return next();
          }
          //return next(new Error('authentication error'));
        });
    }
...
}

当我在客户端启动应用程序时会发生以下情况

在服务器端,对端口 3000 的代理显然适用于 websocket 协议的长轮询部分,但是在它尝试升级后失败并回退到长轮询......(我认为升级尝试以下是导致上述错误消息的原因):

我认为这里的问题是我的代理配置没有正确处理 websocket 协议中的“升级”消息,但我不完全确定。

【问题讨论】:

  • 您能否在线检查(例如使用 Wireshark)Angular CLI 代理是否将“升级”标头转发到您的服务器?我遇到了类似的情况,在我这边,我可以看到“升级”标头被丢弃,导致服务器拒绝连接尝试。
  • 马克-克里斯蒂安,你说得对,就是这么回事!

标签: angular websocket proxy angular-cli


【解决方案1】:

感谢 Marc-Christian,他发现了转发无法正常工作的原因。我最终通过做两件事来解决这个问题:1)将 websocket 流量中断到不同的端口(8080),2)将 socket.io 中的路径和 proxy.conf.json 中的转发路径更改为“mysock”(不确定两者是否都需要)。

【讨论】:

    猜你喜欢
    • 2017-01-19
    • 2018-11-26
    • 1970-01-01
    • 2020-10-27
    • 2016-11-07
    • 2018-11-29
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多