방법: Azure Fluid Relay 서비스에 연결
이 문서에서는 Azure Fluid Relay 서비스를 프로비전하고 사용할 수 있도록 준비하는 단계를 안내합니다.
Important
앱을 Azure Fluid Relay 서버에 연결하려면 먼저 Azure 계정에서 Azure Fluid Relay 서버 리소스를 프로비전해야 합니다.
Azure Fluid Relay 서비스는 클라우드에서 호스트되는 Fluid 서비스입니다. @fluidframework/azure-client 패키지의 AzureClient를 사용하여 Fluid 애플리케이션을 Azure Fluid Relay 인스턴스에 연결할 수 있습니다. AzureClient
는 컨테이너 개체 자체를 서비스 독립적으로 유지하면서 Fluid 컨테이너를 서비스에 연결하는 논리를 처리합니다. 이 클라이언트의 한 인스턴스를 사용하여 여러 컨테이너를 관리할 수 있습니다.
아래 섹션에서는 고유의 애플리케이션에서 AzureClient
를 사용하는 방법을 설명합니다.
서비스에 연결
Azure Fluid Relay 인스턴스에 연결하려면 먼저 AzureClient
를 만들어야 합니다. 서비스에 대해 현재 사용자에게 권한을 부여하는 데 사용할 JWT(JSON Web Token)를 생성하려면 테넌트 ID, 서비스 URL 및 토큰 공급자를 포함한 일부 구성 매개 변수를 제공해야 합니다. @fluidframework/test-client-utils 패키지는 개발 목적으로 사용할 수 있는 InsecureTokenProvider를 제공합니다.
주의
이를 사용하면 클라이언트 쪽 코드 번들에 테넌트 키 비밀을 노출하므로 InsecureTokenProvider
를 개발 목적으로만 사용해야 합니다. 이는 테넌트 키로 서명을 담당하는 사용자 고유의 백 엔드 서비스에서 토큰을 가져오는 ITokenProvider 구현으로 바꿔야 합니다. 구현 예는 AzureFunctionTokenProvider입니다. 자세한 내용은 방법: Azure 함수로 TokenProvider 작성을 참조하세요. id
및 name
필드는 임의적입니다.
const user = { id: "userId", name: "userName" };
const config = {
tenantId: "myTenantId",
tokenProvider: new InsecureTokenProvider("myTenantKey", user),
endpoint: "https://myServiceEndpointUrl",
type: "remote",
};
const clientProps = {
connection: config,
};
const client = new AzureClient(clientProps);
이제 AzureClient
의 인스턴스가 있으므로 이를 사용하여 Fluid 컨테이너를 만들거나 로드할 수 있습니다!
토큰 공급자
AzureFunctionTokenProvider는 테넌트 키 비밀이 클라이언트 쪽 번들 코드에 노출되지 않도록 하는 ITokenProvider
의 구현입니다. AzureFunctionTokenProvider
는 현재 사용자 개체와 함께 /api/GetAzureToken
에 의해 추가된 Azure 함수 URL을 가져옵니다. 나중에는 tenantId, documentId 및 userId/userName을 선택적 매개 변수로 전달하여 Azure 함수에 대한 GET
요청을 만듭니다.
const config = {
tenantId: "myTenantId",
tokenProvider: new AzureFunctionTokenProvider(
"myAzureFunctionUrl" + "/api/GetAzureToken",
{ userId: "userId", userName: "Test User" }
),
endpoint: "https://myServiceEndpointUrl",
type: "remote",
};
const clientProps = {
connection: config,
};
const client = new AzureClient(clientProps);
토큰에 사용자 지정 데이터 추가
사용자 개체는 선택적 추가 사용자 세부 정보를 보유할 수도 있습니다. 예시:
const userDetails = {
email: "xyz@outlook.com",
address: "Redmond",
};
const config = {
tenantId: "myTenantId",
tokenProvider: new AzureFunctionTokenProvider(
"myAzureFunctionUrl" + "/api/GetAzureToken",
{ userId: "UserId", userName: "Test User", additionalDetails: userDetails }
),
endpoint: "https://myServiceEndpointUrl",
type: "remote",
};
Azure 함수는 테넌트의 비밀 키를 사용하여 서명된 지정된 사용자에 대한 토큰을 생성하고 비밀 자체를 노출하지 않고 클라이언트에 반환합니다.
컨테이너 관리
AzureClient
API는 각각 컨테이너를 만들고 가져오는 createContainer 및 getContainer 함수를 노출합니다. 두 함수 모두 컨테이너 데이터 모델을 정의하는 컨테이너 스키마를 사용합니다. getContainer
함수의 경우 가져오려는 컨테이너의 id
컨테이너에 대한 추가 매개 변수가 있습니다.
컨테이너 만들기 시나리오에서 다음 패턴을 사용할 수 있습니다.
const schema = {
initialObjects: {
/* ... */
},
dynamicObjectTypes: [
/*...*/
],
};
const azureClient = new AzureClient(clientProps);
const { container, services } = await azureClient.createContainer(
schema
);
const id = await container.attach();
container.attach()
호출은 컨테이너가 실제로 서비스에 연결되고 Blob Storage에 기록되는 경우입니다. 이 컨테이너 인스턴스에 대한 고유 식별자인 id
를 반환합니다.
동일한 협업 세션에 참여하려는 모든 클라이언트는 동일한 컨테이너 id
로 getContainer
를 호출해야 합니다.
const { container, services } = await azureClient.getContainer(
id,
schema
);
Fluid에서 내보낸 로그 기록을 시작하는 방법에 대한 자세한 내용은 로깅 및 원격 분석을 참조하세요.
다시 가져오는 컨테이너는 컨테이너 스키마에 정의된 대로 initialObjects
를 보유합니다. 스키마를 설정하고 container
개체를 사용하는 방법에 대한 자세한 내용은 fluidframework.com에서 데이터 모델링을 참조하세요.
대상 그룹 세부 정보 가져오기
createContainer
및 getContainer
에 대한 호출은 위에서 설명한 container
및 services 개체의 두 값을 반환합니다.
container
에는 Fluid 데이터 모델이 포함되어 있으며 서비스에 구애받지 않습니다. AzureClient
에서 반환된 이 컨테이너 개체에 대해 작성하는 모든 코드는 클라이언트에서 다른 서비스에 재사용할 수 있습니다. 예를 들어 TinyliciousClient를 사용하여 시나리오의 프로토타입을 만든 경우 Fluid 컨테이너 내의 공유 개체와 상호 작용하는 모든 코드는 AzureClient
사용으로 이동할 때 재사용할 수 있습니다.
services
개체에는 Azure Fluid Relay 서비스와 관련된 데이터가 포함되어 있습니다. 이 개체에는 현재 컨테이너에 연결된 사용자 명단을 관리하는 데 사용할 수 있는 audience 값이 포함되어 있습니다.
다음 코드는 audience
개체를 사용하여 현재 컨테이너에 있는 모든 멤버의 업데이트된 보기를 유지하는 방법을 보여 줍니다.
const { audience } = containerServices;
const audienceDiv = document.createElement("div");
const onAudienceChanged = () => {
const members = audience.getMembers();
const self = audience.getMyself();
const memberStrings = [];
const useAzure = process.env.FLUID_CLIENT === "azure";
members.forEach((member) => {
if (member.userId !== (self ? self.userId : "")) {
if (useAzure) {
const memberString = `${member.userName}: {Email: ${member.additionalDetails ? member.additionalDetails.email : ""},
Address: ${member.additionalDetails ? member.additionalDetails.address : ""}}`;
memberStrings.push(memberString);
} else {
memberStrings.push(member.userName);
}
}
});
audienceDiv.innerHTML = `
Current User: ${self ? self.userName : ""} <br />
Other Users: ${memberStrings.join(", ")}
`;
};
onAudienceChanged();
audience.on("membersChanged", onAudienceChanged);
audience
는 사용자 ID와 사용자 이름이 있는 AzureMember 개체를 반환하는 두 가지 함수를 제공합니다.
getMembers
는 컨테이너에 연결된 모든 사용자의 맵을 반환합니다. 이 값은 멤버가 컨테이너에 조인하거나 컨테이너를 떠날 때마다 변경됩니다.getMyself
는 이 클라이언트의 현재 사용자를 반환합니다.
audience
는 또한 멤버 명단이 변경될 때 이벤트를 내보냅니다. membersChanged
는 모든 명단 변경에 대해 실행되는 반면 memberAdded
및 memberRemoved
는 수정된 clientId
및 member
값을 사용하여 각각의 변경에 대해 실행됩니다. 이러한 이벤트가 발생한 후 getMembers
에 대한 새로운 호출은 업데이트된 멤버 명단을 반환합니다.
샘플 AzureMember
개체는 다음과 같습니다.
{
"userId": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
"userName": "Test User",
"connections": [
{
"id": "c699c3d1-a4a0-4e9e-aeb4-b33b00544a71",
"mode": "write"
},
{
"id": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
"mode": "write"
}
],
"additionalDetails": {
"email": "xyz@outlook.com",
"address": "Redmond"
}
}
사용자 ID, 이름 및 추가 세부 정보와 함께 AzureMember
개체에는 연결 배열도 포함됩니다. 사용자가 하나의 클라이언트로만 세션에 로그인한 경우 connections
에는 클라이언트 ID와 읽기/쓰기 모드 여부를 포함하는 하나의 값만 있습니다. 그러나 동일한 사용자가 여러 클라이언트에서 로그인한 경우(즉, 서로 다른 디바이스에서 로그인했거나 동일한 컨테이너로 여러 브라우저 탭이 열린 경우) 여기서 connections
는 각 클라이언트에 대해 여러 값을 보유합니다. 위의 예제 데이터에서 이름이 "Test User"이고 ID가 "00aa00aa-bb11-cc22-dd33-44ee44ee44ee"인 사용자가 현재 두 클라이언트에서 컨테이너를 열고 있음을 확인할 수 있습니다. additionalDetails 필드의 값은 AzureFunctionTokenProvider
토큰 생성에서 제공된 값과 일치합니다.
이러한 함수와 이벤트를 결합하여 현재 세션의 사용자를 실시간으로 볼 수 있습니다.
축하합니다! 이제 Fluid 컨테이너를 Azure Fluid Relay 서비스에 성공적으로 연결하고 공동 작업 세션의 멤버에 대한 사용자 세부 정보를 다시 가져왔습니다!