웹사이트 검색

node.js - express로 부트스트랩할 때 NestJS에서 WebSockets 핸드셰이크가 작동하지 않음 (여러 서버)


우리의 NestJs 서버는 HTTP를 통해 웹소켓 핸드셰이크를 완벽하게 처리하곤 했습니다. 하지만 그 후 HTTPS 지원을 추가했고, 여기서 설명된 것처럼 여러 서버 기술을 사용하여 구현했습니다: https://docs.nestjs.com/faq/multiple-servers

그렇게 한 후에, 웹소켓 핸드셰이크(업그레이드 요청)가 작동을 멈췄습니다.

웹 소켓이 작동하는 우리가 가지고 있던 NestJs 부트스트래핑은 다음과 같았습니다:

const app = await NestFactory.create(AppModule);
const webSocketAdapter = new WebSocketAdapter(app);
app.useWebSocketAdapter(webSocketAdapter);

[...] // We initialize express sessions and passport here.

await app.init();
await app.listen(80);

동시에 HTTP와 HTTPS를 지원하기 위해, 우리는 https://docs.nestjs.com/faq/multiple-servers 에 안내된 지침을 따라 부트스트래핑을 다음과 같이 변경했습니다:

const server = express();
const app = await NestFactory.create(AppModule, new ExpressAdapter(server));
const webSocketAdapter = new WebSocketAdapter(app);
app.useWebSocketAdapter(webSocketAdapter);

[...] // We initialize express sessions and passport here.

await app.init();

http.createServer(server).listen(80);
const httpsConfiguration = [...] // Nothing meaningful here. We load PEM files and put them in there.
https.createServer(httpsConfiguration, server).listen(443);

그 변경 이후로, 우리 웹 소켓이 작동을 멈췄습니다. WebSocketAdapter에서 verifyClient() 함수가 호출되는지 확인했습니다. 더 이상 호출되지 않습니다. 따라서 NestJs가 더 이상 요청을 웹소켓 업그레이드 요청으로 처리하지 않는 것 같습니다.

브라우저에서 콘솔은 다음 오류 메시지를 표시합니다:

myScript.js:123 WebSocket connection to 'ws://localhost/api/v1/mysubpath' failed: Error during WebSocket handshake: Unexpected response code: 200

저는 NestJs 코드에서 추적하면서 무엇이 잘못되고 있는지 알아내려고 노력하고 있었지만, 전혀 쉬운 일이 아닙니다.

웹소켓이 더 이상 작동하지 않는 이유에 대해 아는 사람이 있나요?

편집 :

더 조사해본 결과, Nest 애플리케이션이 Express 어댑터로 초기화될 때 Nest 애플리케이션을 제공하면 WsAdapter가 웹소켓 서버를 제대로 초기화할 수 없는 것 같습니다. 그래서 대신 WebSocket 어댑터에 http 서버 인스턴스를 제공합니다.

하지만, 우리는 동시에 HTTP와 HTTPS에서 웹소켓을 제공할 수 없는 문제에 갇히게 됩니다. 웹소켓 어댑터에는 하나의 서버만 제공할 수 있고, 하나의 웹소켓 어댑터만 네스트 애플리케이션에 제공될 수 있습니다. 그래서 우리는 어댑터나 네스트 애플리케이션이 HTTP와 HTTPS 모두에서 동시에 웹소켓을 지원하도록 만드는 방법을 찾을 수 없었습니다.

우리의 코드는 이제 이렇게 보입니다:

const server = express();
const app = await NestFactory.create(AppModule, new ExpressAdapter(server));

const httpServer = http.createServer(server);
const httpsConfiguration = [...]
const httpsServer = https.createServer(httpsConfiguration, server)

const webSocketAdapter = new WebSocketAdapter(httpServer); // Here we can only supply one server. 
app.useWebSocketAdapter(webSocketAdapter); // Here we can only supply one adapter.

[...] // We initialize express sessions and passport here.

await app.init();

httpServer.listen(80);
httpsServer.listen(443);