Real-world examples showing how to use the OddSockets Go SDK in production applications with proper Go patterns and concurrency
View on GitHubpackage main
import (
"context"
"fmt"
"log"
"github.com/tygacloud/oddsocketsai-go-sdk/oddsockets"
)
func main() {
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_live_1234567890abcdef",
})
if err != nil {
log.Fatal(err)
}
defer client.Close()
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
channel := client.Channel("my-channel")
messages := make(chan *oddsockets.Message, 100)
if err := channel.Subscribe(ctx, messages, nil); err != nil {
log.Fatal(err)
}
go func() {
for msg := range messages {
fmt.Printf("Received: %+v\n", msg.Data)
}
}()
result, err := channel.Publish(ctx, "Hello, World!", nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Published: %s\n", result.MessageID)
}
package main
import (
"context"
"fmt"
"sync"
"time"
"github.com/tygacloud/oddsocketsai-go-sdk/oddsockets"
)
func main() {
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_live_1234567890abcdef",
})
if err != nil {
panic(err)
}
defer client.Close()
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
panic(err)
}
// Worker pool pattern
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(workerID int) {
defer wg.Done()
channel := client.Channel(fmt.Sprintf("worker-%d", workerID))
messages := make(chan *oddsockets.Message, 100)
if err := channel.Subscribe(ctx, messages, nil); err != nil {
fmt.Printf("Worker %d failed: %v\n", workerID, err)
return
}
for msg := range messages {
fmt.Printf("Worker %d: %+v\n", workerID, msg.Data)
}
}(i)
}
wg.Wait()
}
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/tygacloud/oddsocketsai-go-sdk/oddsockets"
)
func main() {
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_live_1234567890abcdef",
ReconnectAttempts: 5,
HeartbeatInterval: 30 * time.Second,
})
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
// Add error event handler
client.On(oddsockets.EventError, func(eventType oddsockets.EventType, data interface{}) {
fmt.Printf("ā Error occurred: %v\n", data)
})
client.On(oddsockets.EventReconnected, func(eventType oddsockets.EventType, data interface{}) {
fmt.Println("ā
Reconnected successfully")
})
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
log.Fatalf("Connection failed: %v", err)
}
channel := client.Channel("error-handling-demo")
messages := make(chan *oddsockets.Message, 100)
if err := channel.Subscribe(ctx, messages, nil); err != nil {
log.Fatalf("Subscription failed: %v", err)
}
// Handle messages with error recovery
for {
select {
case msg, ok := <-messages:
if !ok {
fmt.Println("Channel closed, attempting to reconnect...")
return
}
fmt.Printf("šØ Received: %+v\n", msg.Data)
case <-ctx.Done():
fmt.Println("Context cancelled")
return
}
}
}
package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/tygacloud/oddsocketsai-go-sdk/oddsockets"
)
func main() {
// Create cancellable context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Handle graceful shutdown
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigChan
fmt.Println("\nš Shutting down gracefully...")
cancel()
}()
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_live_1234567890abcdef",
})
if err != nil {
panic(err)
}
defer client.Close()
if err := client.Connect(ctx); err != nil {
panic(err)
}
channel := client.Channel("graceful-shutdown")
messages := make(chan *oddsockets.Message, 100)
if err := channel.Subscribe(ctx, messages, nil); err != nil {
panic(err)
}
// Message processor with context cancellation
go func() {
for {
select {
case msg, ok := <-messages:
if !ok {
return
}
fmt.Printf("šØ Processing: %+v\n", msg.Data)
// Simulate processing with cancellation support
select {
case <-time.After(2 * time.Second):
fmt.Println("ā
Processing complete")
case <-ctx.Done():
fmt.Println("ā¹ļø Processing cancelled")
return
}
case <-ctx.Done():
fmt.Println("š Processor shutting down")
return
}
}
}()
// Wait for cancellation
<-ctx.Done()
fmt.Println("š Shutdown complete")
}
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"time"
"github.com/tygacloud/oddsocketsai-go-sdk/oddsockets"
)
type Service struct {
client *oddsockets.Client
health bool
}
func (s *Service) healthHandler(w http.ResponseWriter, r *http.Request) {
status := map[string]interface{}{
"status": "healthy",
"connected": s.client.IsConnected(),
"timestamp": time.Now().Unix(),
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(status)
}
func (s *Service) messageHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var payload map[string]interface{}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
channel := s.client.Channel("microservice-events")
result, err := channel.Publish(context.Background(), payload, nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
response := map[string]interface{}{
"message_id": result.MessageID,
"timestamp": result.Timestamp,
"success": true,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func main() {
service := &Service{}
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_live_1234567890abcdef",
})
if err != nil {
log.Fatal(err)
}
service.client = client
defer client.Close()
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
// HTTP server for health checks and API
http.HandleFunc("/health", service.healthHandler)
http.HandleFunc("/message", service.messageHandler)
fmt.Println("š Microservice starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
package main
import (
"context"
"testing"
"time"
"github.com/tygacloud/oddsocketsai-go-sdk/oddsockets"
)
func TestBasicConnection(t *testing.T) {
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_test_1234567890abcdef",
})
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := client.Connect(ctx); err != nil {
t.Fatalf("Failed to connect: %v", err)
}
if !client.IsConnected() {
t.Error("Client should be connected")
}
}
func TestMessagePublishing(t *testing.T) {
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_test_1234567890abcdef",
})
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
t.Fatalf("Failed to connect: %v", err)
}
channel := client.Channel("test-channel")
result, err := channel.Publish(ctx, "test message", nil)
if err != nil {
t.Fatalf("Failed to publish: %v", err)
}
if result.MessageID == "" {
t.Error("Message ID should not be empty")
}
if !result.Success {
t.Error("Publish should be successful")
}
}
func TestMessageSubscription(t *testing.T) {
client, err := oddsockets.NewClient(&oddsockets.Config{
APIKey: "ak_test_1234567890abcdef",
})
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
t.Fatalf("Failed to connect: %v", err)
}
channel := client.Channel("test-subscription")
messages := make(chan *oddsockets.Message, 10)
if err := channel.Subscribe(ctx, messages, nil); err != nil {
t.Fatalf("Failed to subscribe: %v", err)
}
// Publish a test message
testMessage := "subscription test"
if _, err := channel.Publish(ctx, testMessage, nil); err != nil {
t.Fatalf("Failed to publish test message: %v", err)
}
// Wait for message
select {
case msg := <-messages:
if msg.Data != testMessage {
t.Errorf("Expected %q, got %q", testMessage, msg.Data)
}
case <-time.After(5 * time.Second):
t.Error("Timeout waiting for message")
}
}