From 999b4d961457d2c3293d7e2f3ba9e67997bf318e Mon Sep 17 00:00:00 2001 From: minco Date: Wed, 2 Jul 2025 16:51:52 +0900 Subject: [PATCH] docs --- README.md | 8 +++ changelog.md | 3 + specification.md | 165 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 README.md create mode 100644 changelog.md create mode 100644 specification.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..2019e78 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Tap Protocol + +Tap과 TapHub가 통신하는 데 필요한 프로토콜의 명세서이다. 안전한 버전 관리를 위해 별도 저장소로 이동되었다. + +## 시작하기 + +[명세서](/specification.md) 페이지에서 상세한 프로토콜 내용을 볼 수 있습니다. +[변동 사항](/changelog.md) 페이지에서 프로토콜의 버전별 변동 사항을 볼 수 있습니다. diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..00e9be3 --- /dev/null +++ b/changelog.md @@ -0,0 +1,3 @@ +## 변화 + +- 커밋 `11fbc2b024` (06/30/25): Tap별 고유 `id`는 이제 서버 측에서 결심한다. TapHello에서 `id`가 제거되었다. diff --git a/specification.md b/specification.md new file mode 100644 index 0000000..50ac977 --- /dev/null +++ b/specification.md @@ -0,0 +1,165 @@ +# Tap API + +Tap API는 좋은 것이다! + +## 1. 기초 + +### Tap + +Tap은 Zako2의 오디오 소스를 책임지는 탈중앙화된 서버이다. Tap은 능동적으로 TapHub에 연결해 오디오 생성을 책임진다. +Tap에는 `name`이 있다. Zako2에게 오디오를 요청할 때, 오디오 소스의 식별자로 `name`이 사용된다. +또한, Tap에는 `id`가 있다. `id`에 관한 설명은 [Tap Group](#tap-group) 을 참조하라. + +### Tap Group + +Tap Group은 같은 `name`의 Tap이 모인 집합이다. TapHub는 Tap Group(i.e. 같은 `name`)에 속한 온라인인 Tap을 하나씩 순회하며 동일 생산, 동일 분배, 평등성이 성립하도록 오디오를 요청한다. + +#### Tap Group 인증 + +Tap Group마다 API Key가 부여된다. 올바른 API Key가 있어야 특정 `name`의 생산자 군에서 생산자의 역할을 수행 할 수 있다. + +### TapHub + +TapHub는 Zako2 소속의 Tap 소스 엔진이다. TapHub는 연결된 Tap을 관리하여 적절한 Tap으로부터 오디오 스트림을 로드하는 역할이다. + +## 2. 악수 + +```mermaid +sequenceDiagram + participant Tap + participant TapHub + + Tap->>TapHub: TapHello + TapHub-->>Tap: TapOkResponse +``` + +### 악수 연결 + +#### 연결 수립 + +Tap은 정상적인 연결 수립을 위해 다음과 같은 엔드포인트에 WebSocket 통신 세션을 수립한다. + +``` +WS /gateway +``` + +#### 안녕하세요 + +정상적인 연결 수립 후, Tap은 다음과 같은 형태의 TapHello를 JSON으로 전송한다. + +```ts +{ + name: string, + token: string +} +``` + +각 필드의 역할은 다음과 같다. + +- `name`: Tap Group의 이름이다. [Tap Group](#tap-group) 을 참조하라. +- `token`: Tap Group용 인증 토큰이다. [Tap Group 인증](#tap-group-인증) 을 참조하라. + +#### 안녕하세요 응답 + +TapHub의 내부 검증 절차 후, TapHub는 해당 WebSocket으로 다음과 같은 응답을 보낸다. + +```ts +{ + ok: boolean, + version: string, + message: string +} +``` + +각 필드의 역할은 다음과 같다. + +- `ok`: 연결 수립 성공 여부. `false`면 해당 세션은 올바르지 않기 때문에, 연결을 중단해야 한다. +- `version`: 프로토콜의 현재 버전. [버전 규칙](#4-버전-규칙) 을 참조하라. +- `message`: 추가 메시지. `ok == false` 일 때 주로 서식한다. + +### 완료 + +## 3. 오디오 요청 핸들링 + +### 리퀘스트 + +오디오 필요 시, TapHub는 WebSocket으로 다음과 같은 JSON 코드를 보낸다. + +```ts +{ + id: string, + data: string, + parameters: object +} +``` + +각 필드의 역할은 다음과 같다. + +- `id`: Audio 요청의 Nonce +- `data`: Audio 요청의 Data(예: TTS 텍스트, 유튜브 URL) +- `parameters`: 파라미터 Key-Value 데이터 (예: pitch, throat) + +Tap은 다음 경우에 따라 오디오 데이터를 담은 새로운 HTTP 요청을 수행해야 한다. + +### 정상적인 Audio Stream + +``` +POST /data/{id}/ok +``` + +해당 엔드포인트로 Raw 오디오 스트림을 전송한다. +`id` 파라미터는 [리퀘스트](#리퀘스트) 에서 받은 Nonce와 동일한 값을 보낸다. + +### 비정상적인 Audio Stream + +``` +POST /data/{id}/err +``` + +해당 엔드포인트로 다음과 같은 형태의 오류 정보를 전송한다. + +```ts +{ + message: string; +} +``` + +`id` 파라미터는 [리퀘스트](#리퀘스트) 에서 받은 Nonce와 동일한 값을 보낸다. + +## 4. 버전 규칙 + +ZakoTap 프로토콜은 기본적으로 SemVer 방식을 따른다. 자세한 설명은 다음과 같다. + +### 설명 + +버전은 장조, 단조, 패치로 이루어진다. 각 요소는 양의 정수이며, 다음과 같이 `.`으로 구분된다. + +``` +장조.단조.패치 +``` + +각 요소의 역할은 다음과 같다. + +- `장조`: 호환되지 않는 큰 변화가 발생할 때 변동되며, 다른 장조의 프로토콜은 상호 통신이 불가하다. +- `단조`: 변화가 있지만, 서로 호환이 되는 경우에 변동된다. 다른 단조의 프로토콜은 하위 호환성을 지원한다. +- `패치`: 간단한 버그 수정 시 변동된다. 자연스럽게 하위 호환성을 지원한다. + +### 행동 규약 + +버전을 수신하면 클라이언트는 서버의 버전을 자신의 버전과 대조한다. +이때, `장조`가 다른 경우, 프로토콜 실행을 중단하고 업데이트를 요구한다. +이외의 요소는 무시한다. + +### 예시 + +다음은 예시이다. + +```diff +서버 버전 / 클라이언트 버전 -> 진행 / 중단 +``` + +```diff ++ 1.0.0 / 1.1.2 -> 진행 ++ 1.3.4 / 1.2.1 -> 진행 +- 1.2.0 / 2.0.0 -> 중단 +```