WebSocket API
개요¶
WebSocket API는 Socket 서버와 WebSocket 통신하여 채팅 서비스를 제공합니다. 게임 클라이언트 접속, 채널 메시지 전송 등을 지원합니다.
WebSocket API의 주요 기능은 아래와 같습니다.
- 클라이언트 접속 / 해제
- PING / PONG
- 채팅 메시지 전송 / 수신
- 채널 채팅
- 1:1 채팅
- 차단한 유저 필터링
- 차단한 유저에게 메시지를 발신하지 않음
- 차단한 유저로부터 메시지를 수신하지 않음
- 채널 입장, 퇴장 알림
기본 정보¶
WebSocket API 사용 시, 공통적으로 알아야 하는 기본 정보를 안내합니다.
주요 용어¶
- 채널: 채팅방
- 채널 메시지: 참여한 채널의 모든 유저에게 전송하는 채팅 메시지
- 1:1 메시지: 특정 유저에게만 전송하는 채팅 메시지
패킷 유형¶
Socket 서버와 전송 및 수신하는 패킷 유형은 아래와 같습니다.
패킷 명 | 설명 |
---|---|
CONNECT | Socket 서버 접속 |
RESPONSE_CONNECT | CONNECT 요청에 대한 응답 |
DISCONNECT | Socket 서버 연결 해제 |
RESPONSE_DISCONNECT | DISCONNECT 요청에 대한 응답 |
PING | 연결 유지 CONNECT 가 성공하지 않은 상태에서 PING 요청 시, 서버에서 연결을 해제함 |
PONG | PING 요청에 대한 응답 |
CHANNEL_CHAT | 채널 채팅 |
RESPONSE_CHANNEL_CHAT | CHANNEL_CHAT 요청에 대한 응답 |
DIRECT_CHAT | 1:1 채팅 |
RESPONSE_DIRECT_CHAT | DIRECT_CHAT 요청에 대한 응답 |
NOTIFY_ENTER_CHANNEL | 채널 입장 메시지 |
NOTIFY_EXIT_CHANNEL | 채널 퇴장 메시지 |
NOTIFY_DELETE_CHANNEL | 채널 삭제 메시지 |
NOTIFY_CHANNEL_NOTICE | 채널 공지 메시지 |
NOTIFY_CHANNEL_CHAT | 채널 채팅 메시지 |
NOTIFY_DIRECT_CHAT | 1:1 채팅 메시지 |
NOTIFY_DISCONNECT | 연결 해제 메시지 WebSocket 커넥션이 idle 상태 일때, Json 포맷이 유효하지 않을 때 해당 패킷 타입으로 응답 |
Socket 접속 프로세스¶
-
게임 서버에서 채팅 Http API로 토큰 발급 요청. ※ 발급된 토큰은 채팅 Socket 서버 연결에 사용됨
- Hive Certification Key를 사용하여 유저 토큰 발급 API을 요청
-
게임 클라이언트에서 Socket 서버로 접속 요청
- WebSocket 통신
- 1번 과정에서 발급된 토큰 사용
- 접속에 성공하면 Socket 서버에서는 아래 정보를 반환
Socket 통신 구조¶
-
'RESPONSE_'로 시작하는 패킷 유형의 JSON 형식
-
그 외의 패킷 형식
서버 측에서 WebSocket 연결 해제하는 경우는 아래에 해당됩니다.
- 클라이언트 측에서 1분간 아무런 요청이 없을 경우
- JSON 형식이 아닐 때
- status 값이 401, 403 일 때
- 401 unauthorized
- 403 forbidden
응답 코드¶
응답 상태 코드입니다.
상태 코드 | 상태 메시지 | 설명 |
---|---|---|
200 | Success. | 성공 |
400 | Bad Request | 잘못된 요청 |
401 | Unauthorized | 권한 없음 |
403 | Forbbiden | 서버에서 거부됨 |
408 | Request timeout | 클라이언트에서 60초간 요청이 없어서, 서버에서 연결을 해제 |
409 | Conflict | 사용자의 요청이 서버 상태와 충돌 (e.g. 1:1 채팅 상대방이 오프라인인 경우) |
500 | Internal Server Error | 내부 서버 오류 |
WebSocket API 기능¶
채팅 서비스에 이용되는 WebSocket API의 기능 별 API 요청 및 응답, 예제 코드를 설명합니다.
클라이언트 접속¶
Request parameters¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 클라이언트 접속 명령어 (CONNECT ) | string | Y |
body | 요청 데이터 | object | Y |
Request parameters > body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
playerId | 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 1234 |
loginKey | 접속할 때 사용하는 토큰 채팅 Http API에서 발급 | string | Y | "eyJhbGciOiJIUzI1NiJ9.eyJnYW1lSW5kZXgiOjEsInBsYXllcklkIjoxMjM0LCJpYXQiOjE3MzAzNjY4MjksImV4cCI6MTczMDM3MDQyOX0.fpg6kqwqp1QN3KuYcjVBr8j0mzjN2doefJ_D6xFxcFY" |
extraData | 유저 부가정보 (UTF-8 기준)(최대 256 Byte) | string | N | e.g. "{\"nickname\":\"Test1234\",\"guildname\":\"together\"}" |
Response body¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 접속 요청에 대한 응답 (RESPONSE_CONNECT ) | string | Y |
status | 상태 코드 | integer | Y |
message | 상태 메시지 | string | Y |
body | 반환 데이터 | object | Y |
Response body > body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
sessionId | 접속 성공 시 반환되는 값 | string | Y | e.g. "005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76" |
Request sample¶
{
"packetType": "CONNECT",
"body":{
"gameIndex":1,
"playerId": 1234,
"loginKey": API 서버에서 생성한 JWT,
"extraData":부가정보
}
}
Response sample¶
{
"packetType":"RESPONSE_CONNECT",
"status": 200,
"message":"OK",
"body":{
"sessionId":"005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76"
}
}
클라이언트 접속 해제¶
Request parameters¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 클라이언트 접속 해제 명령어 (DISCONNECT ) | string | Y |
body | 요청 데이터 | object | Y |
Request parameters > body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
sessionId | 접속 성공 시 반환된 sessionId | string | N | e.g. "6c2408fffe8c91a8-00002f24-00000032-093b757cdc668383-54b4fbc1" |
- sessionId 를 지정하지 않을 경우, websocket 에 할당된 sessionId 에 대한 연결해제 처리
- sessionId 를 지정할 경우, 해당 값에 대한 연결해제 처리
Response body¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 접속 해제 요청에 대한 응답 (RESPONSE_DISCONNECT ) | string | Y |
status | 상태 코드 | integer | Y |
message | 상태 메시지 | string | Y |
Request sample¶
-
sessionId를 지정하지 않은 경우
-
sessionId를 지정하는 경우
Response Sample¶
PING / PONG¶
- Socket 서버와 CONNECT가 완료된 상태에서만 요청이 유효
- PONG 응답이 없을 경우 재로그인 필요
Request parameters¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | PING 요청 명령어 (PING ) | string | Y |
Response body¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | PONG 응답 명령어 (PONG ) | string | Y |
Request sample¶
Response sample¶
채널 메시지 전송¶
Request parameters¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 채널 메시지 전송 명령어 (CHANNEL_CHAT ) | string | Y |
body | 요청 데이터 | object | Y |
Request parameters > body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
from | 채널에 메시지 전송할 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 1234 |
to | 채널 메시지 전송할 채널 ID 채팅 Http API에서 생성 | string | Y | e.g. "open:1" |
message | 채널에 전송할 메시지 (최대 200자) | string | Y | e.g. "Hello World!" |
langCode | Hive 언어 코드 (ISO 639 alpha-2를 기준으로 하며 ISO 639 alpha-2로 구분되지 않는 언어는 Script tag를 붙여 구분) | string | Y | e.g. "en" |
Response body¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 채널 메시지 전송에 대한 응답 (RESPONSE_CHANNEL_CHAT ) | string | Y |
status | 상태 코드 | integer | Y |
message | 상태 메시지 | string | Y |
Request sample¶
{
"packetType":"CHANNEL_CHAT",
"body": {
"gameIndex": 1,
"from": 1234,
"to": "open:1",
"message": "Hello World!",
"langCode": "en"
}
}
Response sample¶
1:1 메시지 전송¶
Request parameters¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 1:1 메시지 전송 명령어 (DIRECT_CHAT ) | string | Y |
body | 요청 데이터 | object | Y |
Request parameters > body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
from | 1:1 메시지 전송할 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 1234 |
to | 1:1 메시지 전달 받을 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 2222 |
message | 1:1로 전송할 메시지 (최대 200자) | string | Y | e.g. "Hello World!" |
langCode | Hive 언어 코드 (ISO 639 alpha-2를 기준으로 하며 ISO 639 alpha-2로 구분되지 않는 언어는 Script tag를 붙여 구분) | string | Y | e.g. "en" |
Response body¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 1:1 메시지 전송에 대한 응답 (RESPONSE_DIRECT_CHAT ) | string | Y |
status | 상태 코드 | integer | Y |
message | 상태 메시지 | string | Y |
Response body > body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
status | 응답 상태 코드 | integer | Y | e.g. 200 |
Request sample¶
{
"packetType": "DIRECT_CHAT",
"body": {
"gameIndex": 1,
"from": 2222,
"to": 1234,
"message": "안녕하세요",
"langCode": "ko"
}
}
Response sample¶
Socket 서버 이벤트 메시지¶
이벤트 발생 시, Server에서 Client로 전송되는 메시지를 설명합니다.
해당 메시지는 packetType이 NOTIFY
로 시작합니다.
채널 입장 메시지¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 채널 입장 메시지 (NOTIFY_ENTER_CHANNEL ) | string | Y |
body | 요청 데이터 | object | Y |
Body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
channelId | 입장한 채널 ID | string | Y | e.g. "open:10" |
playerId | 채널에 입장한 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 1234 |
extraData | 유저 부가정보 (UTF-8 기준) (최대 256 Byte) | string | Y | e.g. "abcd" |
timestamp | 채널에 입장한 일시 (UTC+0 기준, yyyy-MM-dd'T'HH:mm:ss.SSSZ 형식) | string | Y | e.g. "2024-11-12T08:59:59.497Z" |
Sample¶
{
"packetType": "NOTIFY_ENTER_CHANNEL",
"body": {
"gameIndex": 1,
"channelId": "open:10",
"playerId": 1234,
"extraData": "abcd",
"timestamp": "2024-11-12T08:59:59.497Z"
}
}
채널 퇴장 메시지¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 채널 퇴장 메시지 (NOTIFY_EXIT_CHANNEL ) | string | Y |
body | 요청 데이터 | object | Y |
Body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
channelId | 퇴장한 채널 ID | string | Y | e.g. "open:10" |
playerId | 채널에서 퇴장한 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 2222 |
extraData | 유저 부가정보 (UTF-8 기준)(최대 256 Byte) | string | Y | e.g. "abcd" |
timestamp | 채널에서 퇴장한 일시 (UTC+0 기준, yyyy-MM-dd'T'HH:mm:ss.SSSZ 형식) | string | Y | e.g. "2024-11-12T08:59:59.497Z" |
Sample¶
{
"packetType": "NOTIFY_EXIT_CHANNEL",
"body": {
"gameIndex": 1,
"channelId": "open:10",
"playerId": 2222,
"extraData": "abcd",
"timestamp": "2024-11-12T09:29:35.872Z"
}
}
채널 삭제 메시지¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 채널 삭제 메시지 (NOTIFY_DELETE_CHANNEL ) | string | Y |
body | 요청 데이터 | object | Y |
Body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
channelId | 삭제한 채널 ID | string | Y | e.g. "open:10" |
timestamp | 채널을 삭제한 일시 (UTC+0 기준, yyyy-MM-dd'T'HH:mm:ss.SSSZ 형식) | string | Y | e.g. "2024-11-12T08:59:59.497Z" |
Sample¶
{
"packetType": "NOTIFY_DELETE_CHANNEL",
"body": {
"gameIndex": 1,
"channelId": "owner:1",
"timestamp": "2024-11-13T05:06:29.198Z"
}
}
채널 공지 메시지¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 공지 메시지 (NOTIFY_CHANNEL_NOTICE ) | string | Y |
body | 요청 데이터 | object | Y |
Body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
channelId | 공지 메시지 받은 채널 ID | string | N | e.g. "open:10" |
from | 공지 메시지 전송한 계정 식별자 | string | Y | e.g. SYSTEM |
message | 공지 메시지 내용 | string | Y | e.g. "공지 메시지 입니다." |
timestamp | 공지 메시지 전송한 일시 (UTC+0 기준, yyyy-MM-dd'T'HH:mm:ss.SSSZ 형식) | string | Y | e.g. "2024-11-13T05:06:29.198Z" |
Sample¶
// 특정 채널에 공지
{
"packetType": "NOTIFY_CHANNEL_NOTICE",
"body": {
"gameIndex": 1,
"channelId": "open:10",
"from": "SYSTEM",
"message": "공지 메시지 입니다.",
"timestamp": "2024-11-13T05:06:29.198Z"
}
}
채널 메시지¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 채널 메시지 (NOTIFY_CHANNEL_CHAT ) | string | Y |
body | 요청 데이터 | object | Y |
Body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
from | 채널 메시지 전송한 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 2222 |
fromExtra | 유저 부가정보 (UTF-8 기준)(최대 256 Byte) | string | Y | e.g. "bbbb" |
to | 채널 메시지 전송한 채널 ID | string | Y | e.g. "open:10" |
langCode | Hive 언어 코드 (ISO 639 alpha-2를 기준으로 하며 ISO 639 alpha-2로 구분되지 않는 언어는 Script tag를 붙여 구분) | string | Y | e.g. "ko" |
timestamp | 채널 메시지 전송한 일시 (UTC+0 기준, yyyy-MM-dd'T'HH:mm:ss.SSSZ 형식) | string | Y | e.g. "2024-11-13T05:12:18.385Z" |
Sample¶
{
"packetType": "NOTIFY_CHANNEL_CHAT",
"body": {
"gameIndex": 1,
"from": 2222,
"fromExtra": "bbbb",
"to": "open:10",
"message": "Hello World!",
"langCode": "ko",
"timestamp": "2024-11-13T05:12:18.385Z"
}
}
1:1 메시지¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 1:1 메시지 (NOTIFY_DIRECT_CHAT ) | string | Y |
body | 요청 데이터 | object | Y |
Body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
gameIndex | Hive 게임 인덱스 | integer | Y | e.g. 1 |
from | 1:1 메시지 전달 받은 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 1234 |
fromExtra | 유저 부가정보 (UTF-8 기준)(최대 256 Byte) | string | Y | e.g. "abcd" |
to | 1:1 메시지 전송한 계정 식별자 Hive 플레이어 ID | long | Y | e.g. 2222 |
message | 1:1 메시지 내용 | string | Y | e.g. "안녕하세요. 1:1 채팅입니다." |
langCode | Hive 언어 코드 (ISO 639 alpha-2를 기준으로 하며 ISO 639 alpha-2로 구분되지 않는 언어는 Script tag를 붙여 구분) | string | Y | e.g. "ko" |
timestamp | 1:1 메시지 전송한 일시 (UTC+0 기준, yyyy-MM-dd'T'HH:mm:ss.SSSZ 형식) | string | Y | e.g. "2024-11-13T05:12:50.060Z" |