Notatka
Dostęp do tej strony wymaga autoryzacji. Może 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 wykorzystane 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 autoryzacyjne potrzebne Twojej aplikacji, aby uzyskać dostęp do usługi Azure Web PubSub. Klucz dostępu w parametry połączenia działa jak hasło root 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. Wejdź do folderu
SocketIOProject, aby uruchomić następujące polecenia.Obecnie pakiet Function Bundle nie zawiera wiązania funkcji Socket.IO, dlatego musisz 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.jsi zastąp jego zawartość 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 });To wykorzystuje
SocketIOTrigger, aby było wyzwalane komunikatem od klienta Socket.IO, oraz powiązanieSocketIOdo rozsyłania komunikatów do przestrzeni nazw.Utwórz funkcję, która zwraca plik index.html do wyświetlenia.
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 parametr
AzureWebJobsStoragew pliku local.settings.json jest ustawiony naUseDevelopmentStorage=true.
Skonfiguruj usługę Web PubSub dla Socket.IO
- Dodaj ciąg połączenia do aplikacji Function App:
func settings add WebPubSubForSocketIOConnectionString "<connection string>"
- Dodaj ustawienia huba 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="*"
Ciąg połączenia można uzyskać za pomocą polecenia Azure CLI
az webpubsub key show -g <resource group> -n <resource name>
Dane wyjściowe zawierają primaryConnectionString i secondaryConnectionString, a każdy z nich jest dostępny.
Konfigurowanie tunelu
W trybie serverless usługa używa webhooków do wywoływania funkcji. Gdy próbujesz uruchomić aplikację lokalnie, głównym problemem jest umożliwienie usłudze dostępu 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 udostępnia lokalna funkcja 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 do tunelowania 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: