Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OddSockets Go SDK

Go Reference Go Report Card License: MIT

Official Go SDK for OddSockets real-time messaging platform.

Features

  • High Performance: Optimized for Go's concurrency model with goroutines
  • Channels & Context: Native Go patterns with context cancellation
  • Type Safety: Strong typing with Go structs and interfaces
  • Enhanced Surface: Slack-like reactions, threads, typing, presence and more
  • Cost Effective: No per-message pricing, no message size limits
  • Cloud Native: Perfect for microservices and Kubernetes deployments

📦 Installation

go get github.com/jyswee/oddsockets-go-sdk

🏃‍♂️ Quick Start

Basic Usage

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/jyswee/oddsockets-go-sdk/oddsockets"
)

func main() {
    // Create client
    client, err := oddsockets.NewClient(&oddsockets.Config{
        APIKey:     "ak_live_1234567890abcdef",
        ManagerURL: "https://connect.oddsockets.tyga.network",
        UserID:     "go-demo-user",
    })
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // Connect to OddSockets
    ctx := context.Background()
    if err := client.Connect(ctx); err != nil {
        log.Fatal(err)
    }

    // Create channel
    channel := client.Channel("my-channel")

    // Subscribe to messages
    messages := make(chan *oddsockets.Message, 100)
    if err := channel.Subscribe(ctx, messages, &oddsockets.SubscribeOptions{
        EnablePresence: true,
        RetainHistory:  true,
    }); err != nil {
        log.Fatal(err)
    }

    // Handle messages in goroutine
    go func() {
        for msg := range messages {
            fmt.Printf("Received: %+v\n", msg.Data)
        }
    }()

    // Publish a message
    if err := channel.Publish(ctx, "Hello from Go! 🐹", nil); err != nil {
        log.Fatal(err)
    }

    // Keep alive
    time.Sleep(5 * time.Second)
}

Context and Cancellation

package main

import (
    "context"
    "time"

    "github.com/jyswee/oddsockets-go-sdk/oddsockets"
)

func main() {
    client, _ := oddsockets.NewClient(&oddsockets.Config{
        APIKey: "ak_live_1234567890abcdef",
    })
    defer client.Close()

    // Context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // Connect with context
    client.Connect(ctx)

    channel := client.Channel("timed-channel")
    messages := make(chan *oddsockets.Message, 10)

    // Subscribe with context cancellation
    go func() {
        channel.Subscribe(ctx, messages, nil)
    }()

    // Context will automatically cancel subscription after timeout
}

Token auth for game clients (TokenProvider)

Game and app clients should never ship a static API key. Instead, supply a TokenProvider callback that exchanges your player's own JWT for a short-lived, scoped realtime token via the OddSockets /v1/token front door. The SDK calls it before every (re)connect and again shortly before the token expires, so the connection refreshes itself with no restart.

client, _ := oddsockets.NewClient(&oddsockets.Config{
    // No APIKey. The provider supplies a fresh minted token instead.
    TokenProvider: func(ctx context.Context) (oddsockets.Token, error) {
        // Exchange the signed-in player's JWT for a realtime token.
        // POST https://connect.oddsockets.tyga.network/v1/token
        //   Authorization: Bearer <player JWT>
        // -> { token, expiresAt, exp, baseUrl, identity }
        return mintRealtimeToken(ctx, playerJWT())
    },
    // Refresh this many ms before expiry (default 120000).
    TokenRefreshLeadMs: 120000,
})

// token_refreshed fires each time the SDK rotates the token in place.
client.On("token_refreshed", func(_ oddsockets.EventType, data interface{}) {
    log.Printf("realtime token refreshed: %+v", data)
})

client.Connect(context.Background())

The Token returned by your provider only needs Token; ExpiresAt (ISO-8601 or epoch), Exp (epoch seconds), or the JWT's own exp claim are used to schedule the ahead-of-expiry refresh.

Enhanced Features

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 the exported client.Enhanced field. The pattern is always the same:

  1. Send an action with a client.Enhanced.* method.
  2. Receive the paired broadcast with client.On("<event>", handler).
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/jyswee/oddsockets-go-sdk/oddsockets"
)

