Java
Use the Java server SDK for synchronous or asynchronous publishing, auth, state queries, and push.
Install
Install the published package from Maven Central:
<dependency>
<groupId>io.sockudo</groupId>
<artifactId>sockudo-http-java</artifactId>
<version>2.1.0</version>
</dependency>implementation("io.sockudo:sockudo-http-java:2.1.0")Configure
Sockudo sockudo = new Sockudo("app-id", "app-key", "app-secret");
sockudo.setHost("127.0.0.1");
sockudo.setPort(6001);
sockudo.setEncrypted(false);Create one instance and reuse it; the client is thread-safe and keeps a pooled
HTTP connection manager. You can also configure it from
http://key:secret@host:port/apps/app-id, but that URL contains credentials
and must not be logged.
Use setEncrypted(true) for HTTPS in production. Configure the synchronous or
asynchronous HTTP client when you need an outbound proxy, connection pool
limits, or request timeouts.
Publish
Map<String, Object> data = new HashMap<>();
data.put("id", "ord_123");
Result result = sockudo.trigger(
"orders",
"order.created",
data,
null,
"order-created-ord_123"
);The SDK also supports multi-channel and batch publishing:
sockudo.trigger(
List.of("tenant-42:orders", "user-7:orders"),
"order.updated",
Map.of("id", "ord_123", "status", "paid")
);
List<Event> batch = List.of(
new Event("orders", "order.created", Map.of("id", "ord_124")),
new Event("orders", "order.paid", Map.of("id", "ord_124"))
);
sockudo.trigger(batch);Use the overload accepting a socket ID to exclude the originating connection.
The five-argument overload accepts both socketId and idempotencyKey; each
batch Event can also carry those values. Attach a stable key to any request
that a job or HTTP handler may retry.
All requests return Result. Inspect getStatus() and getMessage() rather
than assuming a completed call succeeded:
Result result = sockudo.trigger(
"orders",
"order.created",
data,
null,
"order-created-ord_123"
);
if (result.getStatus() != Status.SUCCESS) {
throw new IllegalStateException("Sockudo publish failed: " + result.getStatus());
}Auth
String privateAuth = sockudo.authenticate(socketId, "private-orders");
Map<String, String> userInfo = new HashMap<>();
userInfo.put("name", "Ada");
String presenceAuth = sockudo.authenticate(
socketId,
"presence-lobby",
new PresenceUser("user-42", userInfo)
);Authenticate the application session and authorize the exact channel before
signing. Build PresenceUser from trusted server-side identity. Use
authenticateUser for user-targeted events, then
terminateUserConnections or forceReconnectUser when permissions change.
Async
SockudoAsync async = new SockudoAsync("app-id", "app-key", "app-secret");
async.setHost("127.0.0.1");
async.setPort(6001);
CompletableFuture<Result> result =
async.trigger("orders", "order.created", Collections.singletonMap("id", "ord_123"));Compose the returned future and handle errors explicitly:
async.trigger(
"orders",
"order.created",
data,
null,
"order-created-ord_123"
)
.thenAccept(response -> recordStatus(response.getStatus()))
.exceptionally(error -> {
scheduleRetry(operationId, error);
return null;
});Tune the async client rather than blocking on every future. Async execution is not a durable queue; persist work separately when it must survive process failure.
State and history
Result channels = sockudo.get(
"/channels",
Map.of("filter_by_prefix", "presence-", "info", "user_count")
);
Result users = sockudo.get("/channels/presence-lobby/users");
Result page = sockudo.getChannelHistory(
"orders",
Map.of("limit", "50", "direction", "newest_first")
);
Result next = sockudo.getChannelHistory(
"orders",
Map.of("cursor", opaqueCursor)
);Presence history and snapshots have corresponding helpers. State is an operational snapshot; keep pages bounded and forward cursors unchanged.
Webhooks
Validate the signature against the exact raw body before parsing:
Validity validity = sockudo.validateWebhookSignature(
xPusherKey,
xPusherSignature,
rawBody
);
if (validity != Validity.VALID) {
throw new SecurityException("invalid Sockudo webhook");
}
Webhook webhook = sockudo.parseWebhook(rawBody);
enqueueWebhookEvents(webhook.getEvents());The parser preserves unknown event names and fields for forward compatibility. Do not log the raw body or signature.
End-to-end encrypted channels
Pass a base64-encoded 32-byte encryption master key to the SDK constructor and
publish only to private-encrypted-* names. The SDK encrypts the payload and
derives the shared secret returned during auth. Do not mix encrypted and
unencrypted channels in one publish, and keep the master key in a secret
manager.
Push notifications
Map<String, Object> device = new HashMap<>();
device.put("deviceId", "android-device-1");
device.put("clientId", "user-42");
device.put("platform", "fcm");
device.put("providerToken", "provider-token");
sockudo.activateDevice(device);
Map<String, Object> subscription = new HashMap<>();
subscription.put("deviceId", "android-device-1");
subscription.put("clientId", "user-42");
subscription.put("channel", "orders");
sockudo.upsertChannelPushSubscription(subscription);
Map<String, Object> payload = new HashMap<>();
payload.put("title", "Order updated");
payload.put("body", "Order ord_123 is packed");
Map<String, Object> request = new HashMap<>();
request.put("recipients", List.of(Map.of("type", "channel", "channel", "orders")));
request.put("payload", payload);
request.put("idempotency_key", "push-order-ord_123-packed");
sockudo.publishPush(request);Push helpers set sync to false and include the required Sockudo push capability header.
Concurrency, errors, and production guidance
The synchronous client is thread-safe. Its default connection pool is small;
increase PoolingHttpClientConnectionManager.setDefaultMaxPerRoute for
high-concurrency services and set explicit timeouts.
Retry only transient network errors, 429, and suitable server failures with
bounded exponential backoff. A retried publish must retain its original
idempotency key. Authentication and validation errors require a request or
configuration change.
- Reuse the sync or async client.
- Keep the SDK deadline shorter than the caller's deadline.
- Validate and rate-limit auth/history endpoints.
- Keep credentials, signed URIs, raw webhooks, payloads, and provider tokens out of logs.
- Test connection-pool saturation, duplicate attempts, credential rotation, and graceful application shutdown.