격은 일 재현
nestjs로 서버를 구현하고 ec2에서 도메인을 통한 https통신을 하고 있는 서버가 있습니다.
ngnix를 통해 ssl 인증을 지원하도록 설정을 하였습니다
아래는 서버 업데이트를 하면서 api가 대폭 변동하였는데 전에 있는 api도 지원은 해줘야 해서 '/v2'(임시)로 분기 처리하였습니다.
server {
listen 80;
server_name open-ai-catbow.store www.open-ai-catbow.store;
charset utf-8;
location / {
if ($bad_ip) {
return 444;
}
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name open-ai-catbow.store www.open-ai-catbow.store;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/open-ai-catbow.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/open-ai-catbow.store/privkey.pem;
location /v2 {
if ($bad_ip) {
return 444;
}
proxy_pass http://127.0.0.1:4000;
}
location / {
if ($bad_ip) {
return 444;
}
proxy_pass http://127.0.0.1:3000;
}
}
nestjs에서 아래와 같은 간단한 소켓 서버를 구현했습니다.
@WebSocketGateway({
cors: {
origin: '*',
},
namespace: /\/family-.+/,
})
export class EventsGateway {
constructor(
@Inject(forwardRef(() => TodoService))
private readonly todoService: TodoService,
) {}
@WebSocketServer()
server: Server;
@SubscribeMessage('login')
handleLogin(
@MessageBody() data: { userId: number },
@ConnectedSocket() socket: Socket,
) {
const namespace = socket.nsp;
socket.join(`${data.userId}`);
namespace.emit('login', `hello i am ${data.userId}`);
}
@SubscribeMessage('todo')
async handleTodo(
@MessageBody() data: { userId: number },
@ConnectedSocket() socket: Socket,
) {
// 당사자한테 todo 보내주기
const todo = await this.todoService.getTodayTodoList(data.userId);
socket.in(`${data.userId}`).emit('todo', todo);
}
@SubscribeMessage('calendar')
async handleCalendar(@ConnectedSocket() socket: Socket) {
const namespace = socket.nsp;
namespace.emit('calendar', 'update calendar');
}
@SubscribeMessage('picture-diary')
async handlePictureDiary(@ConnectedSocket() socket: Socket) {
const namespace = socket.nsp;
namespace.emit('picture-diary', 'update picture-diary');
}
@SubscribeMessage('disconnect')
handleDisconnect(@ConnectedSocket() socket: Socket) {
const namespace = socket.nsp;
const disconnectedSocketId = socket.id;
// 연결 해제된 소켓 정보를 다른 사용자에게 알리기
namespace.emit('user-disconnected', disconnectedSocketId);
}
}
로컬에서는 잘 작동이 되었는데 도메인을 통한 https 통신을하면 404에러가 뜨면서 안되는 현상을 겪었습니다.
해결 책
결론이 뭐냐면 http_version을 명시하고 header에 3가지를 추가해 줘야한다 합니다. ( 핵심 부분 복사하였습니다.)
NGINX supports WebSocket by allowing a tunnel to be set up between a client and a backend server. For NGINX to send the Upgrade request from the client to the backend server, the Upgrade and Connection headers must be set explicitly, as in this example:
location /wsapp/ {
proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
Once this is done, NGINX deals with this as a WebSocket connection.
위처럼 4개의 옵션을 놓고 '/wsaap/' 부분을 url과 맞춰줘야합니다
location /socket.io {
if ($bad_ip) {
return 444;
}
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
nestjs 'WebSocketGateway'로 소켓 서버를 열면 주소에 'socket.io'가 붙습니다. !!
여기까지 도달하기에 무려 3시간걸렸는데, 다른언어와 프레임워크 예제만 보다보니 눈치를 못채고 있었는데,
머리 식히고 Handshake details을 보고 아 이거구나 .. 하고 발견했습니다.
총 NGNIX 세팅
server {
listen 80;
server_name open-ai-catbow.store www.open-ai-catbow.store;
charset utf-8;
location / {
if ($bad_ip) {
return 444;
}
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name open-ai-catbow.store www.open-ai-catbow.store;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/open-ai-catbow.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/open-ai-catbow.store/privkey.pem;
location /v2 {
if ($bad_ip) {
return 444;
}
proxy_pass http://127.0.0.1:4000;
}
location /socket.io {
if ($bad_ip) {
return 444;
}
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
location / {
if ($bad_ip) {
return 444;
}
proxy_pass http://127.0.0.1:3000;
}
}
'nestjs' 카테고리의 다른 글
Server-Sent Events(SSE) in nestjs (0) | 2023.10.15 |
---|---|
open-ai chat-gpt streaming 통신 기록 (0) | 2023.10.14 |
Nestjs 테스트코드 + Github action으로 EC2 자동화 배포 (0) | 2023.08.29 |
댓글