WebSocket + Nginx 404에러부터 테스트까지

·2025년 9월 21일

troubleshooting

목록 보기
2/9
public class ChattingConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry){
        registry.addEndpoint("/ws/chat")
                .setAllowedOriginPatterns("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry){
        registry.setApplicationDestinationPrefixes("/send");
        registry.enableSimpleBroker("/topic");
    }
}
public class ChatController {

    private final ChatService chatService;

    @MessageMapping("/{roomId}")
    @SendTo("/topic/{roomId}")
    public ChatMessageResDto sendMessage(@DestinationVariable Long roomId,@Valid ChatMessageReqDto dto) {
        log.info("메시지 도착 = {}", dto.getContent());
        return chatService.saveMessage(roomId, dto, userId);
    }
	
    // 생략
}

1. HTTP vs WebSocket 차이

  • HTTP(REST API)
    • 요청(Request) → 응답(Response) → 연결 종료.
    • 요청마다 새로운 TCP 연결을 맺을 수 있고, 라이프사이클이 짧음.
    • 서버 Push 불가, 항상 클라이언트가 요청해야 데이터 전달 가능.
  • WebSocket
    • 초기에만 HTTP로 Upgrade 핸드셰이크 수행 (Upgrade: websocket 헤더).
    • 성공하면 101 Switching Protocols 응답 후, 하나의 TCP 연결을 지속.
    • 이후엔 양방향 통신 가능 (서버→클라이언트 Push).
    • HTTP가 아닌 WebSocket 프레임 단위로 통신.

핵심: WebSocket은 "지속적인 연결 기반 양방향 통신"이라, 중간 Proxy(Nginx)나 방화벽이 Upgrade 헤더를 제대로 전달하지 않으면 동작하지 않습니다.

2. Nginx에서 꼭 해줘야 할 설정

WebSocket이 HTTP와 달리 Upgrade 헤더를 요구하기 때문에 프록시에서 처리 필수.

 location / {
                proxy_pass http://IP주소:8080;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
}

location /ws/chat/ {
                proxy_pass http://IP주소:8080;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  • proxy_http_version 1.1 → WebSocket Upgrade는 HTTP/1.1 이상에서만 지원.
  • Upgrade / Connection 헤더 → 브라우저가 보낸 Upgrade 요청을 백엔드까지 그대로 전달.
  • Host / X-Real-IP / X-Forwarded-For → 실제 클라이언트 정보 전달 (로그, 보안, CORS).

이 설정을 안 해주면 404에러가 발생한다.

3. STOMP + SockJS 사용 흐름

  1. 클라이언트가 /ws/chat으로 연결 시도 (SockJS → 내부적으로 /ws/chat/... 경로 사용).
  2. 연결 성공 시 STOMP 프로토콜로 publish/subscribe.
    • 메시지 전송: /send/{roomId}
    • 메시지 구독: /topic/{roomId}
  3. Authorization 헤더 필요 시 {"Authorization": "Bearer <JWT토큰>"} 을 STOMP CONNECT 프레임의 헤더에 넣어 전달.

https://jiangxy.github.io/websocket-debug-tool/

출처 : https://woo0doo.tistory.com/38 글 보다가 찾은 사이트예요

SockJS + STOMP 조합이기 때문에 둘 다 클릭해주고 연결해준다.

헤더에 accesstoken을 {"Authorization":"Bearer 토큰"} 방식으로 넣는다

이후 /send/{roomId} 하고 메시지 내용 넣어서 send해준다.

구독했다면 메시지를 받을 수 있다!

0개의 댓글