WebSocket API
개요¶
WebSocket API는 Socket 서버와 WebSocket 통신하여 채팅 서비스를 제공합니다. 게임 클라이언트 접속, 채널 메시지 전송 등을 지원합니다.
WebSocket API의 주요 기능은 아래와 같습니다.
- 클라이언트 접속 / 해제
- PING / PONG
- 채팅 메시지 전송 / 수신
- 채널 채팅
- 1:1 채팅
- 차단한 사용자 필터링
- 차단한 사용자에게 메시지를 발신하지 않음
- 차단한 사용자로부터 메시지를 수신하지 않음
- 채널 입장, 퇴장 알림
기본 정보¶
WebSocket API 사용 시, 공통적으로 알아야 하는 기본 정보를 안내합니다.
주요 용어¶
- 채널: 채팅방
- 채널 메시지: 참여한 채널의 모든 사용자에게 전송하는 채팅 메시지
- 1:1 메시지: 특정 사용자에게만 전송하는 채팅 메시지
패킷 유형¶
Socket 서버와 전송 및 수신하는 패킷 유형은 아래와 같습니다.
패킷 명 | 설명 |
---|---|
CONNECT | Socket 서버 접속 |
RESPONSE_CONNECT | CONNECT 요청에 대한 응답 |
RECONNECT | Socket 서버 재연결 |
RESPONSE_RECONNECT | RECONNECT 요청에 대한 응답 |
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 연결 해제¶
WebSocket 연결을 해제하면 서버에서 다음 동작들을 수행합니다.
- 참여 중인 채널에서 퇴장 및 퇴장 알림메시지 전송
- 접속 정보 삭제
Socket 통신 구조¶
JSON 포맷으로 WebSocket 통신을 수행합니다. 요청 패킷 형식은 아래와 같습니다.
{
"packetType":"패킷 유형",
"correlationId":"요청에 대한 응답을 매칭하는 식별자",
"body": {
//packetType 에 따른 JSON 데이터
}
}
다음은 응답 패킷 형식입니다.
{
"packetType":"패킷 유형 (RESPONSE 로 시작)",
"correlationId":"요청에 대한 응답을 매칭하는 식별자",
"status":"상태 코드",
"message":"상태 메시지",
"body": // JSON Object
}
다음은 서버 메시지 패킷 형식입니다.
서버 측에서 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": "eyJhbGciOiJIUzI1NiJ9.eyJnYW1lSW5kZXgiOjEsInBsYXllcklkIjoxMjM0LCJpYXQiOjE3MzAzNjY4MjksImV4cCI6MTczMDM3MDQyOX0.fpg6kqwqp1QN3KuYcjVBr8j0mzjN2doefJ_D6xFxcFY", // API 서버에서 생성한 JWT
"extraData": "{\"nickname\":\"Test1234\",\"guildname\":\"together\"}" // 부가정보
}
}
Response sample¶
{
"packetType":"RESPONSE_CONNECT",
"status": 200,
"message":"OK",
"body":{
"sessionId":"005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76"
}
}
클라이언트 재연결¶
네트워크 상황에 따라 WebSocket 연결이 해제될 수 있으므로 재연결 기능을 제공합니다. WebSocket 연결 해제 후 10분 이내 RECONNECT
요청 시, 이전에 참여한 채널에 입장합니다.
Request parameters¶
필드명 | 설명 | 타입 | 필수 여부 |
---|---|---|---|
packetType | 클라이언트 재연결 명령어 (RECONNECT ) | 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_RECONNECT ) | string | Y |
status | 상태 코드 | integer | Y |
message | 상태 메시지 | string | Y |
body | 반환 데이터 | object | Y |
Response body > body¶
필드명 | 설명 | 타입 | 필수 여부 | 예시 |
---|---|---|---|---|
sessionId | 접속 성공 시 반환되는 값 | string | Y | e.g. "005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76" |
channelIds | 이전에 참여한 채널 중 입장에 성공한 채널 목록 | array | Y | e.g. ["ch:1", "ch:2"] |
failChannelIds | 이전에 참여한 채널 중 입장에 실패한 채널 목록 | array | Y | e.g. [] |
Request sample¶
{
"packetType": "RECONNECT",
"body":{
"gameIndex":1,
"playerId": 1234,
"loginKey": "eyJhbGciOiJIUzI1NiJ9.eyJnYW1lSW5kZXgiOjEsInBsYXllcklkIjoxMjM0LCJpYXQiOjE3MzAzNjY4MjksImV4cCI6MTczMDM3MDQyOX0.fpg6kqwqp1QN3KuYcjVBr8j0mzjN2doefJ_D6xFxcFY", // API 서버에서 생성한 JWT
"extraData": "{\"nickname\":\"Test1234\",\"guildname\":\"together\"}" // 부가정보
}
}
Response sample¶
{
"packetType":"RESPONSE_RECONNECT",
"status": 200,
"message":"OK",
"body":{
"sessionId":"005056fffea3fd10-000400fd-00000797-f67881178d98d1cd-64ae9a76",
"channelIds":["ch:1", "ch:2"], // 이전에 참여한 채널 중 입장에 성공한 채널 목록
"failChannelIds":[] // 이전에 참여한 채널 중 입장에 실패한 채널 목록
}
}
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" |