Azure Messaging Web PubSub Java SDK

azure-messaging-webpubsub-java
分类编程
作者Agentic Awesome Skills 社区
许可MIT
评分4.90/5
使用15.8K

Azure Web PubSub Java SDK

使用 Azure Web PubSub Java SDK 构建实时 Web 应用程序。

安装

xml
<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-messaging-webpubsub</artifactId>
    <version>1.5.0</version>
</dependency>

客户端创建

使用连接字符串

java
import com.azure.messaging.webpubsub.WebPubSubServiceClient;
import com.azure.messaging.webpubsub.WebPubSubServiceClientBuilder;

WebPubSubServiceClient client = new WebPubSubServiceClientBuilder()
.connectionString("<connection-string>")
.hub("chat")
.buildClient();

使用访问密钥

java
import com.azure.core.credential.AzureKeyCredential;

WebPubSubServiceClient client = new WebPubSubServiceClientBuilder()
.credential(new AzureKeyCredential("<access-key>"))
.endpoint("<endpoint>")
.hub("chat")
.buildClient();

使用 DefaultAzureCredential

java
import com.azure.identity.DefaultAzureCredentialBuilder;

WebPubSubServiceClient client = new WebPubSubServiceClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint("<endpoint>")
.hub("chat")
.buildClient();

异步客户端

java
import com.azure.messaging.webpubsub.WebPubSubServiceAsyncClient;

WebPubSubServiceAsyncClient asyncClient = new WebPubSubServiceClientBuilder()
.connectionString("<connection-string>")
.hub("chat")
.buildAsyncClient();

核心概念

  • Hub (中心):连接的逻辑隔离单元
  • Group (组):中心内连接的子集
  • Connection (连接):单个 WebSocket 客户端连接
  • User (用户):可以拥有多个连接的实体

核心模式

发送至所有连接

java
import com.azure.messaging.webpubsub.models.WebPubSubContentType;

// 发送文本消息
client.sendToAll("Hello everyone!", WebPubSubContentType.TEXT_PLAIN);

// 发送 JSON
String jsonMessage = "{\"type\": \"notification\", \"message\": \"New update!\"}";
client.sendToAll(jsonMessage, WebPubSubContentType.APPLICATION_JSON);

使用过滤器发送至所有连接

java
import com.azure.core.http.rest.RequestOptions;
import com.azure.core.util.BinaryData;

BinaryData message = BinaryData.fromString("Hello filtered users!");

// 按 userId 过滤
client.sendToAllWithResponse(
message,
WebPubSubContentType.TEXT_PLAIN,
message.getLength(),
new RequestOptions().addQueryParam("filter", "userId ne 'user1'"));

// 按组过滤
client.sendToAllWithResponse(
message,
WebPubSubContentType.TEXT_PLAIN,
message.getLength(),
new RequestOptions().addQueryParam("filter", "'GroupA' in groups and not('GroupB' in groups)"));

发送至组

java
// 发送至组内的所有连接
client.sendToGroup("java-developers", "Hello Java devs!", WebPubSubContentType.TEXT_PLAIN);

// 向组发送 JSON
String json = "{\"event\": \"update\", \"data\": {\"version\": \"2.0\"}}";
client.sendToGroup("subscribers", json, WebPubSubContentType.APPLICATION_JSON);

发送至特定连接

java
// 通过 ID 发送至特定连接
client.sendToConnection("connectionId123", "Private message", WebPubSubCon
tentType.TEXT_PLAIN);
code
### 发送给用户
java // 向特定用户的所有连接发送消息 client.sendToUser("andy", "Hello Andy!", WebPubSubContentType.TEXT_PLAIN);
code
### 管理组
java // 将连接添加到组 client.addConnectionToGroup("premium-users", "connectionId123");

// 从组中移除连接
client.removeConnectionFromGroup("premium-users", "connectionId123");

// 将用户添加到组(该用户的所有连接)
client.addUserToGroup("admin-group", "userId456");

