HTTP 대체 연결
네트워크에서 WebSocket을 차단하면 채팅이 일반 HTTPS로 자동으로 계속됩니다. 전환 시점, 강제 적용 방법, Content Security Policy와 프록시 설정, 문제 해결 방법을 설명합니다.
위젯은 일반적으로 WebSocket을 통해 채팅 서버에 연결됩니다. 일부 네트워크에서는 이를 허용하지 않습니다. 이때 HTTP 대체 연결을 사용합니다. 운영자나 방문자가 따로 조치하지 않아도 채팅이 일반 HTTPS 요청을 통해 계속됩니다.
HTTP 대체 연결이란
WebSocket 연결은 주로 다음 환경에서 실패합니다.
- 프록시나 방화벽이 일반 HTTP(S) 요청만 통과시키는 기업 네트워크,
- WebSocket을 전달하지 않는 호스팅 서비스, CDN 또는 로드 밸런서,
Upgrade및Connection헤더를 전달하지 않는 리버스 프록시 뒤의 환경.
HTTP 대체 연결에서는 위젯이 서버 메시지를 Server-Sent Events, 즉 오래 유지되는 HTTPS 스트림으로 수신합니다. 이 스트림으로 아무것도 도착하지 않으면 롱 폴링으로 전환합니다. 전송에는 HTTPS POST를 사용합니다. 두 경로 모두 WebSocket과 동일한 메시지를 전달합니다. 방문자는 메시지를 작성하고 AI 어시스턴트와 상담원의 답변을 받으며, 여러 열린 탭은 평소처럼 하나의 연결을 공유합니다. 첨부 파일은 원래 HTTPS로 업로드되므로 연결 방식과 무관합니다.
대체 연결은 웹사이트의 채팅 위젯에 적용됩니다. 상담원 화면은 계속 WebSocket으로 연결됩니다.
적용되는 경우
위젯은 다음 경우에 HTTP 대체 연결을 사용합니다.
- 브라우저가 WebSocket을 지원하지 않는 경우,
- WebSocket 연결 시도가 연속으로 두 번 실패한 경우. 8초 후에도 연결되지 않고 거부되지도 않은 시도 역시 실패로 간주합니다.
- 강제로 적용한 경우(아래 참조).
전환은 해당 페이지에서 아직 WebSocket 연결이 한 번도 성립하지 않았을 때만 이루어집니다. 네트워크 변경 등으로 기존 WebSocket 연결이 끊기면 위젯은 WebSocket으로 다시 연결합니다.
대체 연결이 활성화되면 위젯은 해당 페이지에서 이 방식을 유지합니다. 다음 페이지에서 다시 두 번의 시도로 시간을 낭비하지 않도록 전환을 기억합니다. 30분 이내에 같은 탭에서 연 페이지는 곧바로 HTTPS로 연결됩니다. 동시에 위젯은 페이지마다 백그라운드에서 WebSocket이 이제 통과하는지 한 번 확인합니다. 성공하면 다음 페이지는 다시 WebSocket을 사용하고, 현재 페이지는 HTTP 대체 연결을 유지합니다.
대체 연결 강제 적용
테스트하거나 WebSocket이 작동하지 않는 것으로 알려진 환경에서는 처음부터 HTTP 대체 연결을 켤 수 있습니다. 가장 간단한 방법은 위젯의 script 태그에 data-rc-transport="http" 속성을 지정하는 것입니다.
<script src="https://cdn.reactive.chat/loader.js"
data-rc-site-key="SITE_KEY"
data-rc-transport="http"
async></script>
위젯은 문서 전체에서 이 속성을 찾습니다. 따라서 다른 요소에 지정해도 위젯이 시작될 때 해당 요소가 이미 문서 안에 있으면 작동합니다.
또는 위젯의 script 태그 앞에 JavaScript로 옵션을 설정합니다.
<script>
window.ReactiveChatSettings = { transport: 'http' };
</script>
<script src="https://cdn.reactive.chat/loader.js"
data-rc-site-key="SITE_KEY"
async></script>
나중에 ReactiveChat('boot', { transport: 'http' })를 호출해도 이 설정에는 영향을 주지 않습니다. 연결 방식은 위젯이 시작될 때 결정됩니다.
Content Security Policy
Server-Sent Events, 롱 폴링 및 메시지 전송은 채팅 연결과 같은 주소를 사용하되 wss:// 대신 https:// 를 사용합니다. 웹사이트에 Content Security Policy가 설정되어 있으면 connect-src에서 두 형식을 모두 허용해야 합니다.
connect-src 'self' wss://ws.reactive.chat https://ws.reactive.chat
오프라인 양식과 파일 업로드도 https:// 주소를 사용합니다. 자체 도메인을 사용하는 경우에는 서브도메인의 주소를 넣습니다.
connect-src 'self' wss://chat.your-domain.com https://chat.your-domain.com
정책의 다른 항목은 그대로 유지합니다. 그 밖에 정책에서 허용해야 하는 사항은 위젯 삽입에 설명되어 있습니다.
자체 도메인을 사용하는 경우
웹사이트의 서브도메인을 통해 채팅을 운영하는 경우 HTTP 대체 연결도 WebSocket과 동일한 /rc_wss/ 경로를 사용합니다. 프록시에 별도 경로를 추가할 필요는 없지만 이 경로의 응답을 버퍼링 없이 전달해야 합니다.
- nginx:
/rc_wss/섹션에proxy_buffering off및proxy_cache off를 설정합니다. - Apache:
/rc_wss/용ProxyPass줄에flushpackets=on을 설정합니다. - Caddy:
/rc_wss/의reverse_proxy에flush_interval -1을 설정합니다.
계정 페이지와 자체 도메인 가이드의 템플릿에는 이 설정이 이미 들어 있습니다. 이전 설정을 가져와 사용 중이라면 현재 템플릿과 비교합니다.
브라우저에 저장되는 정보
HTTPS 연결이 성공하면 위젯은 브라우저의 sessionStorage에 rc_http 항목을 만듭니다. 이 항목에는 연결 시각만 들어 있으며 개인정보는 없습니다. 위젯은 이를 이용해 이후 30분 동안 다음 페이지에서 곧바로 HTTP 대체 연결을 사용합니다. WebSocket이 다시 통과하면 항목을 삭제합니다. 다른 sessionStorage 항목처럼 늦어도 탭을 닫으면 사라집니다. 일부 비공개 창 등에서 sessionStorage를 사용할 수 없으면 페이지마다 다시 WebSocket으로 시작합니다.
활성 연결 경로 확인
브라우저의 개발자 도구를 열고 “네트워크” 탭으로 이동합니다.
- WebSocket:
wss://ws.reactive.chat/rc_wss/에 WebSocket 유형의 연결이 있습니다. 자체 도메인을 사용하는 경우에는 해당 서브도메인으로 연결됩니다. - HTTP 대체 연결:
https://ws.reactive.chat/rc_wss/h/…로 요청이 전송됩니다. 먼저h/auf, 다음으로…/sse에 오래 유지되는 스트림이 나타납니다. 롱 폴링에서는…/poll에 반복 요청이 나타나며, 메시지를 보낼 때마다…/tx에 요청이 하나씩 전송됩니다.
“애플리케이션” 또는 “저장소”에서도 rc_http 항목이 설정되어 있는지 확인할 수 있습니다.
문제 해결
Content Security Policy가 https 주소를 차단하는 경우
connect-src에 wss:// 주소만 있으면 브라우저가 대체 연결의 요청을 차단합니다. 이때 브라우저 콘솔에 CSP 메시지가 표시됩니다. 대상 주소: https://…/rc_wss/h/auf. WebSocket이 통과하는 환경에서는 아무런 차이를 느끼지 못하지만 WebSocket을 사용할 수 없는 네트워크에서는 연결이 전혀 성립하지 않습니다. 위 예시처럼 https:// 주소를 추가합니다.
프록시가 응답을 버퍼링하는 경우
중간 프록시가 스트림을 버퍼링하면 Server-Sent Events가 늦게 도착하거나 한꺼번에 도착하거나 전혀 도착하지 않습니다. 위젯은 스트림의 첫 메시지를 5초 동안 기다린 후 롱 폴링으로 전환합니다. 이 방식으로도 채팅은 작동하지만 연결에 몇 초 더 걸립니다. 자체 도메인을 사용하는 경우 /rc_wss/의 버퍼링을 해제합니다(위 참조).
오래 유지되는 요청이 끊기는 경우
롱 폴링에서는 전달할 내용이 없을 때 서버가 요청을 최대 25초 동안 열어 둡니다. 열린 스트림에서는 15초마다 연결 유지 신호를 보냅니다. 이보다 일찍 요청을 중단하는 방화벽이나 프록시는 위젯이 자주 다시 연결하도록 만듭니다. 채팅 주소에 대한 요청이 최소 30초 동안 유지되도록 허용합니다.
채팅이 전혀 연결되지 않는 경우
WebSocket과 HTTP 대체 연결이 모두 실패하면 위젯은 백그라운드에서 계속 시도합니다. 방문자의 네트워크에서 채팅 주소에 HTTPS로 접근할 수 있는지, Content Security Policy나 필터가 차단하고 있지는 않은지 확인합니다.
문서에서 더 알아보기
자세한 내용: 전송: WebSocket, HTTP 대체 연결과 재연결. 모든 장은 문서에서 확인할 수 있습니다.
최종 업데이트: