Este tutorial mostra como criar um serviço de chat em tempo real com várias salas usando WebSockets com uma ligação persistente para comunicação bidirecional. Com os WebSockets, o cliente e o servidor podem enviar mensagens entre si sem sondar o servidor para atualizações.
Embora possa configurar o Cloud Run para usar a afinidade de sessão, esta oferece uma afinidade de melhor esforço, o que significa que qualquer novo pedido ainda pode ser potencialmente encaminhado para uma instância diferente. Consequentemente, as mensagens do utilizador no serviço de chat têm de ser sincronizadas em todas as instâncias e não apenas entre os clientes ligados a uma instância.
Crie um serviço de chat em tempo real
Este serviço de chat de exemplo usa uma instância do Memorystore para Redis para armazenar e sincronizar mensagens do utilizador em todas as instâncias. O Redis usa um mecanismo de Pub/Sub, que não deve ser confundido com o produto Cloud Pub/Sub, para enviar dados para clientes subscritos ligados a qualquer instância, de modo a eliminar a sondagem HTTP para atualizações.
No entanto, mesmo com as atualizações push, qualquer instância iniciada só recebe novas mensagens enviadas para o contentor. Para carregar mensagens anteriores, o histórico de mensagens teria de ser armazenado e obtido a partir de uma solução de armazenamento persistente. Este exemplo usa a funcionalidade convencional de uma loja de objetos do Redis para colocar em cache e obter o histórico de mensagens.
A instância do Redis está protegida da Internet através de IPs privados com acesso controlado e limitado a serviços executados na mesma rede privada virtual que a instância do Redis. Recomendamos que use a saída de VPC direta.
Limitações
Este tutorial não mostra a autenticação do utilizador final nem o armazenamento em cache da sessão. Para saber mais sobre a autenticação do utilizador final, consulte o tutorial do Cloud Run sobre a autenticação do utilizador final.
Este tutorial não implementa uma base de dados, como o Firestore, para o armazenamento e a obtenção indefinidos do histórico de mensagens de chat.
São necessários elementos adicionais para que este serviço de exemplo esteja pronto para produção. Recomendamos uma instância do Redis de nível padrão para oferecer alta disponibilidade através da replicação e da comutação por falha automática.
Objetivos
Escreva, crie e implemente um serviço do Cloud Run que use WebSockets.
Estabeleça ligação a uma instância do Memorystore for Redis para publicar e subscrever novas mensagens em várias instâncias.
Ligue o serviço do Cloud Run ao Memorystore através da saída da VPC direta.
Custos
Neste documento, usa os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custos com base na sua utilização projetada,
use a calculadora de preços.
Antes de começar
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Cloud Run, Memorystore for Redis, Artifact Registry, and Cloud Build APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. - Instale e inicialize a CLI gcloud.
-
Leitor do Artifact Registry (
roles/artifactregistry.reader) -
Editor do Cloud Build (
roles/cloudbuild.builds.editor) -
Administrador do Cloud Memorystore Redis (
roles/redis.admin) -
Administrador do Cloud Run (
roles/run.admin) -
Criar contas de serviço (
roles/iam.serviceAccountCreator) -
Project IAM Admin (
roles/resourcemanager.projectIamAdmin) -
Administrador da conta de serviço (
roles/iam.serviceAccountAdmin) -
Consumidor de utilização do serviço (
roles/serviceusage.serviceUsageConsumer)
Funções necessárias
Para receber as autorizações de que precisa para concluir o tutorial, peça ao seu administrador para lhe conceder as seguintes funções da IAM no seu projeto:
Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.
Também pode conseguir as autorizações necessárias através de funções personalizadas ou outras funções predefinidas.
Configure as predefinições do gcloud
Para configurar o gcloud com as predefinições do seu serviço do Cloud Run:
Defina o projeto predefinido:
gcloud config set project PROJECT_ID
Substitua PROJECT_ID pelo nome do projeto que criou para este tutorial.
Configure o gcloud para a região escolhida:
gcloud config set run/region REGION
Substitua REGION pela região do Cloud Run suportada à sua escolha.
Localizações do Cloud Run
O Cloud Run é regional, o que significa que a infraestrutura que executa os seus serviços do Cloud Run está localizada numa região específica e é gerida pela Google para estar disponível de forma redundante em todas as zonas dessa região.
O cumprimento dos seus requisitos de latência, disponibilidade ou durabilidade são fatores
principais para selecionar a região onde os seus serviços do Cloud Run são executados.
Geralmente, pode selecionar a região mais próxima dos seus utilizadores, mas deve considerar a localização dos outros Google Cloudprodutos usados pelo seu serviço do Cloud Run.
A utilização Google Cloud de produtos em conjunto em várias localizações pode afetar
a latência do seu serviço, bem como o custo.
O Cloud Run está disponível nas seguintes regiões:
Sujeito aos preços de Nível 1
asia-east1(Taiwan)asia-northeast1(Tóquio)asia-northeast2(Osaca)asia-south1(Mumbai, Índia)europe-north1(Finlândia)Baixo CO2
europe-north2(Estocolmo)Baixo CO2
europe-southwest1(Madrid)Baixo CO2
europe-west1(Bélgica)Baixo CO2
europe-west4(Países Baixos)Baixo CO2
europe-west8(Milão)europe-west9(Paris)Baixo CO2
me-west1(Telavive)northamerica-south1(México)us-central1(Iowa)Baixo CO2
us-east1(Carolina do Sul)us-east4(Virgínia do Norte)us-east5(Columbus)us-south1(Dallas)Baixo CO2
us-west1(Oregão)Baixo CO2
Sujeito aos preços de Nível 2
africa-south1(Joanesburgo)asia-east2(Hong Kong)asia-northeast3(Seul, Coreia do Sul)asia-southeast1(Singapura)asia-southeast2(Jacarta)asia-south2(Deli, Índia)australia-southeast1(Sydney)australia-southeast2(Melbourne)europe-central2(Varsóvia, Polónia)europe-west10(Berlim)europe-west12(Turim)europe-west2(Londres, Reino Unido)Baixo CO2
europe-west3(Frankfurt, Alemanha)europe-west6(Zurique, Suíça)Baixo CO2
me-central1(Doha)me-central2(Dammam)northamerica-northeast1(Montreal)Baixo CO2
northamerica-northeast2(Toronto)Baixo CO2
southamerica-east1(São Paulo, Brasil)Baixo CO2
southamerica-west1(Santiago, Chile)Baixo CO2
us-west2(Los Angeles)us-west3(Salt Lake City)us-west4(Las Vegas)
Se já criou um serviço do Cloud Run, pode ver a região no painel de controlo do Cloud Run na Google Cloud consola.
Obtenha o exemplo de código
Para obter o exemplo de código para utilização:
Clone o repositório de exemplo para a sua máquina local:
Node.js
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
Em alternativa, pode transferir o exemplo como um ficheiro ZIP e extraí-lo.
Altere para o diretório que contém o código de exemplo do Cloud Run:
Node.js
cd nodejs-docs-samples/run/websockets/
Compreenda o código WebSockets
O Socket.io é uma biblioteca que permite a comunicação bidirecional em tempo real entre o navegador e o servidor. Embora o Socket.io não seja uma implementação do WebSocket, envolve a funcionalidade para fornecer uma API mais simples para vários protocolos de comunicação com funcionalidades adicionais, como fiabilidade melhorada, reconexão automática e transmissão para todos ou um subconjunto de clientes.
Integração do lado do cliente
O cliente instancia uma nova instância de Socket para cada ligação. Uma vez que este exemplo é renderizado do lado do servidor, não é necessário definir o URL do servidor. A instância de socket pode emitir e ouvir eventos.
Integração do lado do servidor
Do lado do servidor, o servidor Socket.io é inicializado e anexado ao servidor HTTP. Semelhante ao lado do cliente, assim que o servidor Socket.io estabelece uma ligação ao cliente, é criada uma instância de socket para cada ligação que pode ser usada para emitir e ouvir mensagens. O Socket.io também fornece uma interface para criar "salas" ou um canal arbitrário ao qual os sockets podem aderir e sair.
O Socket.io também fornece um adaptador Redis para transmitir eventos a todos os clientes, independentemente do servidor que está a publicar o socket. O Socket.io usa apenas o mecanismo Pub/Sub do Redis e não armazena dados.
O adaptador Redis do Socket.io pode reutilizar o cliente Redis usado para armazenar o histórico de mensagens da sala. Cada contentor cria uma ligação à instância do Redis e o Cloud Run pode criar um grande número de instâncias. Este valor está muito abaixo das 65 000 ligações que o Redis pode suportar.
Nova associação
O Cloud Run tem um limite de tempo máximo de 60 minutos. Por isso, tem de adicionar uma lógica de restabelecimento da ligação para possíveis limites de tempo. Em alguns casos, o Socket.io tenta automaticamente restabelecer a ligação após eventos de desligamento ou erro de ligação. Não existe garantia de que o cliente volte a estabelecer ligação à mesma instância.
As instâncias persistem se existir uma ligação ativa até que todos os pedidos sejam fechados ou expirem. Mesmo que use a afinidade de sessão do Cloud Run, é possível que os novos pedidos sejam equilibrados em carga para contentores ativos, o que permite o dimensionamento dos contentores. Se estiver preocupado com o grande número de contentores que persistem após um pico de tráfego, pode diminuir o valor de tempo limite máximo para que os soquetes não usados sejam limpos com maior frequência.
Envie o serviço
Crie uma instância do Memorystore for Redis:
gcloud redis instances create INSTANCE_ID --size=1 --region=REGION
Substitua o seguinte:
- INSTANCE_ID: o nome da instância, por exemplo,
my-redis-instance. - REGION_ID: a região
para todos os seus recursos e serviços, por exemplo,
europe-west1.
À instância é automaticamente atribuído um intervalo de IP do intervalo de rede de serviço predefinido. Este tutorial usa 1 GB de memória para a cache local de mensagens na instância do Redis. Saiba como determinar o tamanho inicial de uma instância do Memorystore para o seu exemplo de utilização.
- INSTANCE_ID: o nome da instância, por exemplo,
Defina uma variável de ambiente com o endereço IP da rede autorizada da sua instância do Redis:
export REDISHOST=$(gcloud redis instances describe INSTANCE_ID --region REGION --format "value(host)")
Crie uma conta de serviço para servir como identidade do serviço. Por predefinição, esta conta não tem privilégios além da associação ao projeto.
gcloud iam service-accounts create chat-identity gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:chat-identity@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/serviceusage.serviceUsageConsumer
Encontre o nome da sua rede VPC autorizada pela instância do Redis executando o seguinte comando:
gcloud redis instances describe INSTANCE_ID --region REGION --format "value(authorizedNetwork)"
Substitua o seguinte:
- INSTANCE_ID: o nome da instância, por exemplo,
my-redis-instance. - REGION_ID: a região
para todos os seus recursos e serviços, por exemplo,
europe-west1.
Tome nota do nome da rede de VPC.
- INSTANCE_ID: o nome da instância, por exemplo,
Crie e implemente a imagem de contentor no Cloud Run:
gcloud run deploy chat-app --source . \ --allow-unauthenticated \ --timeout 3600 \ --service-account chat-identity \ --network NETWORK \ --subnet SUBNET \ --update-env-vars REDISHOST=$REDISHOST
Substitua o seguinte:
- NETWORK é o nome da rede VPC autorizada à qual a sua instância do Redis está associada.
- SUBNET é o nome da sua sub-rede. A sub-rede tem de ter
/26ou mais. A saída direta da VPC suporta intervalos IPv4 RFC 1918, RFC 6598 e Classe E.
Responda a todas as instruções para instalar as APIs necessárias respondendo
yquando lhe for pedido. Só tem de fazer isto uma vez por projeto. Responda a outros pedidos fornecendo a plataforma e a região, se não tiver definido predefinições para estas, conforme descrito na página de configuração. Saiba mais sobre a Implementação a partir do código fonte.
Experimente o serviço
Para experimentar o serviço completo:
Navegue no navegador para o URL fornecido pelo passo de implementação.
Adicione o seu nome e uma sala de chat para iniciar sessão.
Envie uma mensagem para a sala!
Se optar por continuar a desenvolver estes serviços, lembre-se de que têm acesso restrito à gestão de identidade e acesso (IAM) ao resto do Google Cloud e terão de receber funções de IAM adicionais para aceder a muitos outros serviços.
Limpar
Para evitar custos adicionais na sua conta Google Cloud , elimine todos os recursos que implementou com este tutorial.
Elimine o projeto
Se criou um novo projeto para este tutorial, elimine-o. Se usou um projeto existente e precisa de o manter sem as alterações que adicionou neste tutorial, elimine os recursos que criou para o tutorial.
A forma mais fácil de eliminar a faturação é eliminar o projeto que criou para o tutorial.
Para eliminar o projeto:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Elimine recursos de tutoriais
Elimine o serviço do Cloud Run que implementou neste tutorial. Os serviços do Cloud Run não incorrem em custos até receberem pedidos.
Para eliminar o seu serviço do Cloud Run, execute o seguinte comando:
gcloud run services delete SERVICE-NAME
Substitua SERVICE-NAME pelo nome do seu serviço.
Também pode eliminar serviços do Cloud Run a partir da Google Cloud consola.
Remova a configuração da região predefinida
gcloudque adicionou durante a configuração do tutorial:gcloud config unset run/regionRemova a configuração do projeto:
gcloud config unset projectElimine outros Google Cloud recursos criados neste tutorial:
- Elimine a imagem do contentor de serviço denominada
gcr.io/PROJECT_ID/chat-appdo Artifact Registry - Elimine a conta de serviço
chat-identity@PROJECT_ID.iam.gserviceaccount.com - Elimine a instância do Memorystore for Redis
- Elimine a imagem do contentor de serviço denominada
O que se segue?
Saiba como funciona o Socket.io e a utilização mais avançada.
Explore melhor a saída direta da VPC com uma rede da VPC.
Reveja as práticas recomendadas para o Memorystore e para usar WebSockets no Cloud Run.