Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este tutorial orienta você sobre como criar um Web PubSub para Socket.IO serviço no Modo sem Servidor e criar um aplicativo de chat integrado ao Azure Function.
Encontre exemplos de código completo que são usados neste tutorial:
Importante
O Modo Padrão precisa de um servidor persistente, não é possível integrar o Web PubSub para Socket.IO no modo padrão com a Função do Azure.
Importante
As cadeias de conexão brutas aparecem neste artigo apenas para fins de demonstração.
Uma cadeia de ligação inclui a informação de autorização que a sua aplicação precisa para aceder ao serviço Azure Web PubSub. A chave de acesso na cadeia de ligação funciona como uma palavra-passe root para o seu serviço. Em ambientes de produção, proteja sempre as suas chaves de acesso. Use o Azure Key Vault para gerenciar e girar suas chaves com segurança e proteger sua conexão com WebPubSubServiceCliento .
Evite distribuir chaves de acesso para outros usuários, codificá-las ou salvá-las em qualquer lugar em texto simples acessível a outras pessoas. Rode as suas chaves se acreditar que podem ter sido comprometidas.
Pré-requisitos
- Uma conta do Azure com uma subscrição ativa. Se não tiver uma, poderá criar uma conta gratuita.
- Ferramenta principal do Azure Function
- Alguma familiaridade com a biblioteca Socket.IO.
Criar um recurso Web PubSub para Socket.IO no modo sem servidor
Para criar um Web PubSub para Socket.IO, você pode usar o seguinte comando da CLI do Azure:
az webpubsub create -g <resource-group> -n <resource-name>--kind socketio --service-mode serverless --sku Premium_P1
Criar um projeto do Azure Function localmente
Você deve seguir as etapas para iniciar um projeto local do Azure Function.
Siga a etapa para instalar a ferramenta principal mais recente do Azure Function
Na janela do terminal ou em um prompt de comando, execute o seguinte comando para criar um projeto na
SocketIOProjectpasta:func init SocketIOProject --worker-runtime javascript --model V4Este comando cria um projeto JavaScript. E digite a pasta
SocketIOProjectpara executar os seguintes comandos.Atualmente, o Pacote de Funções não inclui Vinculação de Função Socket.IO, pelo que é necessário adicionar o pacote manualmente.
Para eliminar a referência do pacote de funções, edite o arquivo host.json e remova as seguintes linhas.
"extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[4.*, 5.0.0)" }Executar o comando:
func extensions install -p Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO -v 1.0.0-beta.4
Crie uma função para negociação. A função de negociação utilizada para gerar endpoints e tokens que permitem ao cliente aceder ao serviço.
func new --template "Http Trigger" --name negotiateAbra o arquivo em
src/functions/negotiate.jse substitua pelo seguinte código:const { app, input } = require('@azure/functions'); const socketIONegotiate = input.generic({ type: 'socketionegotiation', direction: 'in', name: 'result', hub: 'hub' }); async function negotiate(request, context) { let result = context.extraInputs.get(socketIONegotiate); return { jsonBody: result }; }; // Negotiation app.http('negotiate', { methods: ['GET', 'POST'], authLevel: 'anonymous', extraInputs: [socketIONegotiate], handler: negotiate });Esta etapa cria uma função
negotiatecom Disparador HTTP eSocketIONegotiationassociação de saída, o que significa que pode usar uma chamada HTTP para acionar a função e retornar um resultado de negociação gerado pelaSocketIONegotiationassociação.Crie uma função para entregar mensagens.
func new --template "Http Trigger" --name messageAbra o arquivo
src/functions/message.jse substitua pelo seguinte código:const { app, output, trigger } = require('@azure/functions'); const socketio = output.generic({ type: 'socketio', hub: 'hub', }) async function chat(request, context) { context.extraOutputs.set(socketio, { actionName: 'sendToNamespace', namespace: '/', eventName: 'new message', parameters: [ context.triggerMetadata.socketId, context.triggerMetadata.message ], }); } // Trigger for new message app.generic('chat', { trigger: trigger.generic({ type: 'socketiotrigger', hub: 'hub', eventName: 'chat', parameterNames: ['message'], }), extraOutputs: [socketio], handler: chat });Isso utiliza
SocketIOTriggerpara ser acionado por uma mensagem de cliente Socket.IO e utiliza a associaçãoSocketIOpara transmitir mensagens para o espaço de nomes.Crie uma função para retornar um índice html para visitar.
Crie uma pasta
publicemsrc/.Crie um arquivo
index.htmlhtml com o seguinte conteúdo.<html> <body> <h1>Socket.IO Serverless Sample</h1> <div id="chatPage" class="chat-container"> <div class="chat-input"> <input type="text" id="chatInput" placeholder="Type your message here..."> <button onclick="sendMessage()">Send</button> </div> <div id="chatMessages" class="chat-messages"></div> </div> <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script> <script> function appendMessage(message) { const chatMessages = document.getElementById('chatMessages'); const messageElement = document.createElement('div'); messageElement.innerText = message; chatMessages.appendChild(messageElement); hatMessages.scrollTop = chatMessages.scrollHeight; } function sendMessage() { const message = document.getElementById('chatInput').value; if (message) { document.getElementById('chatInput').value = ''; socket.emit('chat', message); } } async function initializeSocket() { const negotiateResponse = await fetch(`/api/negotiate`); if (!negotiateResponse.ok) { console.log("Failed to negotiate, status code =", negotiateResponse.status); return; } const negotiateJson = await negotiateResponse.json(); socket = io(negotiateJson.endpoint, { path: negotiateJson.path, query: { access_token: negotiateJson.token } }); socket.on('new message', (socketId, message) => { appendMessage(`${socketId.substring(0,5)}: ${message}`); }) } initializeSocket(); </script> </body> </html>Para retornar a página HTML, crie uma função e copie códigos:
func new --template "Http Trigger" --name indexAbra o arquivo
src/functions/index.jse substitua pelo seguinte código:const { app } = require('@azure/functions'); const fs = require('fs').promises; const path = require('path') async function index(request, context) { try { context.log(`HTTP function processed request for url "${request.url}"`); const filePath = path.join(__dirname,'../public/index.html'); const html = await fs.readFile(filePath); return { body: html, headers: { 'Content-Type': 'text/html' } }; } catch (error) { context.log(error); return { status: 500, jsonBody: error } } }; app.http('index', { methods: ['GET', 'POST'], authLevel: 'anonymous', handler: index });
Como executar o aplicativo localmente
Depois que o código é preparado, siga as instruções para executar o exemplo.
Configurar o Armazenamento do Azure para o Azure Function
O Funções do Azure requer uma conta de armazenamento para funcionar mesmo em execução local. Escolha uma das duas opções a seguir:
- Execute o emulador gratuito do Azurite.
- Use o serviço de Armazenamento do Azure. Este poderá implicar custos se continuar a utilizá-lo.
- Instalar o Azurite
npm install -g azurite
- Inicie o emulador de armazenamento Azurite:
azurite -l azurite -d azurite\debug.log
- Certifique-se de que o
AzureWebJobsStoragein local.settings.json definido comoUseDevelopmentStorage=true.
Configurar a configuração do Web PubSub para Socket.IO
- Adicione a cadeia de conexão à aplicação de função:
func settings add WebPubSubForSocketIOConnectionString "<connection string>"
- Adicionar configurações de hub ao Web PubSub para Socket.IO
az webpubsub hub create -n <resource name> -g <resource group> --hub-name hub --event-handler url-template="tunnel:///runtime/webhooks/socketio" user-event-pattern="*"
A cadeia de conexão pode ser obtida pelo comando CLI do Azure
az webpubsub key show -g <resource group> -n <resource name>
A saída contém primaryConnectionString e secondaryConnectionString, e qualquer um deles está disponível.
Configurar túnel
No modo sem servidor, o serviço usa webhooks para acionar a função. Quando tentas executar a aplicação localmente, um problema crucial é garantir que o serviço possa aceder ao teu endpoint de função local.
Uma maneira mais fácil de conseguir isso é usar a Tunnel Tool
Instale a Ferramenta Tunnel:
npm install -g @azure/web-pubsub-tunnel-toolOperar o túnel
awps-tunnel run --hub hub --connection "<connection string>" --upstream http://127.0.0.1:7071A
--upstreamé a URL que a Função do Azure local expõe. A porta pode ser diferente e você pode verificar a saída ao iniciar a função na próxima etapa.
Executar aplicativo de exemplo
Depois que a ferramenta de túnel estiver em execução, você poderá executar o aplicativo de função localmente:
func start
E visite a página em http://localhost:7071/api/index.
Próximos passos
Em seguida, você pode tentar usar o Bicep para implantar o aplicativo online com autenticação baseada em identidade: