Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa esercitazione illustra come creare un servizio Web PubSub per Socket.IO in modalità serverless e creare un'app di chat che si integra con Funzioni di Azure.
Trovare esempi di codice completi usati in questa esercitazione:
Importante
La modalità predefinita richiede un server permanente, non è possibile integrare Web PubSub per Socket.IO in modalità predefinita con Funzione di Azure.
Importante
Le stringa di connessione non elaborate vengono visualizzate in questo articolo solo a scopo dimostrativo.
Una stringa di connessione include le informazioni sull'autorizzazione necessarie all'applicazione per l'accesso al servizio Azure Web PubSub. La chiave di accesso all'interno della stringa di connessione è simile a una password radice per il servizio. Negli ambienti di produzione proteggere sempre le chiavi di accesso. Usare Azure Key Vault per gestire e ruotare le chiavi in modo sicuro e proteggere la connessione con WebPubSubServiceClient.
Evitare di distribuire le chiavi di accesso ad altri utenti, impostarle come hardcoded o salvarle in un file di testo normale accessibile ad altri. Ruotare le chiavi se si ritiene che siano state compromesse.
Prerequisiti
- Un account Azure con una sottoscrizione attiva. Se non si ha un account, è possibile crearne uno gratuito.
- Strumento di base della funzione di Azure
- Una certa familiarità con la libreria di Socket.IO.
Creare un Web PubSub per Socket.IO risorsa in modalità serverless
Per creare un web pubSub per Socket.IO, è possibile usare il comando seguente dell'interfaccia della riga di comando di Azure :
az webpubsub create -g <resource-group> -n <resource-name>--kind socketio --service-mode serverless --sku Premium_P1
Creare un progetto di funzione di Azure in locale
È necessario seguire la procedura per avviare un progetto di funzione di Azure locale.
Seguire il passaggio per installare lo strumento principale di Funzioni di Azure più recente
Nella finestra del terminale o da un prompt dei comandi eseguire il comando seguente per creare un progetto nella cartella
SocketIOProject:func init SocketIOProject --worker-runtime javascript --model V4Questo comando crea un progetto JavaScript. Immettere la cartella
SocketIOProjectper eseguire i comandi seguenti.Attualmente, il bundle di funzioni non include Socket.IO binding di funzioni, quindi è necessario aggiungere manualmente il pacchetto.
Per eliminare il riferimento al bundle di funzioni, modificare il file host.json e rimuovere le righe seguenti.
"extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[4.*, 5.0.0)" }Eseguire il comando:
func extensions install -p Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO -v 1.0.0-beta.4
Creare una funzione per la negoziazione. Funzione di negoziazione usata per generare endpoint e token per consentire al client di accedere al servizio.
func new --template "Http Trigger" --name negotiateAprire il file in
src/functions/negotiate.jse sostituire con il codice seguente: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 });Questo passaggio crea una funzione
negotiatecon un trigger HTTP e un'associazione di outputSocketIONegotiation, ossia è possibile usare una richiesta HTTP per attivare la funzione e restituire un risultato di negoziazione generato dall'associazioneSocketIONegotiation.Creare una funzione per la distribuzione dei messaggi.
func new --template "Http Trigger" --name messageAprire il file
src/functions/message.jse sostituire con il codice seguente: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 });Viene usato
SocketIOTriggerper attivare un messaggio client Socket.IO e usare l'associazioneSocketIOper trasmettere i messaggi allo spazio dei nomi.Creare una funzione per restituire un codice HTML di indice da visitare.
Creare una cartella
publicinsrc/.Creare un file
index.htmlHTML con il contenuto seguente.<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>Per restituire la pagina HTML, creare una funzione e copiare i codici:
func new --template "Http Trigger" --name indexAprire il file
src/functions/index.jse sostituire con il codice seguente: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 });
Come eseguire l'app in locale
Dopo aver preparato il codice, seguire le istruzioni per eseguire l'esempio.
Configurare Archiviazione di Azure per la funzione di Azure
Funzioni di Azure richiede che un account di archiviazione funzioni anche in esecuzione in locale. Scegliere una delle due opzioni seguenti:
- Eseguire l'emulatore Free Azurite.
- Usare il servizio Archiviazione di Azure. Ciò può comportare costi se si continua a usarlo.
- Installare il Azurite
npm install -g azurite
- Avviare l'emulatore di archiviazione Di Azurite:
azurite -l azurite -d azurite\debug.log
- Assicurarsi che in
AzureWebJobsStoragelocal.settings.json impostato suUseDevelopmentStorage=true.
Configurare la configurazione di Web PubSub per Socket.IO
- Aggiungere stringa di connessione all'APP per le funzioni:
func settings add WebPubSubForSocketIOConnectionString "<connection string>"
- Aggiungere le impostazioni dell'hub a Web PubSub per 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="*"
Il stringa di connessione può essere ottenuto dal comando dell'interfaccia della riga di comando di Azure
az webpubsub key show -g <resource group> -n <resource name>
L'output contiene primaryConnectionString e secondaryConnectionStringe è disponibile.
Configurare il tunnel
In modalità serverless il servizio usa webhook per attivare la funzione. Quando si tenta di eseguire l'app in locale, un problema cruciale è consentire al servizio di accedere all'endpoint della funzione locale.
Un modo più semplice per ottenere questo risultato consiste nell'usare lo strumento tunnel
Installare lo strumento tunnel:
npm install -g @azure/web-pubsub-tunnel-toolEseguire il tunnel
awps-tunnel run --hub hub --connection "<connection string>" --upstream http://127.0.0.1:7071--upstreamè l'URL esposto dalla funzione di Azure locale. La porta può essere diversa ed è possibile controllare l'output all'avvio della funzione nel passaggio successivo.
Eseguire un'app di esempio
Dopo l'esecuzione dello strumento tunnel, è possibile eseguire l'app per le funzioni in locale:
func start
Visitare la pagina Web all'indirizzo http://localhost:7071/api/index.
Passaggi successivi
Successivamente, è possibile provare a usare Bicep per distribuire l'app online con l'autenticazione basata sull'identità: