Angular websocket代理在升级到websocket协议时失败

时间:2018-05-21 02:49:59

标签: angular websocket proxy angular-cli

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

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

我正在使用angular-cli和socket.io,启动我在端口3000上运行的API,然后使用“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'));
        });
    }
...
}

以下是我在客户端启动应用程序时发生的事情

enter image description here

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

enter image description here

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

1 个答案:

答案 0 :(得分:0)

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