Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym samouczku przedstawiono sposób tworzenia usługi Web PubSub dla usługi Socket.IO w trybie bezserwerowym i tworzenia aplikacji czatu integrującej się z funkcją platformy Azure.
Znajdź pełne przykłady kodu używane w tym samouczku:
Ważne
Tryb domyślny wymaga trwałego serwera. Nie można zintegrować usługi Web PubSub dla Socket.IO w trybie domyślnym z funkcją platformy Azure.
Ważne
Nieprzetworzone parametry połączenia są wyświetlane tylko w tym artykule w celach demonstracyjnych.
Parametry połączenia zawiera informacje o autoryzacji wymagane przez aplikację w celu uzyskania dostępu do usługi Azure Web PubSub. Klucz dostępu wewnątrz ciągu połączenia jest podobny do hasła głównego dla twojej usługi. W środowiskach produkcyjnych zawsze chroń klucze dostępu. Użyj usługi Azure Key Vault, aby bezpiecznie zarządzać kluczami i obracać je oraz zabezpieczać połączenie za pomocą usługi WebPubSubServiceClient.
Unikaj dystrybuowania kluczy dostępu do innych użytkowników, kodowania ich lub zapisywania ich w dowolnym miejscu w postaci zwykłego tekstu, który jest dostępny dla innych użytkowników. Obróć klucze, jeśli uważasz, że zostały naruszone.
Wymagania wstępne
- Konto platformy Azure z aktywną subskrypcją. Jeśli nie masz, możesz utworzyć bezpłatne konto.
- Podstawowe narzędzie funkcji platformy Azure
- Znajomość biblioteki Socket.IO.
Tworzenie usługi Web PubSub dla zasobu Socket.IO w trybie bezserwerowym
Aby utworzyć usługę Web PubSub dla Socket.IO, możesz użyć następującego polecenia interfejsu wiersza polecenia platformy Azure:
az webpubsub create -g <resource-group> -n <resource-name>--kind socketio --service-mode serverless --sku Premium_P1
Lokalne tworzenie projektu funkcji platformy Azure
Należy wykonać kroki, aby zainicjować lokalny projekt funkcji platformy Azure.
Wykonaj kroki, aby zainstalować najnowsze narzędzie podstawowe funkcji platformy Azure
W oknie terminalu lub w wierszu polecenia uruchom następujące polecenie, aby utworzyć projekt w folderze
SocketIOProject:func init SocketIOProject --worker-runtime javascript --model V4To polecenie tworzy projekt JavaScript. Wprowadź folder
SocketIOProject, aby uruchomić następujące polecenia.Obecnie pakiet funkcji nie zawiera Socket.IO powiązania funkcji, dlatego należy ręcznie dodać pakiet.
Aby wyeliminować odwołanie do pakietu funkcji, zmodyfikuj plik host.json i usuń następujące wiersze.
"extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[4.*, 5.0.0)" }Uruchom polecenie:
func extensions install -p Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO -v 1.0.0-beta.4
Utwórz funkcję na potrzeby negocjacji. Funkcja negocjacji używana do generowania punktów końcowych i tokenów dla klienta w celu uzyskania dostępu do usługi.
func new --template "Http Trigger" --name negotiateOtwórz plik w
src/functions/negotiate.jspliku i zastąp go następującym kodem: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 });Ten krok tworzy funkcję
negotiatez wyzwalaczem HTTP i powiązaniem wyjściowymSocketIONegotiation, co oznacza, że można użyć wywołania HTTP, aby wyzwolić funkcję i zwrócić wynik negocjacji generowany przez powiązanieSocketIONegotiation.Utwórz funkcję do przekazywania komunikatów.
func new --template "Http Trigger" --name messageOtwórz plik
src/functions/message.jsi zastąp ciąg następującym kodem: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 });Służy
SocketIOTriggerdo wyzwalania przez komunikat klienta Socket.IO i używaniaSocketIOpowiązania do emisji komunikatów w przestrzeni nazw.Utwórz funkcję, aby zwrócić kod HTML indeksu na potrzeby odwiedzania.
Utwórz folder
publicw obszarzesrc/.Utwórz plik
index.htmlHTML z następującą zawartością.<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>Aby zwrócić stronę HTML, utwórz funkcję i kody kopiowania:
func new --template "Http Trigger" --name indexOtwórz plik
src/functions/index.jsi zastąp ciąg następującym kodem: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 });
Jak uruchomić aplikację lokalnie
Po przygotowaniu kodu wykonaj instrukcje uruchamiania przykładu.
Konfigurowanie usługi Azure Storage dla funkcji platformy Azure
Usługa Azure Functions wymaga, aby konto magazynu działało nawet lokalnie. Wybierz jedną z dwóch następujących opcji:
- Uruchom bezpłatny emulator Azurite.
- Użyj usługi Azure Storage. Może to wiązać się z kosztami, jeśli będzie on nadal używany.
- Instalowanie Azurite
npm install -g azurite
- Uruchom emulator magazynu Azurite:
azurite -l azurite -d azurite\debug.log
- Upewnij się, że
AzureWebJobsStoragew local.settings.json ustawionoUseDevelopmentStorage=truewartość .
Konfigurowanie konfiguracji usługi Web PubSub dla Socket.IO
- Dodaj parametry połączenia do aplikacji funkcji:
func settings add WebPubSubForSocketIOConnectionString "<connection string>"
- Dodawanie ustawień centrum do usługi Web PubSub dla 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="*"
Parametry połączenia można uzyskać za pomocą polecenia interfejsu wiersza polecenia platformy Azure
az webpubsub key show -g <resource group> -n <resource name>
Dane wyjściowe zawierają primaryConnectionString wartości i secondaryConnectionString, i są dostępne.
Konfigurowanie tunelu
W trybie bezserwerowym usługa używa elementów webhook do wyzwalania funkcji. Podczas próby uruchomienia aplikacji lokalnie kluczowy problem polega na tym, że usługa będzie mogła uzyskać dostęp do lokalnego punktu końcowego funkcji.
Najprostszym sposobem osiągnięcia tego celu jest użycie narzędzia Tunnel Tool
Zainstaluj narzędzie tunelu:
npm install -g @azure/web-pubsub-tunnel-toolUruchamianie tunelu
awps-tunnel run --hub hub --connection "<connection string>" --upstream http://127.0.0.1:7071Jest
--upstreamto adres URL, który uwidacznia lokalna funkcja platformy Azure. Port może być inny i można sprawdzić dane wyjściowe podczas uruchamiania funkcji w następnym kroku.
Uruchamianie przykładowej aplikacji
Po uruchomieniu narzędzia tunelu możesz uruchomić aplikację funkcji lokalnie:
func start
Odwiedź stronę internetową pod adresem http://localhost:7071/api/index.
Następne kroki
Następnie możesz spróbować użyć aplikacji Bicep do wdrożenia aplikacji w trybie online przy użyciu uwierzytelniania opartego na tożsamościach: