Como: Conectar-se a um serviço do Azure Fluid Relay

Este artigo descreve as etapas para obter seu serviço Azure Fluid Relay provisionado e pronto para uso.

Importante

Antes de conectar seu aplicativo a um servidor do Azure Fluid Relay, você deve provisionar um recurso de servidor do Azure Fluid Relay em sua conta do Azure.

O serviço 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 . AzureClient lida com a lógica de conectar seu contêiner Fluid ao serviço, mantendo o próprio objeto de contêiner agnóstico em relação ao serviço. Você pode usar uma instância desse cliente para gerenciar vários contêineres.

As secções abaixo explicarão como utilizar AzureClient na sua própria aplicação.

Conectando-se ao serviço

Para se conectar a uma instância do Azure Fluid Relay, primeiro você precisa criar um AzureClientarquivo . Você deve fornecer alguns parâmetros de configuração, incluindo o ID do locatário, a URL do serviço e um provedor de token para gerar o JSON Web Token (JWT) que será usado para autorizar o usuário atual em relação ao serviço. O pacote @fluidframework/test-client-utils fornece um InsecureTokenProvider que pode ser usado para fins de desenvolvimento.

Atenção

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. Isso deve ser substituído por uma implementação de ITokenProvider que busca o token de seu próprio serviço de back-end que é responsável por assiná-lo com a chave de locatário. Um exemplo de implementação é AzureFunctionTokenProvider. Para obter mais informações, consulte Como escrever um TokenProvider com uma função do Azure. Observe que os id campos 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, você pode começar a usá-lo para criar ou carregar contêineres Fluid!

Provedores de token

O AzureFunctionTokenProvider é uma implementação que garante que o segredo da chave do locatário não seja exposto no código do pacote do lado do ITokenProvider cliente. As AzureFunctionTokenProvider tomadas em sua URL de Função do Azure anexada por /api/GetAzureToken junto com o objeto de usuário atual. Mais tarde, ele faz uma GET solicitação para sua Função do Azure passando o tenantId, documentId e 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 determinado usuário que está assinado usando a chave secreta do locatário e o retornará ao cliente sem expor o segredo em si.

Gerir contentores

A AzureClient API expõe as funções createContainer e getContainer para criar e obter contêineres, respectivamente. Ambas as funções aceitam um esquema de contêiner que define o modelo de dados de contêiner. Para a getContainer função, há um parâmetro adicional para o recipiente 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 container.attach() chamada é quando o contêiner realmente se conecta ao serviço e é gravado em seu armazenamento de blob. Ele retorna um id que é o identificador exclusivo para essa instância de contêiner.

Qualquer cliente que queira participar da mesma sessão colaborativa precisa ligar getContainer com o mesmo contêiner id.

const { container, services } = await azureClient.getContainer(
  id,
  schema
);

Para obter mais informações sobre como começar a gravar logs emitidos pelo Fluid, consulte Registro em log e telemetria.

O contêiner que está sendo buscado de volta manterá o initialObjects conforme definido no esquema do contêiner. Consulte Modelagem de dados no fluidframework.com para saber mais sobre como estabelecer o esquema e usar o container objeto.

Obter detalhes do público

Chama e createContainergetContainer retorna dois valores: a container -- descrito acima -- e um objeto services.

O container contém o modelo de dados Fluid e é independente do serviço. Qualquer código que você escrever nesse objeto de contêiner retornado pelo AzureClient é reutilizável com o cliente para outro serviço. Um exemplo é se você prototipou seu cenário usando TinyliciousClient, todo o seu código interagindo com os objetos compartilhados dentro do contêiner Fluid pode ser reutilizado ao passar a usar AzureCliento .

O services objeto contém dados específicos do serviço Azure Fluid Relay. Este objeto contém um valor de audiência que pode ser usado para gerenciar a lista de usuários que estão atualmente conectados ao contêiner.

O código a seguir demonstra como você pode usar o audience objeto para manter uma exibição atualizada de todos os membros 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 um ID de usuário e nome de usuário:

  • getMembers Retorna um mapa de todos os usuários conectados ao contêiner. Esses valores serão alterados sempre que um membro entrar ou sair do contêiner.
  • getMyself retorna o usuário atual neste cliente.

audience também emite eventos para quando a lista de membros muda. membersChangedserá acionado para quaisquer alterações na lista, enquanto memberAdded e disparará para suas respetivas alterações com os clientId e membermemberRemoved valores que foram modificados. Depois que qualquer um desses eventos for acionado, uma nova chamada para getMembers retornará a lista de membros atualizada.

Um objeto de exemplo AzureMember tem a seguinte aparência:

{
  "userId": "0e662aca-9d7d-4ff0-8faf-9f8672b70f15",
  "userName": "Test User",
  "connections": [
    {
      "id": "c699c3d1-a4a0-4e9e-aeb4-b33b00544a71",
      "mode": "write"
    },
    {
      "id": "0e662aca-9d7d-4ff0-8faf-9f8672b70f15",
      "mode": "write"
    }
  ],
  "additionalDetails": {
    "email": "xyz@outlook.com",
    "address": "Redmond"
  }
}

Juntamente com o ID de usuário, nome e detalhes adicionais, AzureMember os objetos também contêm uma matriz de conexões. Se o usuário estiver conectado à sessão com apenas um cliente, connections terá apenas um valor nela com o ID do cliente e se está no modo de leitura/gravação. No entanto, se o mesmo usuário estiver conectado a partir de vários clientes (ou seja, eles estiverem conectados de dispositivos diferentes ou tiverem várias guias do navegador abertas com o mesmo contêiner), connections aqui manterá vários valores para cada cliente. Nos dados de exemplo acima, podemos ver que um usuário com nome "Test User" e ID "0e662aca-9d7d-4ff0-8faf-9f8672b70f15" atualmente tem o contêiner aberto de dois clientes diferentes. Os valores no campo additionalDetails correspondem aos valores fornecidos na geração de AzureFunctionTokenProvider token.

Essas funções e eventos podem ser combinados para apresentar uma visã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 Azure Fluid Relay e recuperou os detalhes do usuário para os membros em sua sessão colaborativa!