azure-web-pubsub-ts

安装量: 45
排名: #16366

安装

npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill azure-web-pubsub-ts

Azure Web PubSub SDKs for TypeScript Real-time messaging with WebSocket connections and pub/sub patterns. Installation

Server-side management

npm install @azure/web-pubsub @azure/identity

Client-side real-time messaging

npm install @azure/web-pubsub-client

Express middleware for event handlers

npm install @azure/web-pubsub-express Environment Variables WEBPUBSUB_CONNECTION_STRING = Endpoint = https:// < resource

.webpubsub.azure.com ; AccessKey = < key

; Version = 1.0 ; WEBPUBSUB_ENDPOINT = https:// < resource

.webpubsub.azure.com Server-Side: WebPubSubServiceClient Authentication import { WebPubSubServiceClient , AzureKeyCredential } from "@azure/web-pubsub" ; import { DefaultAzureCredential } from "@azure/identity" ; // Connection string const client = new WebPubSubServiceClient ( process . env . WEBPUBSUB_CONNECTION_STRING ! , "chat" // hub name ) ; // DefaultAzureCredential (recommended) const client2 = new WebPubSubServiceClient ( process . env . WEBPUBSUB_ENDPOINT ! , new DefaultAzureCredential ( ) , "chat" ) ; // AzureKeyCredential const client3 = new WebPubSubServiceClient ( process . env . WEBPUBSUB_ENDPOINT ! , new AzureKeyCredential ( "" ) , "chat" ) ; Generate Client Access Token // Basic token const token = await client . getClientAccessToken ( ) ; console . log ( token . url ) ; // wss://...?access_token=... // Token with user ID const userToken = await client . getClientAccessToken ( { userId : "user123" , } ) ; // Token with permissions const permToken = await client . getClientAccessToken ( { userId : "user123" , roles : [ "webpubsub.joinLeaveGroup" , "webpubsub.sendToGroup" , "webpubsub.sendToGroup.chat-room" , // specific group ] , groups : [ "chat-room" ] , // auto-join on connect expirationTimeInMinutes : 60 , } ) ; Send Messages // Broadcast to all connections in hub await client . sendToAll ( { message : "Hello everyone!" } ) ; await client . sendToAll ( "Plain text" , { contentType : "text/plain" } ) ; // Send to specific user (all their connections) await client . sendToUser ( "user123" , { message : "Hello!" } ) ; // Send to specific connection await client . sendToConnection ( "connectionId" , { data : "Direct message" } ) ; // Send with filter (OData syntax) await client . sendToAll ( { message : "Filtered" } , { filter : "userId ne 'admin'" , } ) ; Group Management const group = client . group ( "chat-room" ) ; // Add user/connection to group await group . addUser ( "user123" ) ; await group . addConnection ( "connectionId" ) ; // Remove from group await group . removeUser ( "user123" ) ; // Send to group await group . sendToAll ( { message : "Group message" } ) ; // Close all connections in group await group . closeAllConnections ( { reason : "Maintenance" } ) ; Connection Management // Check existence const userExists = await client . userExists ( "user123" ) ; const connExists = await client . connectionExists ( "connectionId" ) ; // Close connections await client . closeConnection ( "connectionId" , { reason : "Kicked" } ) ; await client . closeUserConnections ( "user123" ) ; await client . closeAllConnections ( ) ; // Permissions await client . grantPermission ( "connectionId" , "sendToGroup" , { targetName : "chat" } ) ; await client . revokePermission ( "connectionId" , "sendToGroup" , { targetName : "chat" } ) ; Client-Side: WebPubSubClient Connect import { WebPubSubClient } from "@azure/web-pubsub-client" ; // Direct URL const client = new WebPubSubClient ( "" ) ; // Dynamic URL from negotiate endpoint const client2 = new WebPubSubClient ( { getClientAccessUrl : async ( ) => { const response = await fetch ( "/negotiate" ) ; const { url } = await response . json ( ) ; return url ; } , } ) ; // Register handlers BEFORE starting client . on ( "connected" , ( e ) => { console . log ( Connected: ${ e . connectionId } ) ; } ) ; client . on ( "group-message" , ( e ) => { console . log ( ${ e . message . group } : ${ e . message . data } ) ; } ) ; await client . start ( ) ; Send Messages // Join group first await client . joinGroup ( "chat-room" ) ; // Send to group await client . sendToGroup ( "chat-room" , "Hello!" , "text" ) ; await client . sendToGroup ( "chat-room" , { type : "message" , content : "Hi" } , "json" ) ; // Send options await client . sendToGroup ( "chat-room" , "Hello" , "text" , { noEcho : true , // Don't echo back to sender fireAndForget : true , // Don't wait for ack } ) ; // Send event to server await client . sendEvent ( "userAction" , { action : "typing" } , "json" ) ; Event Handlers // Connection lifecycle client . on ( "connected" , ( e ) => { console . log ( Connected: ${ e . connectionId } , User: ${ e . userId } ) ; } ) ; client . on ( "disconnected" , ( e ) => { console . log ( Disconnected: ${ e . message } ) ; } ) ; client . on ( "stopped" , ( ) => { console . log ( "Client stopped" ) ; } ) ; // Messages client . on ( "group-message" , ( e ) => { console . log ( [ ${ e . message . group } ] ${ e . message . fromUserId } : ${ e . message . data } ) ; } ) ; client . on ( "server-message" , ( e ) => { console . log ( Server: ${ e . message . data } ) ; } ) ; // Rejoin failure client . on ( "rejoin-group-failed" , ( e ) => { console . log ( Failed to rejoin ${ e . group } : ${ e . error } ) ; } ) ; Express Event Handler import express from "express" ; import { WebPubSubEventHandler } from "@azure/web-pubsub-express" ; const app = express ( ) ; const handler = new WebPubSubEventHandler ( "chat" , { path : "/api/webpubsub/hubs/chat/" , // Blocking: approve/reject connection handleConnect : ( req , res ) => { if ( ! req . claims ?. sub ) { res . fail ( 401 , "Authentication required" ) ; return ; } res . success ( { userId : req . claims . sub [ 0 ] , groups : [ "general" ] , roles : [ "webpubsub.sendToGroup" ] , } ) ; } , // Blocking: handle custom events handleUserEvent : ( req , res ) => { console . log ( Event from ${ req . context . userId } : , req . data ) ; res . success ( Received: ${ req . data } , "text" ) ; } , // Non-blocking onConnected : ( req ) => { console . log ( Client connected: ${ req . context . connectionId } ) ; } , onDisconnected : ( req ) => { console . log ( Client disconnected: ${ req . context . connectionId } ) ; } , } ) ; app . use ( handler . getMiddleware ( ) ) ; // Negotiate endpoint app . get ( "/negotiate" , async ( req , res ) => { const token = await serviceClient . getClientAccessToken ( { userId : req . user ?. id , } ) ; res . json ( { url : token . url } ) ; } ) ; app . listen ( 8080 ) ; Key Types // Server import { WebPubSubServiceClient , WebPubSubGroup , GenerateClientTokenOptions , HubSendToAllOptions , } from "@azure/web-pubsub" ; // Client import { WebPubSubClient , WebPubSubClientOptions , OnConnectedArgs , OnGroupDataMessageArgs , } from "@azure/web-pubsub-client" ; // Express import { WebPubSubEventHandler , ConnectRequest , UserEventRequest , ConnectResponseHandler , } from "@azure/web-pubsub-express" ; Best Practices Use Entra ID auth - DefaultAzureCredential for production Register handlers before start - Don't miss initial events Use groups for channels - Organize messages by topic/room Handle reconnection - Client auto-reconnects by default Validate in handleConnect - Reject unauthorized connections early Use noEcho - Prevent message echo back to sender when needed When to Use This skill is applicable to execute the workflow or actions described in the overview.

返回排行榜