Official Java SDK for OddSockets real-time messaging platform.
- Enterprise Ready: Built for production with comprehensive error handling
- Spring Boot Friendly: Drop the client into any Spring service as a bean
- Enhanced Surface: Slack-like reactions, threads, typing, presence and more
- Low Latency: Real-time delivery with automatic reconnection
- Cost Effective: No per-message pricing, no message size limits
- Cloud Native: Perfect for microservices and enterprise applications
<dependency>
<groupId>com.oddsockets</groupId>
<artifactId>oddsockets-java-sdk</artifactId>
<version>0.1.0-beta.1</version>
</dependency>implementation 'com.oddsockets:oddsockets-java-sdk:0.1.0-beta.1'import com.oddsockets.OddSockets;
import com.oddsockets.Channel;
import com.oddsockets.Message;
import com.oddsockets.config.OddSocketsConfig;
public class BasicExample {
public static void main(String[] args) {
// Create client
OddSocketsConfig config = OddSocketsConfig.builder()
.apiKey("ak_live_1234567890abcdef")
.managerUrl("https://connect.oddsockets.tyga.network")
.userId("java-demo-user")
.build();
OddSockets client = new OddSockets(config);
try {
// Connect to OddSockets
client.connect().get();
// Create channel
Channel channel = client.channel("my-channel");
// Subscribe to messages
channel.subscribe(message -> {
System.out.println("Received: " + message.getData());
}, SubscribeOptions.builder()
.enablePresence(true)
.retainHistory(true)
.build()).get();
// Publish a message
channel.publish("Hello from Java! ☕", PublishOptions.builder()
.metadata(Map.of("source", "java-sdk"))
.storeInHistory(true)
.build()).get();
// Keep alive
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
} finally {
client.disconnect();
}
}
}@RestController
@RequiredArgsConstructor
public class MessageController {
private final OddSockets oddSockets;
@PostMapping("/send-message")
public CompletableFuture<PublishResult> sendMessage(@RequestBody MessageRequest request) {
Channel channel = oddSockets.channel(request.getChannel());
return channel.publish(request.getMessage(), PublishOptions.builder()
.metadata(Map.of("timestamp", Instant.now().toString()))
.storeInHistory(true)
.build());
}
@GetMapping("/channel/{name}/presence")
public CompletableFuture<PresenceInfo> getPresence(@PathVariable String name) {
return oddSockets.channel(name).getPresence();
}
}Beyond core pub/sub, OddSockets ships a Slack-like enhanced surface — reactions,
typing indicators, threads, read receipts, presence/status, notifications, DMs,
channel management, message editing and search. It lives on client.enhanced.
The pattern is always the same:
- Send an action with a
client.enhanced.*method (camelCase). - Receive the paired broadcast with
client.on("<event>", handler).
import com.google.gson.JsonObject;
import com.oddsockets.OddSockets;
import com.oddsockets.config.OddSocketsConfig;
OddSockets client = new OddSockets(OddSocketsConfig.builder()
.apiKey("ak_live_1234567890abcdef")
.userId("alice")
.build());
client.connect().get();
// Receive-path: broadcasts from other users on the channel
client.on("user_typing", data -> System.out.println("user is typing"));
client.on("reaction_added", data -> System.out.println("reaction added"));
client.on("thread_reply", data -> System.out.println("new thread reply"));
// Send-path: enhanced actions over the live socket
client.enhanced.startTyping("alice", "room-42");
client.enhanced.addReaction("msg-1", "room-42", ":thumbsup:", "alice", "Alice");
client.enhanced.threadReply("room-42", "msg-1", "Replying in the thread", "alice", "Alice");Each area exposes methods on client.enhanced; the worker broadcasts the paired
events which you handle with client.on(...). Query methods (get*, search*)
return a CompletableFuture<JsonObject> that completes with the worker response.
| Area | Requests (client.enhanced.*) |
Broadcast events (client.on) |
|---|---|---|
| Typing | startTyping, stopTyping |
user_typing, user_stopped_typing |
| Reactions | addReaction, removeReaction, getReactions |
reaction_added, reaction_removed |
| Threads | threadReply, getThread, subscribeThread, followThread, markThreadRead |
thread_reply, thread_subscribed, thread_followed, thread_read_updated |
| Read receipts | markRead, markAllRead, getUnreadCounts |
user_read, unread_count_updated, all_marked_read |
| Messages | editMessage, deleteMessage, pinMessage, unpinMessage, getPinnedMessages, searchMessages |
message_edited, message_deleted, message_pinned, message_unpinned |
| Presence & status | setStatus, setCustomStatus, setDND, getUserPresence |
user_status_changed, custom_status_updated, dnd_status_changed |
| Channels | createChannel, updateChannel, archiveChannel, inviteToChannel, joinChannel, leaveChannel |
channel_created, channel_updated, user_invited, user_joined_channel, user_left_channel |
| DMs | createDM, sendDM, getDMConversations |
dm_created, dm_received |
| Notifications | subscribeNotifications, getNotifications, markNotificationRead, clearNotifications |
notification, notification_read, notifications_cleared |
| Search | searchMessages, searchInChannel, searchByUser, filterMessages |
(future results) |
For any worker event not wrapped above, subscribe with the raw
client.on("<event>", handler) API — all enhanced broadcasts are forwarded onto
the client surface.
- SDK Documentation - Guides and API overview
- Javadoc - Full API reference
Explore the runnable examples:
- Basic Usage - Simple messaging
- Enhanced Features - Reactions, threads, typing and more
- Two-client demo - End-to-end enhanced broadcast regression
OddSocketsConfig config = OddSocketsConfig.builder()
.apiKey("your-api-key") // Required: Your OddSockets API key
.managerUrl("manager-url") // Optional: Manager URL
.userId("user-id") // Optional: User identifier
.autoConnect(true) // Optional: Auto-connect on creation
.reconnectAttempts(5) // Optional: Max reconnection attempts
.heartbeatInterval(Duration.ofSeconds(30)) // Optional: Heartbeat interval
.requestTimeout(Duration.ofSeconds(10)) // Optional: Request timeout
.build();// Subscribe with options
channel.subscribe(messageHandler, SubscribeOptions.builder()
.enablePresence(true) // Enable presence tracking
.retainHistory(true) // Retain message history
.filterExpression("user.premium == true") // Message filter expression
.build());
// Publish with options
channel.publish(message, PublishOptions.builder()
.ttl(3600) // Time to live (seconds)
.metadata(Map.of("priority", "high")) // Additional metadata
.storeInHistory(true) // Store in message history
.build());- Java 11+
- Spring Boot 2.7+ / 3.x
- Jakarta EE 9+
# Run tests
./mvnw test
# Run tests with coverage
./mvnw test jacoco:report
# Run integration tests
./mvnw test -Dtest.profile=integration
# Run performance tests
./mvnw test -Dtest.profile=performance# Build
./mvnw clean compile
# Package
./mvnw clean package
# Install to local repository
./mvnw clean install
# Deploy to Maven Central
./mvnw clean deploy -P releaseOddSockets Java SDK delivers superior performance:
- Low latency real-time delivery
- 99.9% uptime with automatic failover
- Unlimited message size - no artificial limits
- High throughput - handle millions of messages with async pipelines
- End-to-end encryption available
- API key authentication with fine-grained permissions
- Rate limiting and abuse protection
- GDPR compliant data handling
# application.yml
oddsockets:
api-key: ak_live_1234567890abcdef
manager-url: https://connect.oddsockets.tyga.network
user-id: spring-boot-user
auto-connect: true
reconnect-attempts: 5
heartbeat-interval: 30s@Component
@RequiredArgsConstructor
public class MessageService {
private final OddSockets oddSockets;
@EventListener
public void handleApplicationReady(ApplicationReadyEvent event) {
Channel channel = oddSockets.channel("system-events");
channel.subscribe(message -> {
// Handle system messages
log.info("System message: {}", message.getData());
});
}
}@RestController
@RequestMapping("/api/messages")
@RequiredArgsConstructor
public class MessageController {
private final OddSockets oddSockets;
@PostMapping("/broadcast")
public CompletableFuture<List<PublishResult>> broadcast(@RequestBody BroadcastRequest request) {
List<CompletableFuture<PublishResult>> futures = request.getChannels().stream()
.map(channelName -> oddSockets.channel(channelName)
.publish(request.getMessage(), PublishOptions.builder()
.metadata(Map.of("broadcast_id", request.getBroadcastId()))
.storeInHistory(true)
.build()))
.collect(Collectors.toList());
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
}
}OddSockets is available in multiple languages:
- JavaScript SDK - Browser + Node.js, TypeScript ready
- Python SDK - AsyncIO support, Django/Flask integrations
- Go SDK - High performance, goroutines and channels
- C# SDK - .NET Core/Framework, Azure integrations
- Swift SDK - iOS native, Combine framework
- Kotlin SDK - Android native, coroutines support
AI agents can sign up with a verified email in two steps — no dashboard, no human required.
Step 1: Request a verification code
curl -X POST https://oddsockets.com/api/agent-signup \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "agentName": "my-agent", "platform": "java"}'Step 2: Verify the 6-digit code from your email and get your API key
curl -X POST https://oddsockets.com/api/agent-signup/verify \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "code": "123456", "agentName": "my-agent"}'| Free | Starter | Pro | |
|---|---|---|---|
| Price | $0/mo | $49.99/mo | $299/mo |
| MAU | 100 | 1,000 | 50,000 |
| Concurrent connections | 50 | 1,000 | Unlimited |
| Messages/day | 10,000 | 4,320,000 | Unlimited |
| Messages/minute | 100 | 3,000 | Unlimited |
| Channels | 10 | Unlimited | Unlimited |
| Storage | 100MB (24h) | 50GB (6 months) | Unlimited |
All limits are enforced in real time.
MIT License - Copyright (c) 2026 Joe Wee, Tyga.Cloud Ltd. See LICENSE for details.