Como conectar um serviço do Azure Fluid Relay
Este artigo explica as etapas para provisionar e preparar seu serviço do Azure Fluid Relay para uso.
Importante
Antes de conectar seu aplicativo a um servidor do Azure Fluid Relay, você deve provisionar um recurso do servidor do Azure Fluid Relay em sua conta do Azure.
O serviço do Azure Fluid Relay é um serviço Fluid hospedado na nuvem. Você pode conectar seu aplicativo Fluid a uma instância do Azure Fluid Relay usando o AzureClient no pacote @fluidframework/azure-client. O AzureClient
lida com a lógica de conectar seu contêiner Fluid ao serviço, mantendo o próprio objeto de contêiner independente do sistema. Você pode usar uma instância desse cliente para gerenciar vários contêineres.
As seções a seguir explicarão como usar AzureClient
em seu próprio aplicativo.
Conectando-se ao serviço
Para se conectar a uma instância do Azure Fluid Relay, primeiro você precisa criar um AzureClient
. Você deve fornecer alguns parâmetros de configuração, incluindo a ID do locatário, a URL de serviço e um provedor de token para gerar o Token Web JSON (JWT) que será usado para autorizar o usuário atual no serviço. O pacote @fluidframework/test-client-utils fornece um InsecureTokenProvider que pode ser usado para fins de desenvolvimento.
Cuidado
O InsecureTokenProvider
só deve ser usado para fins de desenvolvimento, porque usá-lo expõe o segredo da chave do locatário em seu pacote de código do lado do cliente. Ele deve ser substituído por uma implementação do ITokenProvider que busca o token de seu próprio serviço de back-back responsável por conectá-lo com a chave do locatário. Um exemplo de implementação é o AzureFunctionTokenProvider. Para obter mais informações, confira Como gravar um TokenProvider com uma função do Azure. Observe que os campos id
e name
são arbitrários.
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);
Agora que você tem uma instância do AzureClient
, pode começar a usá-la para criar ou carregar contêineres Fluid!
Provedores de token
O AzureFunctionTokenProvider é uma implementação do ITokenProvider
que garante que o segredo da chave do locatário não seja exposto no código do pacote do lado do cliente. O AzureFunctionTokenProvider
recebe a URL da sua Função do Azure anexada por /api/GetAzureToken
junto com o objeto de usuário atual. Posteriormente, ele faz uma solicitação GET
para a Função do Azure passando o tenantId, o documentId e o userId/userName como parâmetros opcionais.
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);
Adicionando dados personalizados a tokens
O objeto de usuário também pode conter detalhes adicionais opcionais do usuário. Por exemplo:
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",
};
Sua Função do Azure gerará o token para o usuário determinado que está conectado usando a chave secreta do locatário e o retornará ao cliente sem expor o segredo.
Gerenciamento de contêineres
A API AzureClient
expõe as funções createContainer e getContainer para criar e obter contêineres, respectivamente. Ambas as funções têm um esquema de contêiner que define o modelo de dados do contêiner. Para a função getContainer
, há um parâmetro adicional para o contêiner id
do contêiner que você deseja buscar.
No cenário de criação de contêiner, você pode usar o seguinte padrão:
const schema = {
initialObjects: {
/* ... */
},
dynamicObjectTypes: [
/*...*/
],
};
const azureClient = new AzureClient(clientProps);
const { container, services } = await azureClient.createContainer(
schema
);
const id = await container.attach();
A chamada container.attach()
é quando o contêiner realmente se conecta ao serviço e é registrado em seu armazenamento de blob. Ele retorna um id
que é o identificador exclusivo para essa instância de contêiner.
Qualquer cliente que deseja ingressar na mesma sessão colaborativa precisa chamar getContainer
com o mesmo contêiner id
.
const { container, services } = await azureClient.getContainer(
id,
schema
);
Para obter mais informações sobre como iniciar a gravação de logs emitidos pelo Fluid, confira Registro em log e telemetria.
O contêiner que está sendo buscado conterá o initialObjects
conforme definido no esquema de contêiner. Consulte Modelagem de dados em fluidframework.com para saber mais sobre como estabelecer o esquema e usar o objeto container
.
Obter detalhes do público
As chamadas a createContainer
e getContainer
retornam dois valores: um container
, descrito acima, e um objeto de serviços.
O container
contém o modelo de dados Fluid e é independente do serviço. Qualquer código que você gravar nesse objeto de contêiner retornado pelo AzureClient
é reutilizável com o cliente para outro serviço. Por exemplo, se você criou um protótipo do seu cenário usando o TinyliciousClient, todo o seu código que interagir com os objetos compartilhados no contêiner do Fluid poderá ser reutilizado ao passar a usar o AzureClient
.
O objeto services
contém dados específicos para o serviço do Azure Fluid Relay. Esse objeto contém um valor da audiência que pode ser usado para gerenciar a lista de usuários que estão conectados ao contêiner no momento.
O código a seguir demonstra como você pode usar o objeto audience
para manter uma exibição atualizada de todos os membros que estejam atualmente em um contêiner.
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
fornece duas funções que retornarão objetos AzureMember que têm uma ID de usuário e um nome de usuário:
- O
getMembers
retorna um mapa de todos os usuários conectados ao contêiner. Esses valores serão alterados sempre que um membro ingressar ou sair do contêiner. - O
getMyself
retorna o usuário atual neste cliente.
O audience
também emite eventos para quando a lista de membros se alterar. O membersChanged
irá disparar para quaisquer alterações na lista de membros, enquanto memberAdded
e memberRemoved
irão disparar para suas respectivas alterações com os valores clientId
e member
que foram modificados. Depois que qualquer um desses eventos disparar, uma nova chamada para getMembers
retornará a lista de membros atualizada.
Um objeto AzureMember
de exemplo se parece com o seguinte:
{
"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"
}
}
Juntamente com a ID de usuário, o nome e os detalhes adicionais, os objetos AzureMember
também têm uma matriz de conexões. Se o usuário estiver conectado à sessão com apenas um cliente, o connections
terá apenas um valor com a ID do cliente e se estiver no modo de leitura/gravação. No entanto, se o mesmo usuário estiver conectado de vários clientes (ou seja, eles estiverem conectados de diferentes dispositivos ou têm várias guias do navegador abertas com o mesmo contêiner), o connections
aqui conterá vários valores para cada cliente. Nos dados de exemplo acima, podemos ver que um usuário com o nome "Usuário de Teste" e a ID "00aa00aa-bb11-cc22-dd33-44ee44ee44ee" tem atualmente o contêiner aberto em dois clientes diferentes. Os valores no campo additionalDetails corresponderão aos valores fornecidos na geração de token AzureFunctionTokenProvider
.
Essas funções e eventos podem ser combinados para apresentar uma exibição em tempo real dos usuários na sessão atual.
Parabéns! Agora você conectou com êxito seu contêiner Fluid ao serviço do Azure Fluid Relay e retornou os detalhes do usuário para os membros em sua sessão colaborativa!