멀티플레이어 세션 디렉터리
이 문서에서는 Xbox 360 이후 플랫폼에서 Xbox 서비스 멀티 플레이어 세션 디렉터리(MPSD) 서비스를 사용하여 멀티 플레이 세션을 만드는 방법에 대한 개요를 제공합니다.
이 문서는 주로 세션 템플릿을 파트너 센터에 바로 제출하는 Xbox 타이틀 개발자를 대상으로 합니다.
이 문서는 멀티 플레이어 세션의 MPSD 구성, 사용, 문제 해결을 다룹니다.
목차:
- 수정 요약
- 소개
- 이 문서에서 사용되는 용어
- 멀티 플레이어 세션 디렉터리
- MPSD 세션
- 세션 템플릿 특성
- 계약 스키마 업데이트
- 세션 문서에서 멤버 초기화
- 매치 티켓 세션
- 서비스 품질(QoS) 템플릿
- QoS 단계 및 세션 초기화 세부 정보
- Xbox 클라우드 컴퓨팅 세션
- 원시 세션 및 사용자 지정 타이틀 속성
- 활성 멤버 감소
- FAQ 및 문제 해결
수정 요약
클라이언트 쪽 XSAPI(Xbox Services API) 라이브러리는 현재 MPSD 서비스와 통신할 때 계약 버전 104를 사용합니다. 이 문서 버전은 세션 템플릿 스키마를 MPSD 서비스가 지원하는 최신 계약 버전인 계약 버전 107로 업데이트합니다. 버전 104와 107의 차이는 아래의 계약 스키마 업데이트 섹션에 요약되어 있습니다.
계약 버전 104용으로 작성한 템플릿을 버전 107용으로 다시 퍼블리싱하려면 템플릿을 업데이트해야 합니다. 하지만 서비스는 이전 버전과 호환되기 때문에 현재 라이브러리를 계속 사용할 수 있습니다. 라이브러리는 향후 릴리스에서 업데이트될 예정입니다.
이 문서의 이전 개정판은 서버 세션에 관한 정보를 업데이트하고 XSAPI 및 RESTful 서비스 호출에 대한 새 섹션을 추가했습니다. 또한 세션 상태 정보 쿼리(Query for Session State Information) 섹션을 업데이트하고 서비스 품질(QoS) 템플릿 섹션을 수정했습니다.
소개
멀티 플레이어 세션은 MPSD(멀티 플레이어 세션 디렉토리)의 클라우드에 있는 보안 문서로, 이 문서는 게임을 진행하는 사용자 그룹을 나타냅니다. 특히 멀티 플레이어 세션에는 다음과 같은 특징이 있습니다.
각 세션에는 고유한 URI가 있습니다.
세션 문서에는 현재 멤버, 게임 설정, 부트스트랩 데이터, 게임 서버 정보가 포함됩니다.
타이틀이 자체 세션을 만들고 관리합니다.
세션은 멤버 간 연결을 활성화합니다.
멀티 플레이어 세션 디렉터리(MPSD)는 모든 클라이언트의 게임 세션 메타데이터를 중앙 집중화합니다. MPSD는 클라이언트 간의 안전한 장치 연결을 설정하는 데 도움이 되는, 세션 관련 기본 정보를 제공합니다.
또한 MPSD는 클라이언트에서 게임에 연결할 수 있는 기본 첫 번째 부팅 메타데이터를 제공하기 때문에 더 구체적인 게임 데이터가 전달되기 시작합니다.
PLM(프로세스 수명 관리) 및 Xbox One 이상의 응용 프로그램에 대한 작업 전환 특성이 있는 경우 MPSD는 클라이언트에게 활성화된 게임 세션의 일부로 식별되는 피어 및 서버에 대한 올바른 정보를 포함하고, 셸 및 콘솔 운영 체제를 사용하여 게임 세션에 대한 플레이어 수명을 예약하고 활성화하고 관리하는 데 필요한 정보를 확인합니다.
이 문서에서 사용되는 용어
용어 | 정의 |
---|---|
멀티 플레이어 세션 | Xbox 서비스 클라우드에 상주하며 Xbox One 이상(PC 포함)에서 타이틀을 플레이하는 동안 함께 연결되어 있거나 연결될 사용자 그룹을 나타내는 보안 문서입니다. 매치 메이킹, 파티, 진행 상황에 대한 참여와 같은 멀티 플레이어 세션에 대한 모든 측면이 멀티 플레이어 세션을 활용합니다. |
게임 세션 | 이것은 사용자들이 함께 플레이하는 곳인 MPSD에 노출되는 실제 게임 세션입니다. 모든 멀티 플레이어 시나리오는 결과적으로 게임 세션이 됩니다. |
매치 티켓 세션 | 매치 메이킹 과정에서 매치 티켓 제출을 추적하는 데 사용하는 세션입니다. |
비활성 플레이어 | 세션 내에서 비활성 상태로 설정된 플레이어입니다. 게임이 제한되거나, 일시 중단되거나, 타이틀에서 정의한 바에 따라 비활성 상태가 되면 타이틀은 사용자를 비활성 상태로 설정합니다. |
멀티 플레이어 세션 디렉터리
MPSD는 타이틀이 온라인 플레이어 간의 세션 정보를 조정하도록 지원합니다. 여러 유형의 세션에서 다양한 멀티 플레이어 플레이를 할 수 있습니다.
다음 표에는 Xbox 360에서 이러한 작업이 수행되는 방식, 그리고 Xbox One 이상 버전(PC 포함)에서 수행되는 방식의 차이점을 설명합니다.
함수 또는 작업 | Xbox 360 | Xbox One 이상 |
---|---|---|
게임 세션 정보 가져오기 | XSessionGetDetails, XSessionSearchByID를 이용하거나 수동으로 추적합니다. | 서비스에서 세션 정보를 요청합니다. |
호스트 마이그레이션 | 필요한 경우 타이틀이 XSessionMigrateHost를 호출합니다. | 새 세션을 만들 필요는 없습니다. 새 호스트를 SessionID에 할당하기만 하면 됩니다. |
멀티 플레이어 세션 관리 | 한 번에 여러 세션을 처리하는 일은 쉽지 않습니다. 예를 들어 XNetReplaceKey와 XNetUnregisterKey를 비교해 보세요. | 서비스 기반 세션을 이용하면 단일 세션 관리가 더 명확해지고, 여러 세션을 쉽게 처리할 수 있습니다. |
로그아웃 및 연결 해제 처리 | 연결 해제와 로그아웃을 다르게 처리해야 합니다. 각각 XCloseHandle과 XSessionDelete를 이용합니다. | 중앙 집중식 서비스는 로그아웃과 연결 해제 처리를 단순화하며, 게임 구성에서 시간 제한을 설정합니다. |
세션 패턴
게임 세션
플레이어의 XUID, 보안 장치 주소 데이터 및 속성 상태가 포함된 세션. 이는 실제 게임 플레이 세션으로 여겨집니다.
피어 투 피어, 피어 투 호스트, 피어 투 서버 또는 하이브리드 형식입니다.
매치 티켓 세션
- 함께 플레이할 다른 플레이어를 찾고자 매치 메이킹에 제출된 세션입니다. 게임이 추가 플레이어를 찾는다면, 게임 세션은 티켓 세션이 되기도 합니다.
서버 세션
- Xbox 컴퓨팅 처리를 통해 생성되고 사용되는 게임 세션입니다.
그림 1은 MPSD 세션 사용을 설명합니다. 여기서 파란색 상자는 MPSD 세션을 의미하며 빨간색 상자는 이 세션을 사용하는 서비스입니다.
그림 1. MPSD 세션 사용. (그림 누락)
MPSD 세션
세션은 관련 엔터티 목록 2개를 유지합니다.
세션에 참가하거나 초대된 멤버(사용자)입니다.
세션에 참가한 서버(클라우드 서버 또는 전용 서버)입니다.
각 엔터티에는 다음이 존재합니다.
생성 시점에서 설정한 상수 값.
변경 가능한 속성.
읽기 전용 메타데이터.
XSAPIs 및 RESTful 서비스 호출
Xbox 서비스 세션 및 매치 메이킹 서비스와 상호 작용하는 방법에는 두 가지가 있습니다.
- 표준 HTTPs 호출
- XSAPI 래퍼
RESTful 서비스에 대한 표준 HTTPS 호출을 사용
Xbox One 이상의 경우 Xbox 서비스 세션 및 매치 메이킹 서비스와 인터페이스하는 첫 번째 방법은 RESTful Xbox 서비스 URI에 대한 표준 HTTPS 호출을 사용하는 것입니다. 이렇게 하면 서버 및 게임 구성에 따라 해당 서비스와의 호출 및 접속에 유연성을 부여합니다.
이러한 URI 목록은 Xbox 서비스 RESTful 참조를 참조하세요.
RESTful 서비스에 XSAPI 래퍼 사용
세션 및 매치메이킹 서비스와 인터페이스하는 두 번째 방법은 RESTful 서비스 URI의 래퍼 역할을 하는 XSAPI를 사용하는 것입니다. 이렇게 하면 각 호출에 대한 HTTPS 트래픽을 처리할 필요 없이 보다 전통적인 방식으로 코드의 API를 사용할 수 있습니다.
XSAPIs에 대한 자세한 내용은 xbox-live-api GitHub 페이지를 참조하세요.
참조 문서에는 다음이 포함됩니다.
- JSON 구문 분석 API 참조 - JSON 구문 분석 API에 대한 참고자료
- Windows. 웹 네임스페이스 - Windows. 웹 네임스페이스 구성원.
- Xbox Compute SDK 참조 - Xbox Compute 게임 서버 인스턴스를 만들기 위한 API.
MPSD 세션 및 템플릿
MPSD 세션은 파트너 센터를 통해 수집한 템플릿으로 만듭니다. 템플릿은 생성 중인 세션의 프레임워크를 정의하는 JSON 문서입니다. 템플릿은 새로운 세션에 상수를 제공합니다.
다음의 인용은 템플릿 구성 예제입니다.
// Used for creating the session that you then pass into your match ticket request. This *should* not have any QoS requirements.
MatchTicketSession (Contract Version: 107)
{
"constants": {
"system": {
"version": 1,
"maxMembersCount": 10,
"visibility": "private",
"capabilities": {},
"memberInitialization": {
"joinTimeout": 20000,
"externalEvaluation": false,
"membersNeededToStart": 1
}
},
"custom": {}
}
}
// This is the new game session that is returned after you've been matched.
// Note: This is used for in-game QoS. For out-of-game QoS, you will need P2P/HTP requirements.
GameSession (Contract Version:107)
{
"constants": {
"system": {
"maxMembersCount": 12,
"capabilities": {"connectivity": true }
},
"memberInitialization": {
"joinTimeout": 20000,
"measurementTimeout": 15000,
"externalEvaluation": false,
"membersNeededToStart": 4
},
"custom": {}
}
}
매치 티켓 세션은 memberInitialization 개체의 QoS 시간 제한 값으로 설정한 게임 세션 템플릿과 함께 사용해야 합니다.
그림 2. 샘플 호퍼:
다음의 코드 발췌는 QoS가 적용되는 피어 투 피어 게임 세션 템플릿(타이틀 관리 Qos)의 예입니다.
{
"constants": {
"system": {
"version": 1,
"maxMembersCount": 10,
"visibility": "private",
"capabilities": {
"connectivity": true
},
"memberInitialization": {
"joinTimeout": 20000,
"externalEvaluation": false,
"membersNeededToStart": 2
}
},
"custom": {}
}
}
이것은 피어 투 서버 세션 및 RAW 템플릿 예제입니다.
{
"constants": {
"system": {
"version": 1,
"maxMembersCount": 10,
"visibility": "private",
"capabilities": {}
},
"custom": {}
}
}
다음 코드는 Smart Match에 사용하는 매치 티켓 템플릿 예제를 보여줍니다.
{
"constants": {
"system": {
"version": 1,
"maxMembersCount": 10,
"visibility": "private",
"capabilities": {},
"memberInitialization": {
"joinTimeout": 20000,
"externalEvaluation": false,
"membersNeededToStart": 1
}
},
"custom": {}
}
}
SCID에 구성된 템플릿 확인
세션 템플릿
SCID에 존재하는 세션 템플릿 목록과 특정 세션 템플릿 세부 사항은 MPSD에서 검색할 수 있습니다.
GET /serviceconfigs/{scid}/sessiontemplates
GET /serviceconfigs/{scid}/sessiontemplates/{session-template-name}
세션 상태 정보 쿼리
세션은 서비스 구성 및 세션 템플릿 수준에서 쿼리할 수 있습니다.
GET /serviceconfigs/{scid}/sessions
GET /serviceconfigs/{scid}/sessiontemplates/{session-template-name}/sessions
기본적으로 최대 100개의 비공개가 아닌 세션을 반환합니다. 이러한 쿼리 문자열 매개 변수를 사용하여 쿼리를 수정할 수 있습니다.
쿼리 문자열 | 효과 | 설명 |
---|---|---|
keyword=foo | "foo" 키워드가 포함된 세션만 포함합니다. | |
XUID=123 | 사용자 “123”이 있는 세션만 포함합니다. | 기본적으로 사용자는 포함될 세션에서 활성화되어 있어야 합니다. |
reservations=true | 사용자가 예약된 플레이어로 설정되어 있지만 참여하고 있는 상태가 아닌 세션을 포함합니다. | 자체 세션을 쿼리하거나 서버 간에 특정 사용자의 세션을 쿼리할 때만 유효합니다. |
inactive=true | 사용자가 수락했지만 현재 실행하지 않는 세션을 포함합니다. | 사용자가 "준비"되었지만 "활성화"되지 않은 세션을 비활성으로 할 수 있습니다. |
private=true | 개인 세션을 포함합니다. | 자체 세션을 쿼리하거나 서버 간에 쿼리할 때만 유효합니다. |
visibility=open | “open”인 세션만 포함합니다. | "private"으로 설정된 경우 "private=true" 지시문도 설정해야 합니다. |
take=5 | 최대 5개 세션 전으로 돌아갑니다. | 0~100 사이여야 합니다. |
결과는 세션 참조의 JSON 배열이 됩니다. 일부 세션 데이터는 인라인으로 포함됩니다.
참고 모든 쿼리에는 키워드 필터, XUID 필터 또는 두 필터 모두가 포함되어야 합니다.
private(개인 세션 반환)이나 reservations(사용자가 참가하지 않은 세션 반환)를 true로 설정하려면 호출자는 세션에 대한 서버 수준 액세스 권한이 있거나, URI의 XUID 필터와 일치하는 호출자의 XUID 클레임에 대한 액세스 권한이 있어야 합니다. 그렇지 않으면 (이러한 세션의 존재 여부에 관계없이) 403 Forbidden이 반환됩니다.
다음 코드 발췌는 쿼리 응답 예제를 보여줍니다.
{
"results": [ {
"xuid": "9876", // If the session was found from a xuid, that xuid.
"startTime": "2009-06-15T13:45:30.0900000Z",
"sessionRef": {
"scid": "foo",
"templateName": "bar",
"name": "session-seven"
},
"accepted": 4, // Approximate number of non-reserved members.
"status": "active", // or "reserved" or "inactive". This is the state of the user in the session, not the session itself. Only present if the session was found using a xuid.
"visibility": "open", // or "private", "visible", or "full"
"myTurn": true, // Not present is the same as 'false'. Only present if the session was found using a xuid.
"keywords": [ "one", "two" ]
} ]
}
세션 템플릿 특성
계약 스키마 업데이트
본 문서 시작 부분에 언급했듯이, 최신 세션 템플릿 계약 버전은 107입니다. 이 버전은 이전 버전인 104의 스키마에 몇 가지 변경 사항을 적용합니다. 계약 버전 104용으로 작성한 템플릿을 버전 107용으로 다시 퍼블리싱하려면 템플릿을 업데이트해야 합니다.
다음은 이러한 변경 사항을 요약한 내용입니다.
/constants/system/managedInitialization을 /constants/system/memberInitialization으로 변경했습니다.
autoEvaluate 필드 이름을 externalEvaluation으로 변경하고 극성을 바꿨습니다. 단 false는 기본값을 유지합니다.
membersNeededToStart의 기본값을 2에서 1로 변경했습니다.
joinTimeout 기본값을 5초에서 10초로 변경했습니다.
measurementTimeout 기본값을 5초에서 30초로 변경했습니다.
/constants/system/timeouts를 제거했고, 시간 제한의 이름을 변경한 후 /constants/system으로 옮겼습니다.
reserved 시간 제한이 reservedRemovalTimeout으로 변경되었습니다.
inactive 시간 제한이 inactiveRemovalTimeout으로 변경되었고 새로운 기본값이 2시간이 아닌 0시간으로 설정되었습니다.
ready 시간 제한이 readyRemovalTimeout으로 변경되었습니다.
sessionEmpty 시간 제한이 sessionEmptyTimeout으로 변경되었습니다.
최신 플레이어 및 평판 보고를 활성화하려면 (매치 및 로비 세션 같은 도우미 세션과는 다른) 실제 게임 플레이를 나타내는 세션에서 /constants/system/capabilities/gameplay를 true로 지정해야 합니다.
시스템 개체
세션 문서에서 다루는 각 시스템 개체에는 MPSD가 적용 및 해석하는 고정된 스키마가 있습니다.
PUT 요청의 본문에서 시스템 개체를 사용자 지정 개체처럼 확인하고 병합합니다. 하지만 사용자 지정 개체와는 달리, 시스템 개체는 병합이 끝나면 추가 확인 후 이러한 스키마를 기준으로 작동합니다.
/constants/system
{
"version": 1, //Document Version (FAL release version 1, service contract 107)
"maxMembersCount": 100, // Defaults to 100 if not set on creation. Must be between 1 and 100.
"visibility": "private", // Or "visible" or "open", defaults to "open" if not set on creation.
"initiators": [ "1234" ], // If specified on a new session, the creators xuid must be in the list (or the creator must be a server).
"inviteProtocol": "party", // Optional URI scheme of the launch URI for invite toasts.
"reservedRemovalTimeout": 10000, // Default is 30 seconds. Member is removed from the session.
"inactiveRemovalTimeout": 0, // Default is zero. Member is removed from the session.
"readyRemovalTimeout": 60000, // Default is three minutes. Member is removed from the session.
"sessionEmptyTimeout": 0, // Default is zero. Session is deleted.
// Capabilities are boolean values that are optionally set in the session template. If no capabilities are needed, an empty "capabilities" object should be in the template in order to prevent capabilities from being specified on session creation, unless the title desires dynamic session capabilities.
"capabilities": {
"clientMatchmaking": true,
"connectivity": true, // Cannot be set if 'large' is specified.
"suppressPresenceActivityCheck": false,
"gameplay": false,
"large": false
},
/* If a "memberInitialization" object is set, the session expects the client system or title to perform initialization following session creation and/or as new members join the session. The timeouts and initialization stages are automatically tracked by the session, including QoS measurements if any metrics are set. These timeouts override the session's reservation and ready timeouts for members that have 'initializationEpisode' set. */
"memberInitialization": {
"joinTimeout": 20000, // Milliseconds. Unspecified counts as 10 seconds.
"externalEvaluation": false,
"membersNeededToStart": 2 // Unspecified counts as 1. Must be between 0 and maxMembersCount. Only applies to episode 1. If 00 and the session is created with no members to initialize, episode 1 is skipped..
},
/properties/system
{
// Optional array of case-insensitive strings. Cannot be set if the session's visibility is "private".
"keywords": [ "hello" ],
// Array of integer indices of members whose turn it is. Defaults to empty. Can't be set (and doesn't appear) on large sessions.
"turn": [ 0 ],
/* Restricts who can join "open" sessions. (Has no effect on reservations, which means it has no impact on "private" and "visible" sessions.) Defaults to "none". On large sessions, "none" is the only valid value.
If "local", only users whose token's DeviceId matches someone else already in the session and "active": true.
If "followed", only local users (as defined above) and users who are followed by an existing (not reserved) member of the session can join without a reservation. */
"joinRestriction": "none",
// Device token of the host. Must match the "deviceToken" of at least one member, otherwise this field is deleted.
// If "peerToHostRequirements" is set and "host" is set, the measurement stage assumes the given host is the correct host and only measures metrics to that host.
// Can't be set on large sessions.
"host": "99e4c701",
// Can only be set while "initializing/stage" is "evaluating". True indicates success, and false indicates failure. Once set, "initializing/stage" is immediately updated, and this field is removed.
"initializationSucceeded": true,
/* The ordered list of case-insensitive connection strings that the session could use to connect to a game server. Generally titles should use the first on the list, but sophisticated titles could use a custom mechanism (e.g. Thunderhead) for choosing one of the others (e.g. based on load). */
"serverConnectionStringCandidates": [ "datacenter b", "serverfarm a" ],
"matchmaking": {
"targetSessionConstants": { },
// Force a specific connection string to be used (useful in preserveSession=always cases).
"serverConnectionString": "datacenter b",
},
// True if the match that was found didn't work out and needs to be resubmitted. Set to false to signal that the match did work, and the matchmaking service can release the session.
"matchmakingResubmit": true
}
시간 제한
세션은 타이머 및 기타 외부 이벤트에 의해 변경될 수 있습니다. MPSD의 Timeouts 개체는 세션 수명 및 멤버 관리를 위한 기본 메커니즘을 제공합니다.
세션의 nextTimer 필드는 다음 타이머 시간을 제공합니다. 클라이언트는 이 정보를 이용해 다음 설문을 진행할 적절한 기간을 결정합니다. 이 값은 Expires HTTP 헤더에서도 반환됩니다.
시간 제한은 밀리초 단위로 지정됩니다. 0을 사용할 수 있으며 시간 제한이 즉시 수행되어야 함을 나타냅니다.
시간 제한을 지정하지 않으면 무한으로 간주됩니다. 제한 시간에는 기본값이 있기 때문에 무한 제한 시간의 경우 세션 템플릿은 명시적으로 null을 지정해야 합니다.
SessionEmptyTimeout
/constants/system/sessionEmptyTimeout 값은 빈 세션이 삭제될 때까지 걸리는 시간을 밀리초 단위 숫자로 설정합니다. 기본값은 0으로, 세션이 즉시 삭제된다는 뜻입니다. 값을 지정하지 않으면 빈 세션이 무한대로 유지됩니다.
멤버 시간 제한
/constants/system에 있는 다른 3가지 시간 제한으로 멤버가 특정 상태를 유지할 수 있는 시간을 제어합니다.
reservedRemovalTimeout
- 시간 제한이 끝나면 예약이 삭제됩니다. 기본값은 30초입니다.
inactiveRemovalTimeout
- 비활성 멤버는 기본적으로 2시간 후 세션에서 제거됩니다.
readyRemovalTimeout
- "준비"된 구성원은 기본적으로 3분 후에 비활성 상태로 돌아갑니다.
세션 문서에서 멤버 초기화
멤버 초기화
memberInitialization 개체는 세션을 만들거나 신규 멤버가 세션에 참가한 후의 초기화 단계를 제어합니다. 시간 초과 및 초기화 단계는 QoS 측정을 포함하여(메트릭이 설정된 경우) 세션에서 자동으로 추적됩니다.
이러한 시간 제한은 initializationEpisode 속성 집합이 설정된 구성원에 대해 세션의 예약 및 준비 시간 제한을 재정의합니다.
예:
"memberInitialization": {
"joinTimeout": 5000,
"measurementTimeout": 5000,
"evaluationTimeout": 5000, // only specify for external evaluation
"externalEvaluation": true,
"membersNeededToStart": 2
},
그림 3. 멤버 초기화 흐름:
멤버 초기화의 세 단계를 각각 수행하면 시간이 초과될 수 있습니다.
joiningTimeout
- 사용자가 세션에 참가해야 하는 시간(밀리초)입니다. 참가에 실패한 멤버의 예약은 삭제됩니다.
measuringTimeout
- 멤버가 자신의 측정값을 업로드해야 하는 시간입니다. 측정값을 업로드하지 못하는 멤버에는 'timeout'이라는 failureReason이 표시됩니다.
evaluationTimeout
- 멤버가 평가 결정을 내리고 업로드하는 시간입니다. 어떠한 결정도 수신되지 않으면 실패로 간주됩니다.
externalEvaluation
- MPSD는 세션 템플릿에 제공된 요건을 바탕으로 자동 QoS 평가를 수행할 수 있습니다. 평가는 externalEvaluation을 false로 설정하면 수행됩니다. evaluationTimeout을 설정하면 externalEvaluation은 true여야 합니다. 피어 투 피어 또는 피어 투 호스트 요건 2개가 있더라도 externalEvaluation을 false로 설정해야 세션이 초기화를 자동으로 완료할 수 있습니다.
membersNeededToStart
- 자동 평가를 진행하기 위해 “Initialize”:“true”로 존재하고 QoS를 통과해야 하는 최소 구성원의 예약 횟수입니다.
초기화 에피소드
memberInitialization 개체를 설정하면 MPSD는 초기화 단계를 에피소드별로 진행합니다. 첫 번째 에피소드는 세션을 만들 때 시작하며 템플릿에서 정의한 단계를 모두 포함합니다.
에피소드가 실행 중일 때 초대 받거나 참가한 신규 멤버는 다음 에피소드에 처리한다고 표시됩니다. 에피소드 또는 일반적인 memberInitialization의 상태는 세션의 initializing 개체에서 검색할 수 있습니다.
참고 이 개체는 초기화가 끝나면 제거됩니다.
예:
"initializing": {
"stage": "measuring",
"stageStartTime": "2009-06-15T13:45:30.0900000Z",
"episode": 1
},
단계는 참가에서 측정을 거쳐 평가로 이동합니다. 에피소드가 실패하면 단계가 failed로 설정되며 세션을 초기화할 수 없습니다. 에피소드 초기화가 성공하면 초기화 에피소드가 완료되고 initializing 개체가 제거됩니다.
초기화 실패 역시 멤버 별로 추적할 수 있습니다. 이 멤버가 통과하지 못하며, 참가 또는 측정 단계 외부로 전환될 때 초기화 실패가 설정됩니다.
예:
"initializationFailure": "latency",
우선 순위에 따라 이 특성의 값을 timeout, latency, bandwidthdown, bandwidthup, network, group이나 episode로 설정할 수 있습니다. 이 네트워크 값은 네트워크 구성 및/또는 조건(예: 충돌하는 네트워크 주소 변환 [NAT]) 때문에 QoS 메트릭을 측정할 수 없음을 의미합니다.
참가의 끝부분에는 group 값만 사용할 수 있습니다. (참가에서 시간 초과가 발생하면 예약이 제거됩니다.)
memberInitialization이 설정되었고 맴버가 "initialize": true로 추가되었다면, 멤버가 참여할 초기화 에피소드로 설정됩니다. 값 1은 새 세션을 만들 때 추가된 멤버에 사용하며, 초기화 에피소드가 끝나면 제거됩니다.
"initializationEpisode": 1,
매치 티켓 세션
MPSD 세션을 매치 티켓 세션으로 사용하면, 특수한 세션 속성 및 상수가 사용됩니다.
/members/{index}/constants/system
{
{
"xuid": "12345678",
"initialize": "false", // Run initialization for this user (if "memberInitialization" is set). Defaults to false.
매치 메이킹 서비스가 사용자를 세션에 추가하면, 사용자를 세션에 매칭한 방법과 이유에 관한 정보가 matchmakingResult 필드에 제공됩니다.
"matchmakingResult": {
매치 메이킹 세션에서 가져온 사용자의 serverMeasurements 복사본입니다.
"serverMeasurements": {
"east.thunderhead.azure.com": {
"latency": 233 // Milliseconds
}
}
}
}
서비스 품질(QoS) 템플릿
게임 세션 템플릿에서는 값을 추가해 MPSD에게 네트워크 계층과 콘솔 소셜 기능을 조정해야 한다고 알릴 수 있습니다. 이러한 조정의 목적은 세션을 만들기 전에, 그리고 사용자에게 게임에 참가할 수 있음을 알리기 전에 연결 상태 품질을 확인하는 것입니다.
아래 코드 발췌는 QoS가 적용되는 피어 투 호스트 게임 세션 템플릿의 예입니다.
{
"constants": {
"system": {
"version": 1,
"maxMembersCount": 20,
"visibility": "private",
"capabilities": {
"connectivity": true
},
"memberInitialization": {
"joinTimeout": 20000,
"externalEvaluation": false,
"membersNeededToStart": 1
},
"peerToHostRequirements": {
"latencyMaximum": 350,
"bandwidthDownMinimum": 1000,
"bandwidthUpMinimum": 100,
"hostSelectionMetric": "latency"
}
},
"custom": {}
}
}
이 코드 발췌는 QoS가 적용되는 피어 투 피어 게임 세션 템플릿의 예입니다.
{
"constants": {
"system": {
"version": 1,
"maxMembersCount": 20,
"visibility": "private",
"capabilities": {
"connectivity": true
},
"memberInitialization": {
"joinTimeout": 20000,
"externalEvaluation": false,
"membersNeededToStart": 1
},
"peerToPeerRequirements": {
"latencyMaximum": 250,
"bandwidthMinimum": 10000
}
},
"custom": {}
}
}
QoS 세션 템플릿 특성
memberInitialization 개체가 설정된 경우 세션은 클라이언트 시스템 또는 타이틀이 세션 생성 후 및/또는 새 멤버가 세션에 참여할 때 초기화를 수행할 것으로 예상합니다.
시간 초과 및 초기화 단계는 QoS 측정을 포함하여(메트릭이 설정된 경우) 세션에서 자동으로 추적됩니다.
이러한 시간 제한은 initializationEpisode 속성 집합이 설정된 구성원에 대해 세션의 예약 및 준비 시간 제한을 재정의합니다.
"memberInitialization": {
"joinTimeout": 5000, // Milliseconds. Unspecified counts as 10 seconds.
"measurementTimeout": 5000, // Milliseconds. Unspecified counts as 30 seconds.
"evaluationTimeout": 5000, // Milliseconds. Can only be set if 'externalEvaluation' is true. Unspecified counts as 5 seconds.
"externalEvaluation": true,
"membersNeededToStart": 2 // Unspecified counts as 1. Must be between 0 and maxMembersCount. Only applies to episode 1. If 0 and the session is created with no members to initialize, episode 1 is skipped.
},
QoS를 사용하는 게임 세션에는 연결 기능이 필요합니다. 메트릭을 지정하지 않으면, QoS 요건 충족에 필요한 기본값으로 설정됩니다. 메트릭을 지정했다면 QoS 요건을 충족할 수준이어야 합니다.
"metrics": {
"latency": true,
"bandwidthDown": true,
"bandwidthUp": true,
"custom": true
다음 임계값은 세션의 모든 멤버에 대한 각 pairwise 연결에 적용됩니다.
"peerToPeerRequirements": {
"latencyMaximum": 250, // Milliseconds
"bandwidthMinimum": 10000 // Kilobits per second
},
다음 임계값은 호스트 후보의 각 연결에 적용됩니다.
"peerToHostRequirements": {
"latencyMaximum": 250, // Milliseconds
"bandwidthDownMinimum": 100000, // Kilobits per second
"bandwidthUpMinimum": 1000, // Kilobits per second
"hostSelectionMetric": "bandwidthup" // Or "bandwidthdown" or "latency". Not specified is the same as "latency".
},
다음 잠재적 서버 연결 문자열은 반드시 평가해야 합니다(연결 문자열은 소문자여야 합니다).
"measurementServerAddresses": {
"east.thunderhead.azure.com": {
"secureDeviceAddress": "r5Y=" // Base-64 encoded secure-device-address
},
"west.thunderhead.azure.com": {
"secureDeviceAddress": "rwY="
}
}
}
members/{index}/properties/system
이 플래그는 멤버 상태와 activeTitle을 제어하며, 이들을 함께 사용할 수 없습니다(즉, 둘 모두 true로 설정하는 것은 오류입니다). 각각에 대해 false는 "없음"과 동일합니다. 기본 상태는 "비활성"입니다. 즉, 둘 다 존재하지 않습니다.
"ready": true,
"active": false,
// Base-64 blob, or not present. Empty-string is the same as not present.
// 'capabilities/connectivity' must be enabled in order for this to be set.
"secureDeviceAddress": "ryY=",
// List of members in my group, by index. Each element must be an integer 0 <= n < 'membersInfo/next'.
// During member initialization, if any members in the list fail, this member will also fail.
"group": [ 5 ],
// QoS measurements by lower-case device token.
// Like all fields, "measurements" must be updated as a whole. It should be set once when measurement is complete, not incrementally.
// Metrics can me omitted if they weren't successfully measured, i.e. the peer is unreachable.
// If a "measurements" object is set, it can't contain an entry for the member's own address.
"measurements": {
"e69c43a8": {
"latency": 5953, // Milliseconds
"bandwidthDown": 19342, // Kilobits per second
"bandwidthUp": 944, // Kilobits per second
"custom": { }
}
},
// QoS measurements by game-server connection string. Like all fields, "serverMeasurements" must be updated as a whole, so it should be set once when measurement is complete.
// If empty, it means that none of the measurements completed within the "serverMeasurementTimeout".
"serverMeasurements": {
"east.thunderhead.azure.com": {
"latency": 233 // Milliseconds
}
},
// Subscriptions for shoulder taps on session changes. The 'profile' indicates which session changes to tap as well as other properties of the registration like the min time between taps.
// The subscription is named with a client-generated GUID that is also sent back with the tap as a context ID.
// Subscriptions can be added and removed individually, without affecting other subscriptions in the "subscriptions" object.
// To remove a subscription, set its context ID to null.
// (Like the "ready" and "active" flags, the "subscriptions" data is copied out and maintained internally, so the normal replace-all rule on system fields doesn't apply to "subscriptions".)
"subscriptions": {
"961dc162-3a8c-4982-b58b-0347ed086bc9": {
"profile": "party", // Or "matchmaking", "initialization", "roster", "queueHost", or "queue"
"onBehalfOfTitleId": "3948320593", // Optional decimal title ID of the registered channel. If not set the title ID is taken from the token.
},
"709fef70-4638-4b94-905b-24cb02706eb5": null
}
}
QoS 단계 및 세션 초기화 세부 정보
MPSD는 템플릿이 멤버 초기화를 완료하면 게임 생성에 대한 QoS 결과를 추적하고 보고합니다. 이 작업의 진행률은 위의 멤버 초기화 섹션에서 설명한 세션 문서의 initializing 개체로 표시합니다.
initializing 개체에는 현재 초기화 단계를 나타내는 stage 특성이 있습니다. 단계는 참가에서 측정을 거쳐 평가로 이동합니다.
- 에피소드 초기화 #1이 실패하면, 단계가 실패함으로 설정되며 세션을 초기화할 수 없습니다. 에피소드 초기화가 성공하면 초기화 에피소드가 완료되고 "initializing" 개체가 제거됩니다. externalEvaluation을 false로 설정하면 평가 단계를 건너뜁니다. metrics나 measurementServerAddresses를 설정하지 않으면 측정 단계를 건너뜁니다.
"initializing": {
"stage": "measuring",
"stageStartTime": "2009-06-15T13:45:30.0900000Z",
"episode": 1
},
- 호스트 후보는 선호도 순서대로 나열되는 장치 토큰입니다. 이들은 peerToHostRequirements를 설정하고 /properties/system/host를 설정하지 않았을 때 초기화 에피소드 #1의 측정 단계 이후에 설정됩니다. /properties/system/host 개체가 설정되면 삭제됩니다.
"hostCandidates": [ "ab90a362", "99582e67" ],
"constants": { /* Property Bag */ },
"properties": { /* Property Bag */ },
"members": {
"1": {
"constants": { /* Property Bag */ },
"properties": { /* Property Bag */ },
- gamertag 속성은 멤버가 이를 허락하고 해당 멤버의 게이머태그 클레임을 찾았을 때만 설정됩니다.
"gamertag": "stacy",
- deviceToken 특성은 멤버가 보안 장치 주소를 업로드할 때 설정됩니다. 품질 비교를 위해 사용하는, 대소문자를 구분하지 않는 문자열입니다.
"deviceToken": "9f4032ba7",
- reserved 값은 사용자가 세션 문제에 대한 첫 번째 PUT 요청을 실행하면 제거됩니다. 플레이어가 예약되었다면, 플레이어가 게임 세션에 초대받았지만 이를 허락했거나 연결을 평가받지는 않았다는 뜻입니다.
"reserved": true,
- 멤버가 활성 상태라면, activeTitleId는 멤버가 활성화된 타이틀을 10진수로 표시한 것입니다.
"activeTitleId": "8397267",
- 이 특성은 사용자가 세션에 참가한 시간을 나타냅니다. reserved가 true라면, joinTime은 예약을 수행한 시간이 됩니다.
"joinTime": "2009-06-15T13:45:30.0900000Z",
- 이 멤버가 속성/시스템/턴 배열에 속해 있는 경우에는 표시됩니다. 그렇지 않은 경우에는 포함되지 않습니다.
"turn": true,
- 멤버가 단계를 성공적으로 통과 하지 않은 경우 합류 또는 측정 단계에서 체크아웃할 때 member 개체에 initializationFailure 특성이 설정됩니다. 우선 순위에 따라 이를 timeout, latency, bandwidthdown, bandwidthup, network, group, 또는 episode로 설정할 수 있습니다. 네트워크 값은 네트워크 구성 및/또는 조건(예: 충돌하는 네트워크 주소 변환 [NAT]) 때문에 QoS 메트릭을 측정할 수 없음을 의미합니다. 참가의 끝부분에는 group 값만 사용할 수 있습니다. (참가로부터의 시간 초과로 예약이 제거됩니다.) episode 값은 오류가 발생하지 않은 모든 초기화에 참가하거나 측정하는 데 실패 한 "evaluation" 단계 후에 설정됩니다.
"initializationFailure": "latency",
- memberInitialization이 설정되었고 맴버가 "initialize": true로 추가되었다면, 멤버가 참여할 초기화 에피소드로 설정됩니다. 값 1은 생성 시 새 세션에 추가된 멤버에 사용합니다. 초기화 에피소드가 끝나면 제거됩니다.
"initializationEpisode": 1,
- next 특성은 세션에 속한 다음 멤버의 인덱스 값을 나타냅니다. 추가할 멤버가 없다면 이 특성은 membersInfo 개체의 next 속성과 같은 값이 됩니다.
"next": 4
},
"4": { "next": 5 /* etc */ }
},
"membersInfo": {
"first": 1, // The first member's index.
"next": 5, // The index that the next member added will get.
"count": 2, // The number of members.
"accepted": 1 // The number of members that are no longer 'pending'.
},
"servers": {
"name": {
"constants": { /* Property Bag */ },
"properties": { /* Property Bag */ }
}
}
}
Xbox 클라우드 컴퓨팅 세션(사용되지 않음)
Xbox Cloud 컴퓨팅 세션에는 게임 서버에 연결하기 위해 세션이 사용하는, 대소문자를 구분하지 않는 연결 문자열의 정렬된 목록이 있습니다. 일반적으로 타이틀은 목록의 첫 번째 문자열을 사용하지만, 정교한 타이틀은 사용자 지정 메커니즘을 사용하여 다른 항목 중 하나를 선택할 수 있습니다(예: 부하 기준).
"serverConnectionStringCandidates": [ "west.thunderhead.azure.com", "east.thunderhead.azure.com" ],
"matchmaking": {
"clientResult": { // Requires the clientMatchmaking property.
"status": "searching", // Or "expired", "found", "failed", or "canceled".
"statusDetails": "Description", // Default is empty string.
"typicalWait": 30, // The expected number of seconds waiting as a non-negative integer.
"targetSessionRef": {
"scid": "1ECFDB89-36EB-4E59-8901-11F7393689AE",
"templateName": "capture-the-flag",
"name": "2D58F65F-0E3C-4F1F-8277-2BC9873FDB23"
}
},
"targetSessionConstants": { },
// Force a specific connection string to be used (useful in preserveSession=always cases).
"serverConnectionString": "west.thunderhead.azure.com",
// True if the match that was found didn't work out and needs to be resubmitted. Set to false
// to signal that the match did work, and the matchmaking service can release the session.
"resubmit": true
}
}
**/servers/{server-name}/properties/system **
{
"lockId": "opaque56789", // If set, a matchmaking service is servicing this session.
"status": "searching", // Or "expired", "found", "failed", or "canceled". Optional.
"statusDetails": "Description", // Optional free-form text. Default is empty string.
"typicalWait": 30, // Optional. The expected number of seconds waiting as a non-negative integer.
"targetSessionRef": { // Optional.
"scid": "1ECFDB89-36EB-4E59-8901-11F7393689AE",
"templateName": "capture-the-flag",
"name": "2D58F65F-0E3C-4F1F-8277-2BC9873FDB23"
}
}
원시 세션 및 사용자 지정 타이틀 속성
세션은 멀티 플레이어 게임과 관련한 사용자 지정 하우스키핑 정보(메타데이터)를 저장하는 역할을 합니다. 게임 데이터 및 저장된 정보는 TMS++에 저장해야 합니다.
속성 모음
위의 각 개체는 선택형 내부 개체인 시스템과 사용자 지정으로 구성되는 속성 모음으로 표시됩니다.
사용자 지정 개체는 모든 JSON을 포함할 수 있습니다.
"custom": {
"myField1": true,
"myField2": "string",
"myField3": 5.5,
"myField4": { "myObject": null },
"myField5": [ "my", "array" ]
}
활성 멤버 감소
활성 멤버는 MPSD가 사용자가 타이틀을 이용하지 않음을 감지하면 자동으로 비활성 상태로 표시됩니다. 이 현상이 발생하는 대표적인 경우는 사용자 기록에서 현재 상태가 시간 초과되는 것입니다.
이 메커니즘은 안전장치일 뿐입니다. 따라서 멤버가 타이틀에서 나가거나, 전환하거나, 로그아웃하거나, 다른 방식으로 타이틀을 이용하지 않게 되면 타이틀은 멤버를 비활성 상태로 미리 표시해야 합니다(아니면 세션에서 멤버를 제거해야 합니다).
FAQ 및 문제 해결
MPSD를 호출하려면 어떻게 해야 하나요?
인증서 인증 사용: client-sessiondirectory.xboxlive.com
예:
PUT https://client-sessiondirectory-stress.xboxlive.com/serviceconfigs/8cvda84-2606-4bab-8eda-d12313e65143/sessiontemplates/teamDeathmatch/sessions/3baafc35-816d-49cd-9656-5772506c988a
XToken 인증 사용: sessiondirectory.xboxlive.com
예:
PUT https://sessiondirectory-stress.xboxlive.com/serviceconfigs/8cvda84-2606-4bab-8eda-d12313e65143/sessiontemplates/teamDeathmatch/sessions/3baafc35-816d-49cd-9656-5772506c988a
사용할 SCID, 세션 템플릿 및 샌드박스를 어떻게 파악하나요?
이 정보는 타이틀의 파트너 센터에서 확인할 수 있습니다. 아직 파트너 센터에 액세스할 수 없다면, 개발자 계정 관리자에게 문의하세요. 원하는 정보를 제공해 줄 것입니다.
제 요청과 비교해 볼 수 있는 요청 본문 예시가 있나요?
MPSD 호출 시 404 오류가 발생합니다.
Fiddler 추적을 수집해 더 많은 정보를 얻은 다음 다음을 수행합니다.
HttpResponse 본문의 일부분으로 반환된 메시지에서 일반적인 404 메시지를 확인합니다.
요청된 서비스 구성이 유효하지 않거나 세션에 대해 구성되지 않았습니다. 사용 중인 SCID가 올바른지 확인합니다.
요청된 세션을 찾을 수 없습니다. 가져오기 전에 세션이 생성되었고 해당 세션 템플릿이 올바른지 확인합니다. PUT 호출로 세션을 만들 수 있습니다.
사용 중인 URI를 확인합니다.
본체를 다시 부팅하거나 새 사용자로 다시 해봅니다.
MPSD 호출 시 403 오류가 발생합니다.
이는 대체로 사용 권한 또는 범위 문제입니다. Fiddler 추적을 수집해 더 많은 정보를 얻은 다음 다음을 수행합니다.
- 일반적인 403 메시지에 대한 HttpResponse 본문의 일부로 반환된 메시지를 확인합니다.
*요청된 서비스 구성에 액세스할 수 없습니다. *
샌드박스에 액세스할 수 있는 계정을 사용 중인지 확인합니다.
올바른 샌드박스에 있는지 확인합니다.
인증서 인증을 사용 중인데 이 오류가 표시된다면 DAM에게 문의하세요.
요청된 세션에 액세스할 수 없습니다. 비공개 세션은 세션 멤버만 읽을 수 있습니다.
- 표시 유형이 "비공개"인 세션에 액세스하려고 합니다. 세션 내의 구성원만 세션 문서를 읽을 수 있습니다.
요청 본문에 기존 멤버 참조가 있으려면 인증 주체에 서버가 포함되어 있어야 합니다.
- 사용자를 대신하여 다른 사용자를 세션에 참가시킬 수 없습니다. 초대만 가능합니다. 인덱스를 "reserve_<number>"로 설정하여 플레이어를 초대합니다.
412 Precondition Failed 오류가 있습니다.
세션이 이미 있는 경우에는 412 Precondition Failed를 반환합니다.
> PUT /serviceconfigs/00000000-0000-0000-0000-000000000000/sessiontemplates/quick/sessions/foo HTTP/1.1
> Content-Type: application/json
> If-None-Match: \*
세션 etag가 If-Match 헤더와 일치하지 않는 경우 412 Precondition Failed를 반환합니다.
> PUT /serviceconfigs/00000000-0000-0000-0000-000000000000/sessiontemplates/quick/sessions/foo HTTP/1.1
> Content-Type: application/json
> If--Match: 9555A7DE-8B91-40E4-8CFB-0629312C9C7D
MPSD를 호출할 때 405, 409, 503, 400 등과 같은 오류가 발생합니다.
Fiddler 추적을 수집해 더 많은 정보를 얻은 다음 HttpResponse 본문의 일부분으로 반환된 메시지를 확인합니다.
HCSettingsSetTraceLevel 속성을 HCTraceLevel:: 정보로 설정하여 XSAPI를 사용하는 경우에도 HCTraceSetTraceToDebugger가 설정된 경우에는 디버그 출력에 정보를 출력하거나 HCTraceSetClientCallback을 사용하여 게임의 자체 추적 로그에 추적 로그를 추가할 수 있는 콜백을 받을 수 있습니다. XblAddServiceCallRoutedHandler를 사용하여 각 서비스 콜에 대해 호출할 수 있습니다. 이렇게 하면 자체 로깅으로 라우팅할 수 있습니다.
제목에서 템플릿을 변경하려면 어떻게 해야 하나요?
세션 템플릿은 기본값이 아니라 정해진 틀에 가깝습니다. 그러나 템플릿에 이미 설정된 상수는 추가할 수는 있지만 재정의할 수는 없습니다.
세션이 초기화되지 않는다는 오류가 발생합니다.
템플릿(보통 게임, 파티 및 매치 티켓 시나리오)에 멤버 초기화가 있는 경우, 이 문제를 해결하기 위해 QoS를 통과하려면 멤버 예약(멤버가 시작해야 함)에 따라 "initialize=true"가 설정되어 있는지 확인해야 합니다.
세션이 생성되지 않고 HTTP/204 오류가 발생합니다.
이는 생성한 세션에 사용자가 추가되지 않았음을 나타냅니다. 세션을 만들 때 사용자가 없으면, 세션이 생성되지 않습니다.
세션을 만들 때 플레이어를 한 명 이상 추가했는지 확인하세요.
전용 서버 시나리오에서는 매치를 생성하려는 플레이어 또는 매치를 생성해야 하는 플레이어를 확보하고 해당 사용자를 매치의 최초 플레이어로 만들어야 합니다. 또는 sessionEmptyTimeout을 변경하거나 제거하는 방법도 있습니다.
언제 MPSD를 폴링해야 하나요?
MPSD 세션을 폴링해선 안 됩니다. 간단히 말해서, MPSD 세션을 각 클라이언트의 네트워크 연결을 최초로 설정할 때만, 그리고 연결이 끊어진 클라이언트 또는 클라이언트 모음의 네트워크 상태를 복구할 때만 사용하는 방식으로 코드를 설계함으로써 이 작업을 수행할 수 있습니다.
또한 MPSD의 etag 기반 동기화 기본형을 활용하여 경합 상태를 해결하기 위해 세션 상태를 새로고칠 필요가 없습니다.
이러한 원칙은 주로 피어 투 피어 메시에서 함께 연결해 플레이해야 하는 클라이언트 N개가 존재할 때 적용됩니다. 세션에서 새 멤버를 정기적으로 쿼리하는 대신, 각 멤버는 세션에 참가하고, 세션에 존재하는 멤버와 연결하고, 나중에 참가하는 멤버도 같은 작업을 한다고 가정할 수 있습니다. 이를 구현하는 방법은 채팅 및 플레이어 랑데부 샘플을 참조하세요.
드물지만 폴링을 잠시 실행해야 하는 경우도 있습니다. 폴링이 필요한 것 같다면 개발자 계정 관리자에게 문의하세요.