func main() {
    client, err := oddsockets.NewClient(&oddsockets.Config{
        APIKey: "ak_live_1234567890abcdef",
        UserID: "alice",
    })
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    ctx := context.Background()
    if err := client.Connect(ctx); err != nil {
        log.Fatal(err)
    }

    // Receive-path: broadcasts from other users on the channel
    client.On("user_typing", func(_ oddsockets.EventType, data interface{}) {
        m, _ := data.(map[string]interface{})
        fmt.Printf("%v is typing\n", m["userId"])
    })
    client.On("reaction_added", func(_ oddsockets.EventType, data interface{}) {
        m, _ := data.(map[string]interface{})
        fmt.Printf("%v reacted %v\n", m["userId"], m["emoji"])
    })

    channel := client.Channel("room-42")
    msgs := make(chan *oddsockets.Message, 100)
    channel.Subscribe(ctx, msgs, &oddsockets.SubscribeOptions{EnablePresence: true})

    // Send-path: enhanced actions over the live socket
    client.Enhanced.StartTyping("alice", "room-42")
    client.Enhanced.AddReaction(oddsockets.ReactionParams{
        MessageID: "msg-1",
        Channel:   "room-42",
        Emoji:     ":thumbsup:",
        UserID:    "alice",
        UserName:  "Alice",
    })
    client.Enhanced.ThreadReply(oddsockets.ThreadReplyParams{
        Channel:         "room-42",
        ParentMessageID: "msg-1",
        Message:         "Replying in the thread",
        UserID:          "alice",
        UserName:        "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 (map[string]interface{}, error) 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 (map, error) 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 event stream.

Examples

Explore the runnable examples:

Configuration

Client Options

config := &oddsockets.Config{
    APIKey:             "your-api-key",       // Your OddSockets API key (or use TokenProvider)
    TokenProvider:      provider,             // Optional: mint minted tokens instead of an API key
    TokenRefreshLeadMs: 120000,               // Optional: refresh lead time before token expiry
    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:  30 * time.Second,     // Optional: Heartbeat interval
    Timeout:            10 * time.Second,     // Optional: Request timeout
}
// Provide EITHER APIKey OR TokenProvider.

Channel Options

// Subscribe with options
err := channel.Subscribe(ctx, messages, &oddsockets.SubscribeOptions{
    EnablePresence:    true,                  // Enable presence tracking
    RetainHistory:     true,                  // Retain message history
    FilterExpression:  "user.premium == true", // Message filter expression
})

// Publish with options
err := channel.Publish(ctx, message, &oddsockets.PublishOptions{
    TTL:             3600,                    // Time to live (seconds)
    Metadata:        map[string]interface{}{"priority": "high"}, // Additional metadata
    StoreInHistory:  true,                    // Store in message history
})

Go Support

  • Go 1.19+
  • Goroutines and channels
  • Context cancellation
  • Structured concurrency

Testing

# Run tests
go test ./...

# Run tests with coverage
go test -cover ./...

# Run benchmarks
go test -bench=. ./...

# Run integration tests
go test -tags=integration ./...

Building

# Get dependencies
go mod tidy

# Build
go build ./...

# Install
go install ./...

# Cross-compile
GOOS=linux GOARCH=amd64 go build -o oddsockets-linux ./cmd/example

Performance

OddSockets Go 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 goroutines

Security

  • End-to-end encryption available
  • API key authentication with fine-grained permissions
  • Rate limiting and abuse protection
  • GDPR compliant data handling

Framework Integrations

Gin Web Framework

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/jyswee/oddsockets-go-sdk/oddsockets"
)

func main() {
    client, _ := oddsockets.NewClient(&oddsockets.Config{
        APIKey: "ak_live_1234567890abcdef",
    })
    defer client.Close()

    r := gin.Default()
    
    r.POST("/send-message", func(c *gin.Context) {
        var req struct {
            Channel string      `json:"channel"`
            Message interface{} `json:"message"`
        }
        
        if err := c.ShouldBindJSON(&req); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        
        channel := client.Channel(req.Channel)
        if err := channel.Publish(c.Request.Context(), req.Message, nil); err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        
        c.JSON(200, gin.H{"status": "sent"})
    })
    
    r.Run(":8080")
}

gRPC Service

package main

import (
    "context"
    
    "github.com/jyswee/oddsockets-go-sdk/oddsockets"
    "google.golang.org/grpc"
)

type MessageService struct {
    client *oddsockets.Client
}

func (s *MessageService) SendMessage(ctx context.Context, req *SendMessageRequest) (*SendMessageResponse, error) {
    channel := s.client.Channel(req.Channel)
    
    if err := channel.Publish(ctx, req.Message, nil); err != nil {
        return nil, err
    }
    
    return &SendMessageResponse{Success: true}, nil
}

Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: oddsockets-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: oddsockets-service
  template:
    metadata:
      labels:
        app: oddsockets-service
    spec:
      containers:
      - name: service
        image: your-registry/oddsockets-service:latest
        env:
        - name: ODDSOCKETS_API_KEY
          valueFrom:
            secretKeyRef:
              name: oddsockets-secret
              key: api-key
        - name: ODDSOCKETS_MANAGER_URL
          value: "https://connect.oddsockets.tyga.network"

Other SDKs

OddSockets is available in multiple languages:

  • JavaScript SDK - Browser + Node.js, TypeScript ready
  • Python SDK - AsyncIO support, Django/Flask integrations
  • Java SDK - Enterprise-ready, Spring Boot integration
  • C# SDK - .NET Core/Framework, Azure integrations
  • Swift SDK - iOS native, Combine framework
  • Kotlin SDK - Android native, coroutines support

Get a Free API Key

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": "go"}'

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"}'

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
Messages/minute 100 3,000 Unlimited
Channels 10 Unlimited Unlimited
Storage 100MB (24h) 50GB (6 months) Unlimited

All limits are enforced in real time.

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

Go SDK for OddSockets — real-time WebSocket channels, pub/sub, presence. Goroutine-safe.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages