stayge-ws-client-sdk
v0.1.37
Published
Stayge WebSocket Client SDK
Readme
STAYGE WebSocket Client SDK
WebSocket Gateway 서버와 통신하기 위한 클라이언트 SDK입니다.
설치
npm install stayge-ws-client-sdk사용 가이드
상세한 사용 가이드는 SDK 사용 가이드를 참조하세요.
사용예시
React
import { getWebSocketClient, WsError } from "stayge-ws-client-sdk/react";
type Message = {
title: string;
body: string;
};
const ws = getWebSocketClient();
// 기본 연결 (heartbeat 활성화, 20초 주기)
ws.connect({ url: "wss://dev.linc.fan/ws/linc" });
// heartbeat 커스텀 설정
ws.connect({
url: "wss://dev.linc.fan/ws/linc",
heartbeat: {
pingIntervalMs: 15000, // 15초 주기
pongTimeoutMs: 3000, // 3초 타임아웃
maxMissedPongs: 2, // 2회 실패 시 연결 끊김
},
});
ws.onConnect({
callback: () => {
// connected
},
});
// 이벤트 핸들러는 connect 이전에 등록 가능, 여러번 호출해서 멀티 핸들러 등록 가능
ws.onMessage<Message>({
topic: "openchat/12345",
callback: (topic, payload) => {
// 서버에서 메시지가 수신되면 호출됨
// payload는 Message 타입으로 넘어오고 sdk에서 JSON.parse() 후에 핸들러에 넘겨줌
console.log(`Received: topic=${topic}, payload=${JSON.stringify(payload)}`);
},
});
ws.onDisconnect({
callback: () => {
// 서버와 연결이 끊어지면 호출됨
console.log(`onDisconnect`);
},
});
ws.onError({
callback: (error: WsError) => {
// 에러 발생 시 호출됨
if (error.code === "subscribeError") {
// 구독 에러 처리. serverCode로 원인 구분 가능
if (error.serverCode === "invalid_token") {
// 토큰 재발급 후 ws.subscribe() 재호출
}
console.log(`구독 에러 (${error.topic}): ${error.message}`);
} else if (error.code === "subscribeTimeout") {
// 구독 요청에 대한 서버 응답 없음 (자동 재시도 소진 후 통보)
console.log(`구독 타임아웃 (${error.topic})`);
} else if (error.code === "connectionLost") {
// 연결 끊김 감지 (heartbeat 실패)
console.log(`연결 끊김: ${error.message}`);
}
},
});React Native
import { getWebSocketClient, WsError } from "stayge-ws-client-sdk/react-native";
type Message = {
title: string;
body: string;
};
const ws = getWebSocketClient();
ws.connect({ url: "wss://dev.linc.fan/ws/linc" });
ws.onConnect({
callback: () => {
setConnected(true);
},
});
// 이벤트 핸들러는 connect 이전에 등록 가능, 여러번 호출해서 멀티 핸들러 등록 가능
ws.onMessage<Message>({
topic: "openchat/12345",
callback: (topic, payload) => {
// 서버에서 메시지가 수신되면 호출됨
// payload는 Message 타입으로 넘어오고 sdk에서 JSON.parse() 후에 핸들러에 넘겨줌
console.log(`Received: topic=${topic}, payload=${JSON.stringify(payload)}`);
},
});
ws.onDisconnect({
callback: () => {
// 서버와 연결이 끊어지면 호출됨
console.log(`onDisconnect`);
},
});
ws.onError({
callback: (error: WsError) => {
if (error.code === "subscribeError") {
setSubscribedTopics((prev) => prev.filter((t) => t !== error.topic));
} else if (error.code === "connectionLost") {
// 재연결 로직 구현
console.log(`연결 끊김: ${error.message}`);
}
},
});토큰 발급
토픽 구독에 필요한 토큰은 LINC API의 issueWebSocketToken을 통해 발급받아야 합니다.
POST /api/youmeon/v1/websocket/tokenAPI Base URL
| 환경 | Base URL |
|------|----------|
| Dev | https://youmeon-dev.stayge.net |
| QA | https://qa.linc.fan |
| Live | https://www.linc.fan |
Request Body
| Field | Type | Description |
|-------|------|-------------|
| webSocketTopicType | "liveEvent" | "user" | "privateChat" | "openChat" | "internal" | 웹소켓 토픽 타입. internal은 내부용 토픽 |
| webSocketTopic | string | 웹소켓 토픽. internal 타입인 경우 internal/ 프리픽스로 시작해야 함 (예: internal/my-feature/room123) |
Response
| Field | Type | Description |
|-------|------|-------------|
| success | boolean | 성공 여부 |
| message | string | 응답 메시지 |
| data.webSocketToken | string | 웹소켓 토큰 |
const API_BASE_URL = "https://www.linc.fan"; // 환경에 맞게 변경
const response = await fetch(`${API_BASE_URL}/api/youmeon/v1/websocket/token`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer {accessToken}",
},
body: JSON.stringify({
webSocketTopicType: "liveEvent",
webSocketTopic: "artist:12345:live",
}),
});
const { data } = await response.json();
const token = data.webSocketToken;
// 발급받은 토큰으로 구독
ws.subscribe({ topic: "artist:12345:live", token });Subscribe 재시도 (구독 신뢰성)
subscribe()는 기본적으로 아래와 같이 동작합니다 (v0.1.37+, 서버 ack 프로토콜 필요):
- 큐잉: 소켓이 아직 연결되지 않은 상태에서
subscribe()를 호출하면 큐에 보관했다가 연결 완료 시 전송합니다. (이전 버전에서는 조용히 드롭되었음) - ack 확인: 전송 후 서버의 구독 성공 ack(
system:subscribe:ok)를 기다립니다. 타임아웃 시 exponential backoff로 자동 재시도합니다. (subscribe는 멱등이므로 재전송해도 안전) - 에러 분류: 일시적 에러는 자동 재시도하고, 토큰 관련 에러(
invalid_token등)는 재시도 없이 즉시onError로 통보합니다. 이 경우 토큰을 재발급받아 같은 topic으로subscribe()를 다시 호출하면 됩니다. - 최종 통보: 재시도가 모두 소진되면
onError로subscribeError또는subscribeTimeout이 통보됩니다.
구독 상태는 현재 연결 세션 내에서만 유지됩니다. 연결이 끊긴 뒤
connect()로 재연결하면 이벤트 핸들러 재등록과 마찬가지로 앱이 명시적으로subscribe()를 다시 호출해야 합니다 (자동 재구독 없음).서버는 백프레셔 상황에서 ack를 드롭할 수 있어,
subscribeTimeout이 통보되어도 실제로는 구독이 성공해 있을 수 있습니다.subscribeTimeout수신 시에는 재구독(멱등)을 권장합니다.
기본 설정
| 설정 | 기본값 | 설명 |
|------|--------|------|
| ackTimeoutMs | 5000 (5초) | 서버 ack 대기 타임아웃 |
| maxRetries | 3 | 최대 재시도 횟수 (최초 전송 제외) |
| retryBaseDelayMs | 1000 (1초) | 백오프 기본 지연 (재시도마다 2배) |
| retryMaxDelayMs | 30000 (30초) | 백오프 최대 지연 |
| nonRetryableServerCodes | ["invalid_token", "token_expired", "unauthorized", "forbidden"] | 재시도하지 않고 즉시 통보할 서버 에러 코드 |
// 커스텀 설정
ws.connect({
url: "wss://dev.linc.fan/ws/linc",
subscribeRetry: {
ackTimeoutMs: 3000,
maxRetries: 5,
},
});
// 비활성화 (레거시 fire-and-forget 동작)
ws.connect({
url: "wss://dev.linc.fan/ws/linc",
subscribeRetry: false,
});주의:
topic또는token이 빈 값이면subscribe()가 즉시 throw 합니다. (서버는 필수 필드가 누락된 요청에 응답하지 않으므로 전송 전에 차단)
Heartbeat (연결 상태 확인)
SDK는 서버와의 연결 상태를 확인하기 위해 주기적으로 ping/pong 메시지를 교환합니다.
기본 설정
| 설정 | 기본값 | 설명 |
|------|--------|------|
| pingIntervalMs | 20000 (20초) | Ping 전송 주기 |
| pongTimeoutMs | 5000 (5초) | Pong 응답 타임아웃 |
| maxMissedPongs | 3 | 연결 끊김 판단 실패 횟수 |
Heartbeat 비활성화
ws.connect({
url: "wss://example.com/ws/tenant1",
heartbeat: false,
});Debug 로그
SDK 내부 로그는 기본적으로 출력되지 않습니다(silent). 디버깅이 필요할 때만 getWebSocketClient / newWebSocketClient 호출 시 debug 옵션으로 켭니다.
// 모든 카테고리 로그 출력
const ws = getWebSocketClient({ debug: true });
// 카테고리별 토글 (예: ping 로그는 끄고 state/error 만 보기)
const ws = getWebSocketClient({
debug: { state: true, error: true },
});카테고리
| 카테고리 | 포함 로그 |
|----------|-----------|
| state | connect / disconnect / subscribe / unsubscribe / 구독 큐잉·재시도·재구독 / 연결 open·close / rebalance |
| ping | startHeartbeat / sendPing / handlePong |
| error | wsOnError / pong 타임아웃 / connectionLost / 구독 에러·ack 타임아웃 |
메시지 파싱 실패 같은 예외 상황의
console.error는debug옵션과 무관하게 항상 출력됩니다(운영 모니터링 용도).
에러 코드
| 코드 | 설명 |
|------|------|
| subscribeError | 토픽 구독 실패. error.serverCode로 서버 에러 코드(invalid_token 등) 확인 가능 |
| subscribeTimeout | 구독 요청에 대한 서버 응답(ok/error) 미수신. 자동 재시도 소진 후 통보 |
| connectionLost | Heartbeat 실패로 인한 연결 끊김 감지 |
SDK References
관련 문서
프로젝트 폴더 구조
stayge-ws-client-sdk/
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── vite.config.ts
├── src/
│ ├── index.ts # 공통 진입점
│ ├── core/
│ ├── react/
│ └── react-native/
├── docs/
│ ├── guides/ # 가이드 문서
│ └── ... # TypeDoc 생성 API 문서
└── dist/ # 빌드 산출물 (tsup)빌드
npm run build배포
deploy.patch.shSDK 문서 생성 & 업데이트
gen-docs.sh