// 从组中移除用户
client.removeUserFromGroup("admin-group", "userId456");

// 检查用户是否在组中
boolean exists = client.userExistsInGroup("admin-group", "userId456");

code
### 管理连接
java
// 检查连接是否存在
boolean connected = client.connectionExists("connectionId123");

// 关闭连接
client.closeConnection("connectionId123");

// 带原因关闭连接
client.closeConnection("connectionId123", "Session expired");

// 检查用户是否存在(是否有任何连接)
boolean userOnline = client.userExists("userId456");

// 关闭用户的所有连接
client.closeUserConnections("userId456");

// 关闭组内的所有连接
client.closeGroupConnections("inactive-group");

code
### 生成客户端访问令牌
java
import com.azure.messaging.webpubsub.models.GetClientAccessTokenOptions;
import com.azure.messaging.webpubsub.models.WebPubSubClientAccessToken;

// 基础令牌
WebPubSubClientAccessToken token = client.getClientAccessToken(
new GetClientAccessTokenOptions());
System.out.println("URL: " + token.getUrl());

// 带用户 ID 的令牌
WebPubSubClientAccessToken userToken = client.getClientAccessToken(
new GetClientAccessTokenOptions().setUserId("user123"));

// 带角色(权限)的令牌
WebPubSubClientAccessToken roleToken = client.getClientAccessToken(
new GetClientAccessTokenOptions()
.setUserId("user123")
.addRole("webpubsub.joinLeaveGroup")
.addRole("webpubsub.sendToGroup"));

// 带连接时自动加入组的令牌
WebPubSubClientAccessToken groupToken = client.getClientAccessToken(
new GetClientAccessTokenOptions()
.setUserId("user123")
.addGroup("announcements")
.addGroup("updates"));

// 自定义过期时间的令牌
WebPubSubClientAccessToken expToken = client.getClientAccessToken(
new GetClientAccessTokenOptions()
.setUserId("user123")
.setExpiresAfter(Duration.ofHours(2)));

code
### 授予/撤销权限
java
import com.azure.messaging.webpubsub.models.WebPubSubPermission;

// 授予向组发送消息的权限
client.grantPermission(
WebPubSubPermission.SEND_TO_GROUP,
"connectionId123",
new RequestOptions().addQueryParam("targetName", "chat-room"));

// 撤销权限
client.revokePermission(
WebPubSubPermission.SEND_TO_GROUP,
"connectionId123",
new RequestOptions().addQueryParam("targetName", "chat-room"));

// 检查权限
boolean hasPermission = client.checkPermission(
WebPubSubPermission.SEND_TO_GROUP,
"connectionId123",
new RequestOptions().addQueryParam("targetName", "chat-room"));

code
### 异步操作
java
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();

code
## 错误处理
java
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());
}

code
## 环境变量
bash
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>
``

客户端角色

| 角色 | 权限 |
|------|------------|
|
webpubsub.joinLeaveGroup | 加入/离开任何组 |
|
webpubsub.sendToGroup | 发送到任何组 |
|
webpubsub.joinLeaveGroup.<group> | 加入/离开特定组 |
|
webpubsub.sendToGroup.<group>` | 发送到特定组 |

最佳实践

1. 使用组 (Groups):将连接组织成组,以便进行定向消息传递
2. 用户 ID:将连接与用户 ID 关联,实现用户级消息传递
3. 令牌过期:设置合理的令牌过期时间以确保安全
4. 角色:通过角色授予最小必要权限
5. Hub 隔离:为不同的应用功能使用独立的 Hub
6. 连接管理:清理不活跃的连接

触发词

  • "Web PubSub Java"
  • "WebSocket messaging Azure"
  • "real-time push notifications"
  • "server-sent events"
  • "chat application backend"
  • "live updates broadcasting"

适用场景

本技能适用于执行概览中所描述的工作流或操作。

局限性

  • 仅在任务明确符合上述范围时使用此技能。
  • 不要将输出视为针对特定环境的验证、测试或专家评审的替代方案。
  • 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。