GS2-Inbox 트랜잭션 액션
액션의 조합과 동시 실행
모든 서비스에 공통되는 전제는 트랜잭션 액션의 조합에 정리되어 있습니다. 먼저 그쪽을 읽어 주십시오. 이 절의 나머지는 GS2-Inbox 고유의 내용입니다.
GS2-Inbox의 트랜잭션 액션은 네임스페이스·사용자·메시지의 조합으로 결정되는 한 통의 메시지를 대상으로 합니다. 발송은 항상 새로운 메시지를 만들므로, 발송할 때마다 다른 대상이 됩니다.
| 조작 | 같은 행을 겹쳤을 때 | 중첩 너머 | 다른 대상이 되는 경계 |
|---|---|---|---|
메시지의 발송SendMessageByUserId | 각각이 다른 메시지가 된다. 충돌하지 않는다 | 충돌하지 않는다 | 발송할 때마다 다른 대상 |
메시지의 개봉OpenMessageByUserId | 1건으로 통합된다 | 실패한다 | 네임스페이스·사용자·메시지 |
메시지의 삭제DeleteMessageByUserId | 1건으로 통합된다 | 실패한다 | 네임스페이스·사용자·메시지 |
개봉과 삭제는 행이 다르고 경계가 같습니다. 한 통의 메시지를 같은 트랜잭션에서 개봉하고 삭제할 수는 없습니다. 메시지가 다르면 다른 대상이므로, 여러 메시지를 개봉하거나 삭제하는 것은 문제없습니다.
트랜잭션에서 발송한 메시지는 그 트랜잭션의 다른 액션에서는 아직 존재하지 않는 것으로 취급됩니다. 모든 액션이 트랜잭션 시작 시점의 상태를 기준으로 동작하기 때문입니다. 메시지를 보낸 뒤 조작하고 싶은 경우에는 트랜잭션을 나누어 주십시오.
메시지의 개봉은 첨부된 것을 배분합니다. 그것들은 자신의 트랜잭션으로 발행되므로, 배분되는 것이 속한 서비스의 제한이 그대로 해당되며, 아래의 내용도 해당됩니다. 같은 아이템을 첨부한 두 통을 개봉하는 경우가 주의해야 할 케이스입니다.
중첩된 트랜잭션에 주의
안쪽에서 개봉된 메시지와 바깥쪽에서 삭제된 같은 메시지가 충돌하여 트랜잭션이 실패합니다. 개봉이 배분하는 것은 다른 액션과 같은 트랜잭션에 모이므로, 그것들이 속한 서비스의 페이지를 확인해 주십시오.
제한을 회피하고 싶은 경우
메시지의 발송은 획득 액션, 개봉과 삭제는 둘 다 소비 액션입니다. 그 때문에 acquireActionUseJobQueue로는 개봉과 삭제를 분리할 수 없으며, 해소하려면 enableAtomicCommit을 비활성화해야 합니다.
동시 실행과 재시도
발송은 요청이 몇 개 겹쳐도 충돌하지 않습니다. 발송할 때마다 자신의 메시지를 만들기 때문입니다.
개봉과 삭제는 메시지 전체에 대해 기록하므로, 같은 메시지에 대한 동시 업데이트가 있으면 나중에 확정된 쪽이 충돌(409)이 됩니다. 요청 내용에 문제가 있는 것은 아니므로, 재시도하면 성공합니다. 이미 개봉·삭제된 경우에는 재시도하면 그 취지의 오류가 반환됩니다.
Consume Action
소비 액션
Gs2Inbox:OpenMessageByUserId
사용자 ID를 지정하여 메시지를 개봉 완료로 표시
지정된 사용자의 수신함에 있는 지정된 메시지를 읽음(개봉 완료) 상태로 표시합니다.
이는 획득 액션을 실행하지 않고 isRead를 true로 설정하는 단순한 상태 전환입니다.
읽음 처리와 동시에 관련된 보상을 실행하려면 대신 Read API를 사용하십시오.
수량 지정 가능한 액션: 아니오
반전 가능한 액션: 아니오
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| userId | string | ✓ | ~ 128자 | 사용자ID#{userId}로 설정하면 로그인 중인 사용자ID로 치환됩니다. | ||
| messageName | string | ✓ | UUID | ~ 36자 | 메시지 이름 메시지의 고유한 이름을 유지합니다. 이름은 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 각 메시지를 식별하는 데 사용됩니다. | |
| timeOffsetToken | string | ~ 1024자 | 타임 오프셋 토큰 |
{
"action": "Gs2Inbox:OpenMessageByUserId",
"request": {
"namespaceName": "[string]네임스페이스 이름",
"userId": "[string]사용자ID",
"messageName": "[string]메시지 이름",
"timeOffsetToken": "[string]타임 오프셋 토큰"
}
}action: Gs2Inbox:OpenMessageByUserId
request:
namespaceName: "[string]네임스페이스 이름"
userId: "[string]사용자ID"
messageName: "[string]메시지 이름"
timeOffsetToken: "[string]타임 오프셋 토큰"transaction.service("inbox").consume.open_message_by_user_id({
namespaceName="[string]네임스페이스 이름",
userId="[string]사용자ID",
messageName="[string]메시지 이름",
timeOffsetToken="[string]타임 오프셋 토큰",
})Gs2Inbox:DeleteMessageByUserId
사용자 ID를 지정하여 메시지 삭제
지정된 사용자의 받은 편지함에서 메시지를 완전히 삭제합니다.
읽음 상태와 관계없이 메시지 레코드가 삭제됩니다.
수량 지정 가능한 액션: 아니오
반전 가능한 액션: 아니오
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| userId | string | ✓ | ~ 128자 | 사용자ID#{userId}로 설정하면 로그인 중인 사용자ID로 치환됩니다. | ||
| messageName | string | ✓ | UUID | ~ 36자 | 메시지 이름 메시지의 고유한 이름을 유지합니다. 이름은 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 각 메시지를 식별하는 데 사용됩니다. | |
| timeOffsetToken | string | ~ 1024자 | 타임 오프셋 토큰 |
{
"action": "Gs2Inbox:DeleteMessageByUserId",
"request": {
"namespaceName": "[string]네임스페이스 이름",
"userId": "[string]사용자ID",
"messageName": "[string]메시지 이름",
"timeOffsetToken": "[string]타임 오프셋 토큰"
}
}action: Gs2Inbox:DeleteMessageByUserId
request:
namespaceName: "[string]네임스페이스 이름"
userId: "[string]사용자ID"
messageName: "[string]메시지 이름"
timeOffsetToken: "[string]타임 오프셋 토큰"transaction.service("inbox").consume.delete_message_by_user_id({
namespaceName="[string]네임스페이스 이름",
userId="[string]사용자ID",
messageName="[string]메시지 이름",
timeOffsetToken="[string]타임 오프셋 토큰",
})Acquire Action
입수 액션
Gs2Inbox:SendMessageByUserId
사용자 ID를 지정하여 메시지 발신
지정된 사용자의 수신함에 새로운 메시지를 생성하여 전달합니다.
메시지에는 메타데이터(임의의 JSON 콘텐츠)와 readAcquireActions(메시지 개봉 시 부여되는 보상)를 포함할 수 있습니다.
메시지의 유효기간은 절대 타임스탬프(expiresAt) 또는 전달 시점부터의 상대적인 기간(expiresTimeSpan)으로 설정할 수 있습니다. expiresAt가 지정된 경우 expiresTimeSpan보다 우선 적용됩니다.
메시지는 읽지 않은 상태(isRead=false)로 시작됩니다.
수량 지정 가능한 액션: 아니오
반전 가능한 액션: 아니오
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| userId | string | ✓ | ~ 128자 | 사용자ID#{userId}로 설정하면 로그인 중인 사용자ID로 치환됩니다. | ||
| metadata | string | ✓ | ~ 4096자 | 메타데이터 메시지의 제목, 본문, 발신자 정보, 표시 파라미터 등을 포함하는 JSON 문자열 등, 메시지의 내용을 나타내는 임의의 데이터입니다. GS2는 이 값을 해석하지 않으며, 메시지 UI 렌더링을 위해 게임 클라이언트에 그대로 전달됩니다. 최대 4096자입니다. | ||
| readAcquireActions | List<AcquireAction> | [] | 0 ~ 100 items | 개봉 시 입수 액션 사용자가 이 메시지를 개봉했을 때 실행되는 입수 액션 목록입니다. 아이템, 화폐, 리소스 등의 보상을 메시지에 첨부하기 위해 사용됩니다. 여러 액션을 조합하여 서로 다른 종류의 보상을 동시에 지급할 수 있습니다. 메시지당 최대 100개의 액션입니다. | ||
| expiresAt | long | 유효기간 일시 UNIX 시간·밀리초 | ||||
| expiresTimeSpan | TimeSpan | 메시지를 수신한 시각(기준 시각)부터 메시지가 삭제될 때까지의 기간 | ||||
| timeOffsetToken | string | ~ 1024자 | 타임 오프셋 토큰 |
{
"action": "Gs2Inbox:SendMessageByUserId",
"request": {
"namespaceName": "[string]네임스페이스 이름",
"userId": "[string]사용자ID",
"metadata": "[string]메타데이터",
"readAcquireActions": [
{
"action": "[string]입수 액션에서 실행할 액션의 종류",
"request": "[string]액션 실행 시 사용되는 요청의 JSON 문자열"
}
],
"expiresAt": "[long]유효기간 일시",
"expiresTimeSpan": {
"days": "[int]일수",
"hours": "[int]시간",
"minutes": "[int]분"
},
"timeOffsetToken": "[string]타임 오프셋 토큰"
}
}action: Gs2Inbox:SendMessageByUserId
request:
namespaceName: "[string]네임스페이스 이름"
userId: "[string]사용자ID"
metadata: "[string]메타데이터"
readAcquireActions:
- action: "[string]입수 액션에서 실행할 액션의 종류"
request: "[string]액션 실행 시 사용되는 요청의 JSON 문자열"
expiresAt: "[long]유효기간 일시"
expiresTimeSpan:
days: "[int]일수"
hours: "[int]시간"
minutes: "[int]분"
timeOffsetToken: "[string]타임 오프셋 토큰"transaction.service("inbox").acquire.send_message_by_user_id({
namespaceName="[string]네임스페이스 이름",
userId="[string]사용자ID",
metadata="[string]메타데이터",
readAcquireActions={
{
action="[string]입수 액션에서 실행할 액션의 종류",
request="[string]액션 실행 시 사용되는 요청의 JSON 문자열"
}
},
expiresAt="[long]유효기간 일시",
expiresTimeSpan={
days="[int]일수",
hours="[int]시간",
minutes="[int]분"
},
timeOffsetToken="[string]타임 오프셋 토큰",
})