【发布时间】: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