Azure Web PubSub SDK for Java
Build real-time web applications using the Azure Web PubSub SDK for Java.
Installation
<dependency> <groupId>com.azure</groupId> <artifactId>azure-messaging-webpubsub</artifactId> <version>1.5.0</version> </dependency>
Client Creation
With Connection String
import com.azure.messaging.webpubsub.WebPubSubServiceClient; import com.azure.messaging.webpubsub.WebPubSubServiceClientBuilder;
WebPubSubServiceClient client = new WebPubSubServiceClientBuilder() .connectionString("<connection-string>") .hub("chat") .buildClient();
With Access Key
import com.azure.core.credential.AzureKeyCredential;
WebPubSubServiceClient client = new WebPubSubServiceClientBuilder() .credential(new AzureKeyCredential("<access-key>")) .endpoint("<endpoint>") .hub("chat") .buildClient();
With DefaultAzureCredential
import com.azure.identity.DefaultAzureCredentialBuilder;
WebPubSubServiceClient client = new WebPubSubServiceClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .endpoint("<endpoint>") .hub("chat") .buildClient();
Async Client
import com.azure.messaging.webpubsub.WebPubSubServiceAsyncClient;
WebPubSubServiceAsyncClient asyncClient = new WebPubSubServiceClientBuilder() .connectionString("<connection-string>") .hub("chat") .buildAsyncClient();
Key Concepts
-
Hub: Logical isolation unit for connections
-
Group: Subset of connections within a hub
-
Connection: Individual WebSocket client connection
-
User: Entity that can have multiple connections
Core Patterns
Send to All Connections
import com.azure.messaging.webpubsub.models.WebPubSubContentType;
// Send text message client.sendToAll("Hello everyone!", WebPubSubContentType.TEXT_PLAIN);
// Send JSON String jsonMessage = "{"type": "notification", "message": "New update!"}"; client.sendToAll(jsonMessage, WebPubSubContentType.APPLICATION_JSON);
Send to All with Filter
import com.azure.core.http.rest.RequestOptions; import com.azure.core.util.BinaryData;
BinaryData message = BinaryData.fromString("Hello filtered users!");
// Filter by userId client.sendToAllWithResponse( message, WebPubSubContentType.TEXT_PLAIN, message.getLength(), new RequestOptions().addQueryParam("filter", "userId ne 'user1'"));
// Filter by groups client.sendToAllWithResponse( message, WebPubSubContentType.TEXT_PLAIN, message.getLength(), new RequestOptions().addQueryParam("filter", "'GroupA' in groups and not('GroupB' in groups)"));
Send to Group
// Send to all connections in a group client.sendToGroup("java-developers", "Hello Java devs!", WebPubSubContentType.TEXT_PLAIN);
// Send JSON to group String json = "{"event": "update", "data": {"version": "2.0"}}"; client.sendToGroup("subscribers", json, WebPubSubContentType.APPLICATION_JSON);
Send to Specific Connection
// Send to a specific connection by ID client.sendToConnection("connectionId123", "Private message", WebPubSubContentType.TEXT_PLAIN);
Send to User
// Send to all connections for a specific user client.sendToUser("andy", "Hello Andy!", WebPubSubContentType.TEXT_PLAIN);
Manage Groups
// Add connection to group client.addConnectionToGroup("premium-users", "connectionId123");
// Remove connection from group client.removeConnectionFromGroup("premium-users", "connectionId123");
// Add user to group (all their connections) client.addUserToGroup("admin-group", "userId456");
// Remove user from group client.removeUserFromGroup("admin-group", "userId456");
// Check if user is in group boolean exists = client.userExistsInGroup("admin-group", "userId456");
Manage Connections
// Check if connection exists boolean connected = client.connectionExists("connectionId123");
// Close a connection client.closeConnection("connectionId123");
// Close with reason client.closeConnection("connectionId123", "Session expired");
// Check if user exists (has any connections) boolean userOnline = client.userExists("userId456");
// Close all connections for a user client.closeUserConnections("userId456");
// Close all connections in a group client.closeGroupConnections("inactive-group");
Generate Client Access Token
import com.azure.messaging.webpubsub.models.GetClientAccessTokenOptions; import com.azure.messaging.webpubsub.models.WebPubSubClientAccessToken;
// Basic token WebPubSubClientAccessToken token = client.getClientAccessToken( new GetClientAccessTokenOptions()); System.out.println("URL: " + token.getUrl());
// With user ID WebPubSubClientAccessToken userToken = client.getClientAccessToken( new GetClientAccessTokenOptions().setUserId("user123"));
// With roles (permissions) WebPubSubClientAccessToken roleToken = client.getClientAccessToken( new GetClientAccessTokenOptions() .setUserId("user123") .addRole("webpubsub.joinLeaveGroup") .addRole("webpubsub.sendToGroup"));
// With groups to join on connect WebPubSubClientAccessToken groupToken = client.getClientAccessToken( new GetClientAccessTokenOptions() .setUserId("user123") .addGroup("announcements") .addGroup("updates"));
// With custom expiration WebPubSubClientAccessToken expToken = client.getClientAccessToken( new GetClientAccessTokenOptions() .setUserId("user123") .setExpiresAfter(Duration.ofHours(2)));
Grant/Revoke Permissions
import com.azure.messaging.webpubsub.models.WebPubSubPermission;
// Grant permission to send to a group client.grantPermission( WebPubSubPermission.SEND_TO_GROUP, "connectionId123", new RequestOptions().addQueryParam("targetName", "chat-room"));
// Revoke permission client.revokePermission( WebPubSubPermission.SEND_TO_GROUP, "connectionId123", new RequestOptions().addQueryParam("targetName", "chat-room"));
// Check permission boolean hasPermission = client.checkPermission( WebPubSubPermission.SEND_TO_GROUP, "connectionId123", new RequestOptions().addQueryParam("targetName", "chat-room"));
Async Operations
asyncClient.sendToAll("Async message!", WebPubSubContentType.TEXT_PLAIN) .subscribe( unused -> System.out.println("Message sent"), error -> System.err.println("Error: " + error.getMessage()) );
asyncClient.sendToGroup("developers", "Group message", WebPubSubContentType.TEXT_PLAIN) .doOnSuccess(v -> System.out.println("Sent to group")) .doOnError(e -> System.err.println("Failed: " + e)) .subscribe();
Error Handling
import com.azure.core.exception.HttpResponseException;
try { client.sendToConnection("invalid-id", "test", WebPubSubContentType.TEXT_PLAIN); } catch (HttpResponseException e) { System.out.println("Status: " + e.getResponse().getStatusCode()); System.out.println("Error: " + e.getMessage()); }
Environment Variables
WEB_PUBSUB_CONNECTION_STRING=Endpoint=https://<resource>.webpubsub.azure.com;AccessKey=... WEB_PUBSUB_ENDPOINT=https://<resource>.webpubsub.azure.com WEB_PUBSUB_ACCESS_KEY=<your-access-key>
Client Roles
Role Permission
webpubsub.joinLeaveGroup
Join/leave any group
webpubsub.sendToGroup
Send to any group
webpubsub.joinLeaveGroup.<group>
Join/leave specific group
webpubsub.sendToGroup.<group>
Send to specific group
Best Practices
-
Use Groups: Organize connections into groups for targeted messaging
-
User IDs: Associate connections with user IDs for user-level messaging
-
Token Expiration: Set appropriate token expiration for security
-
Roles: Grant minimal required permissions via roles
-
Hub Isolation: Use separate hubs for different application features
-
Connection Management: Clean up inactive connections
Trigger Phrases
-
"Web PubSub Java"
-
"WebSocket messaging Azure"
-
"real-time push notifications"
-
"server-sent events"
-
"chat application backend"
-
"live updates broadcasting"