프로젝트로 돌아가기

개발 중 · 2026.12 예상

Lingding

한국인과 일본인 학습자를 매칭하고 1:1 음성 대화까지 연결하는 언어 교환 앱입니다.

한국인과 일본인이 학습 상대를 찾고 실제 대화까지 이어 가는 언어 교환 앱입니다. 1:1 음성 통화, Go WebSocket signaling server, ICE server 구성, 서비스 기본 CRUD API 설계를 담당하고 있습니다.

기간
2026.05 - 현재
담당 범위
1:1 통화 · signaling server · ICE server · CRUD 설계
Blueberry Team
저장소
비공개 리포지토리

매칭된 두 사람을 실제 대화로 연결하는 기능

Lingding은 한국인과 일본인 학습자가 상대를 찾고 대화하며 서로의 언어를 배우는 앱입니다. 프로필과 매칭만으로는 교류가 시작되지 않기 때문에, 앱 안에서 바로 1:1 음성 통화로 이어지는 기능이 필요했습니다.

저는 통화 기능 전체와 Go signaling server, 네트워크 환경에 맞는 연결 경로를 제공하는 ICE server 구성, 서비스의 기본 CRUD API 설계를 담당했습니다.

1:1 통화

서버가 두 사람을 안내하고 음성은 기기 사이로 전달

  1. 01

    통화를 거는 사람

    첫 번째 스마트폰

  2. 02

    통화 안내 서버

    Go WebSocket signaling

  3. 03

    연결 경로 찾기

    STUN 우선, 필요 시 TURN

  4. 04

    통화를 받는 사람

    두 번째 스마트폰

  5. 05

    음성 경로

    WebRTC 직접 또는 TURN 경유

CRUD 요청과 통화는 같은 시간축에서 움직이지 않습니다

프로필과 매칭 CRUD는 응답을 돌려주면 끝나지만, 통화는 종료할 때까지 통화방과 두 WebSocket, offer·answer·ICE candidate의 순서를 유지해야 합니다.

두 클라이언트에서는 통화방 입장과 offer, answer, ICE candidate의 도착 순서가 달라질 수 있습니다. 상대가 없는 상태, 중복 연결, 종료 후 메시지도 일반 요청 오류와 다르게 다뤄야 했습니다.

일반 데이터 처리는 HTTP CRUD에 두고, 통화방과 시그널링 이벤트는 Go WebSocket으로 관리했습니다. 메시지 유형과 통화방의 수명주기를 명시해 두 클라이언트가 같은 통화 상태를 보도록 하는 책임을 서버에 뒀습니다.

  • 서버에서 통화방 입장·퇴장과 두 피어의 상태 관리했습니다.
  • SDP offer/answer와 ICE candidate를 상대 피어로 중계했습니다.
  • 연결 종료 시 통화방과 연결 자원 정리했습니다.

Go WebSocket 서버에 통화방 입장, 시그널링 중계, 종료 시 자원 정리를 구현하고 Flutter의 1:1 통화 흐름과 연결했습니다. 실제 환경의 동시 연결 수와 이벤트 지연 시간은 아직 측정하지 않았습니다.

실시간 서버에서는 요청 한 번이 아니라 연결 전체의 상태·이벤트 순서·정리 과정을 설계해야 했습니다.

Lingding 프로모션 이미지

TURN 자격 증명을 짧게 발급해 앱 밖에서 관리했습니다

서로 다른 NAT·방화벽 환경에서는 기기끼리 직접 연결하지 못해 TURN 중계가 필요할 수 있습니다. 하지만 고정 자격 증명을 모바일 앱에 넣으면 배포 후에도 추출해 재사용할 수 있습니다.

초기 요구사항은 1:1 음성 통화였기 때문에 TURN 서버를 직접 운영하기보다 관리형 서비스를 쓰는 편이 범위에 맞았습니다. 다만 자격 증명 발급과 비용 통제를 클라이언트에 맡길 수는 없었습니다.

STUN으로 찾은 직접 연결을 우선하고, 필요할 때만 Cloudflare TURN을 대체 경로로 사용했습니다. TURN 자격 증명은 앱에 고정하지 않고 서버가 Cloudflare API를 통해 단기로 발급하도록 경계를 뒀습니다.

  • Go 서버에 단기 TURN 자격 증명 발급 API 구현했습니다.
  • 발급 결과를 Flutter 클라이언트의 ICE 서버 설정에 반영했습니다.
  • 시그널링과 미디어 중계 자격 증명의 책임 분리했습니다.

단기 자격 증명 발급과 클라이언트 적용까지 구현했습니다. 네트워크 유형별 TURN 사용률, 발급 요청 제한, 비용은 아직 검증하지 않아 운영 성과가 아닌 구현 결과로만 적었습니다.

클라이언트에 전달되는 비밀 정보는 감추는 데서 끝나지 않고, 수명과 발급 주체, 사용 범위를 서버 경계에서 관리해야 한다는 점을 배웠습니다.

Lingding 홈 화면 러프

Flutter 1:1 음성 통화, Go WebSocket signaling server, STUN/TURN을 포함한 ICE server 구성, 기본 CRUD API 설계를 구현했습니다.

CRUD API에서는 요청 한 번의 처리를 중심으로 생각했지만, 실시간 기능에서는 서버가 연결 상태와 이벤트 순서, 종료 후 정리까지 계속 관리해야 한다는 점을 배웠습니다.

Lingding의 실제 환경에서는 부하, 연결 성공률, 지연 시간(latency), 장시간 통화를 아직 측정하지 않았고 실제 사용자 지표도 없습니다. 2026년 12월은 확정된 공개일이 아니라 현시점의 예상 일정입니다.

  • Wi-Fi·LTE/5G·제한 네트워크 연결 matrix 구축
  • room·WebSocket 수와 offer→answer→ICE 완료율 측정
  • credential TTL·rate limit·재연결·장시간 soak test 검증