상세 컨텐츠

본문 제목

[Troubleshooting] WebSocket connection to 'ws://localhost:8080/ws/websocket' failed:

Development/Frontend

by Developer, Jiyong Kim 2024. 7. 15. 15:40

본문

프로젝트를 진행하면서 로컬에서는 아무런 문제가 없었는데, 꼭 서버에 올리기만 하면 아래와 같은 Websocket 에러가 발생했다. 심지어 Websocket을 쓰지도 않는데 말이다.

 

콘솔창에 뭐 좀 그만 떠라...

우선 Websocket을 쓰지도 않는데 Websocket 에러가 발생하는 이유부터 알아보자. Create React App(CRA)으로 프로젝트를 생성했건, Vite를 통해서 했건 둘 다 해당 에러가 발생할 것이다. 그 이유는 바로 두 경우 모두 HMR(Hot Module Replacement) 기능을 제공하기 때문이다.

 

HMR은 개발 중에 코드 변경 사항을 즉시 반영하여 페이지를 새로고침하지 않고도 변경된 내용을 확인할 수 있게 해주는 기능을 말하는데, CRA는 Webpack 번들러를 통해서, Vite는 자체 개발 서버를 통해서 해당 기능을 제공한다.(Vite의 HMR 성능이 더 빠르긴하다)

 

개발 감각이 있다면 이미 눈치 챘겠지만, HMR 기능은 Websocket 연결을 기반으로 이루어진다. HMR의 동작 방식을 살펴보면 (1) 개발 서버가 파일 시스템을 감시하여 파일 변경 사항을 감시, (2) Websocket을 통해 브라우저에 파일 변경 사항을 전달, (3) 브라우저는 즉시 변경된 모듈을 교체하여 변경사항 반영 순이다. 이 과정에서 WebSocket 연결이 중요한 역할을 하게 되며, 이 같은 이유로 Websocket 설정을 따로 하거나 사용하지 않아도 이와 같은 에러가 발생하는 것이다.

 

이제 해결방법을 알아보자. 서버에 올릴 때만 문제가 발생한 이유는 Nginx 설정 파일에 WebSocket이 올바르게 작동하도록 허용하는 코드가 작성되지 않았기 때문이다. 아래와 같이 Nginx 설정 파일에 접근하여 설정을 변경해주면 문제가 해결된다.

// Nginx 설정 파일을 vi 편집기로 열기
sudo vi /etc/nginx/nginx.conf
// Websocket 에러를 해결하기 위한 설정
location /ws/ {
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    
    // HTTP 요청이 WebSocket 연결로 업그레이드되도록 보장
    // $http_upgrade 변수는 클라이언트가 보낸 Upgrade 헤더의 값을 가져오며, 이는 websocket이어야 함
    proxy_set_header Upgrade $http_upgrade;
    
    // 프록시 서버가 연결을 업그레이드된 연결로 처리하도록 지시
    proxy_set_header Connection "upgrade";
}
// Nginx 재시작하여 변경 사항 적용
sudo systemctl reload nginx

 

관련 웹팩 가이드 레퍼런스

 

Development - Vagrant | 웹팩

웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.

webpack.kr

관련글 더보기