WebSocket과 ActionCable의 기본
WebSocket은 HTTP와 달리 양방향 통신 채널을 제공하여 서버가 클라이언트 요청 없이 메시지를 전송할 수 있습니다. ActionCable은 Rails 앱 내 Rack 애플리케이션으로, websocket-driver-ruby 젬을 통해 WebSocket 연결을 관리하고, 열린 연결에 text() 메서드를 호출하여 클라이언트에 메시지를 보냅니다. 본문에서는 ToyCable이라는 단순화된 구현으로 이 과정을 보여줍니다.
다중 프로세스 메시지 브로드캐스트
ActionCable은 메인 Rails 프로세스에서 실행되므로, 비동기 작업 등 별도 프로세스에서 클라이언트에 메시지를 보내려면 중간 매개체가 필요합니다. ActionCable은 데이터베이스(Solid Cable), Redis, PostgreSQL의 pub/sub 등 다양한 어댑터를 활용합니다. 별도 프로세스가 중간 매개체에 메시지를 기록하면 ActionCable이 이를 수신하여 해당 클라이언트에 브로드캐스트합니다.
Turbo를 통한 실시간 스트림
turbo_stream_from 헬퍼는 뷰에 <turbo-cable-stream-source> HTML 요소를 렌더링하여 WebSocket 연결을 설정합니다. 이 요소의 signed-stream-name은 스트림 이름의 Base64 인코딩과 HMAC 서명으로 구성되어 구독 요청의 유효성을 검증하고 무단 변조를 방지합니다. Turbo::StreamsChannel은 이 서명 검증을 기반으로 작동하며, broadcast_to 메서드를 통해 특정 채널로 <turbo-stream> HTML을 전송하여 실시간 DOM 업데이트를 가능하게 합니다.