LabHub
はじめる
배우기 러닝패스 코스

リアルタイム通信 — WebSocket・gRPC ストリーミング・WebRTC

リアルタイムチャネルを測り、音声フレームを送る

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

실시간 채널은 평균이 아니라 지연 분포의 꼬리와 재접속률로 보고, 음성 프레임은 20ms 박자를 지켜 보내며, 재생 버퍼로 끊김과 지연을 맞바꿉니다.

왜 이게 필요했나

실시간 채널의 장애는 대부분 "가끔" 일어납니다. 1% 의 프레임이 300ms 늦으면 평균 지연은 거의 그대로인데 대화는 끊깁니다. 연결 수 지표는 멀쩡한데 재접속이 분당 수천 번 일어나고 있을 수도 있습니다. 음성 AI 서비스는 여기에 박자가 더해집니다. 마이크는 20ms 마다 프레임을 만들고, 인식 엔진과 재생기는 그 박자를 기대합니다. 박자를 어기면 받는 쪽 버퍼가 넘치거나 비어서 소리가 튀거나 끊깁니다.

어떻게 동작하나

프레임 산수. 음성 인식이 흔히 받는 형식은 16kHz, 16비트, 모노입니다. 1초에 32,000 바이트(256kbps)이고, 20ms 프레임 하나는 320 표본, 640 바이트입니다. Opus 로 부호화하면 음성은 수십 kbps 로 줄어듭니다. 프레임을 보낼 때는 마감 시각을 절대 시각(시작 + i × 20ms)으로 잡아야 합니다. 보낼 때마다 20ms 잠드는 방식은 부호화에 쓴 시간이 매번 더해져 1초에 수백 ms 씩 밀립니다.

지연의 분포. 왕복 지연은 보낸 순간의 단조 시계를 프레임 머리에 적고 메아리가 온 순간과 빼서 잽니다. 한 방향 지연은 두 기계의 시계가 맞아야 해서 훨씬 어렵습니다. 모은 표본은 p50·p95·p99 로 요약합니다. 최근접 순위 방식은 정렬한 값의 ceil(p/100 × n) 번째를 고르므로 실제로 관측된 값만 보고합니다. 여러 서버의 p99 를 평균 내면 의미 없는 숫자가 되므로, 서버마다 히스토그램을 모아 합친 뒤 백분위를 계산해야 합니다.

지터. RFC 3550 6.4.1절은 도착 간격 지터를, 연속한 두 패킷의 전송 시간 차 D 의 절댓값으로 J = J + (|D| − J)/16 을 되풀이해 추정합니다. 1/16 은 잡음을 줄이는 이득입니다. 브라우저의 WebRTC 통계(getStats) 는 받는 RTP 스트림마다 jitter, packetsLost, jitterBufferDelay, concealedSamples 같은 값을 내놓고, 상대가 보고한 roundTripTime 도 줍니다.

재생 버퍼. 받는 쪽은 첫 프레임이 도착한 뒤 버퍼 시간만큼 기다렸다가 20ms 마다 하나씩 재생합니다. i 번째 프레임이 제 재생 시각보다 늦게 오면 없는 것과 같습니다. 버퍼를 늘리면 늦은 프레임은 줄고 모든 소리가 그만큼 늦어집니다. TCP 위의 WebSocket 은 잃은 것이 없는데도 한 번 멈추면 그 동안의 프레임이 한꺼번에 늦게 오므로, 같은 끊김 비율을 지키려면 멈춘 시간만큼의 버퍼가 필요합니다. 순서와 재전송을 요구하지 않는 WebRTC 데이터 채널이나 RTP 는 잃은 것만 잃습니다.

채널의 관측. 실시간 채널에서 볼 숫자는 다섯 가지입니다.

지표
연결 준비 시간(핸드셰이크·ICE·DTLS) 사용자가 처음 기다리는 시간
메시지 지연 p50·p99 평균 뒤에 숨는 꼬리
재접속률과 닫기 코드 분포 끊김이 어디서 왜 나는지
구독자별 큐 길이·버린 수 느린 소비자
ping 왕복 시간 망 상태와 죽은 상대

재는 방법의 함정. 부하 생성기가 응답을 기다린 뒤에야 다음 요청을 보내면, 서버가 멈춘 동안 보냈어야 할 요청이 아예 측정에서 빠집니다(coordinated omission). 박자를 지키는 송신기 — 앞의 누적 오차 없는 보내기 — 로 재야 멈춤이 꼬리에 제대로 잡힙니다. 또 지연은 같은 기계의 단조 시계로 재야 합니다. 벽시계는 NTP 가 도중에 고치면 거꾸로 가기도 해서 음수 지연이 나옵니다.

관측 숫자에는 꼬리표를 붙입니다. 어느 운반로(WebSocket·WebRTC)인지, 어느 지역과 망 종류(와이파이·LTE)인지를 함께 남겨야, 전체 p99 가 나빠졌을 때 어느 집단의 꼬리인지 가를 수 있습니다.

재접속률도 같은 식으로 봅니다. 연결 수가 일정해 보여도 분당 재접속 수와 닫기 코드의 분포를 따로 세지 않으면, 1% 의 사용자가 30초마다 끊겼다 붙는 상황이 지표 뒤에 숨습니다.

현장에서 만나는 모습

음성 AI 의 체감 지연은 사슬의 합입니다. 20ms 프레임을 모으는 시간, 망, 발화 끝 감지, 인식의 부분 결과, 언어 모델의 첫 토큰, 합성의 첫 조각, 재생 버퍼. ITU-T G.114 가 말하는 한 방향 150ms 는 사람끼리의 통화 기준이고, 음성 AI 는 그 위에 처리 시간이 얹힙니다. 그래서 운반로에서 아낄 수 있는 수십 ms 가 중요하고, 그 수십 ms 를 재는 도구가 먼저 있어야 합니다. 이 실습의 숫자는 음성 AI 코스에서 인식·합성을 이 운반로 위에 올릴 때 기준선이 됩니다.

다음 실습에서 할 것

16kHz WAV 를 20ms 프레임으로 자르고, 누적 오차 없이 박자를 지켜 보내고, 백분위와 RFC 3550 지터를 계산합니다. WebSocket 과 WebRTC 데이터 채널로 같은 프레임의 왕복 지연을 재고, Opus 미디어 트랙으로 소리를 보내 48kHz 로 받는 것을 확인한 뒤, 도착 기록으로 재생 버퍼 크기를 계산합니다.