Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OddSockets C++ SDK

Official C++ SDK for OddSockets real-time messaging platform. Modern C++17, async, header-only option. libcurl + libwebsockets.

Build

mkdir build && cd build
cmake ..
make

Quick Start

#include <oddsockets/OddSockets.hpp>

oddsockets::Config config;
config.apiKey = "YOUR_API_KEY";
config.userId = "my-agent";

oddsockets::OddSockets client(config);
auto channel = client.channel("my-channel");
channel->subscribe([](const std::string& msg) { std::cout << msg << std::endl; });
channel->publish("{\"text\":\"Hello from C++\"}");

Enhanced Features

Enhanced (Slack-like) events layer on top of the core pub/sub. The send side lives on client.enhanced(); each call is fire-and-forget (void) and emits a real worker event over the live socket. The matching broadcast arrives on the raw client.on("<event>", ...) surface as a JSON payload string, so any subscriber in the channel room can react.

#include <oddsockets/OddSockets.hpp>
#include <iostream>

oddsockets::Config config;
config.apiKey = "YOUR_API_KEY";
config.userId = "alice";
config.autoConnect = false;

oddsockets::OddSockets client(config);
client.connect().get();

auto channel = client.channel("room-42");
channel->subscribe([](const std::string&) {}).get();

// Receive-path: enhanced broadcasts arrive on the raw on() surface as JSON strings
client.on("user_typing",    [](const std::string& payload) { std::cout << "typing: "   << payload << "\n"; });
client.on("reaction_added", [](const std::string& payload) { std::cout << "reaction: " << payload << "\n"; });

// Send-path: fire enhanced actions over the live socket
client.enhanced().startTyping("alice", "room-42");
client.enhanced().addReaction("msg-1", "room-42", ":thumbsup:", "alice", "Alice");

Event surface

Area Send (client.enhanced()) Broadcast (client.on(...))
Typing startTyping(userId, channel) · stopTyping(userId, channel) user_typing · user_stopped_typing
Reactions addReaction(messageId, channel, emoji, userId, userName) · removeReaction(messageId, channel, emoji, userId) reaction_added · reaction_removed

The C++ enhanced surface is deliberately focused on typing and reactions. Any other worker event your channel emits is still available directly on client.on("<event>", ...).

Token auth for game clients (tokenProvider)

Ship game clients without embedding an API key. Give the config a tokenProvider callback instead: your backend verifies the player (its own session/JWT), calls the OddSockets POST /v1/token mint endpoint with its API key server-side, and returns the short-lived token. The SDK invokes your callback for a fresh token before every connect, and silently re-mints it before expiry on a background thread while the client stays connected.

#include <oddsockets/OddSockets.hpp>

oddsockets::Config config;
config.userId = "player-1";
// No apiKey. The SDK calls this whenever it needs a fresh token
// (every connect + each pre-expiry refresh). Throw on failure.
config.tokenProvider = []() -> oddsockets::Token {
    // Ask YOUR backend for an OddSockets token, e.g.
    // POST https://your-game-backend.example.com/oddsockets/token
    // (authenticated with the player's own session).
    oddsockets::Token t;
    t.token = fetchTokenFromMyBackend(); // the minted JWT
    // Optional: t.exp (epoch seconds) or t.expiresAt (ISO 8601).
    // Leave both unset and the SDK reads the JWT's own exp claim.
    return t;
};

auto client = std::make_unique<oddsockets::OddSockets>(config);
client->on("token_refreshed", [](const std::string& payload) {
    // {"expiresAt":<epoch ms>}
});
client->connect().get();

Notes:

  • Either an apiKey or a tokenProvider is required — the constructor throws InvalidApiKey when the config has neither.
  • The refreshed token is re-minted config.tokenRefreshLeadMs (default 120000) before the current one expires, on a dedicated background thread that is joined on disconnect(). A failed refresh emits token_refresh_failed and keeps the current connection; the next connect mints fresh.
  • Expiry resolution order: Token::exp (epoch seconds) → Token::expiresAt (ISO 8601) → the exp claim decoded from the JWT itself.

Get a Free API Key

curl -X POST https://oddsockets.com/api/agent-signup \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "agentName": "my-agent", "platform": "cpp"}'
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"}'

Plans

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
Channels 10 Unlimited Unlimited
Storage 100MB (24h) 50GB (6 months) Unlimited

Get Accredited

tyga.games accreditation

Prove you can build and operate real-time features on OddSockets — channels, presence, pub/sub, delivery guarantees and production liveops — on the stack itself. Three tiers (TCU / TCA / TCP), certified through tyga.games and delivered on ClassaaS.

Get accredited on tyga.games →

Support

License

MIT License - Copyright (c) 2026 Joe Wee, Tyga.Cloud Ltd. See LICENSE for details.

About

C++ SDK for OddSockets — real-time WebSocket channels, pub/sub, presence. C++17.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages