Welcome! This guide will help you get up and running with the EnSync Go SDK in minutes.
- Go 1.21 or later - Download Go
- Access to EnSync server - Local or cloud instance
- Access key - Obtain from your EnSync dashboard
go get github.com/EnSync-engine/Go-SDKmkdir my-ensync-app
cd my-ensync-app
go mod init my-ensync-appCreate a file named main.go:
package main
import (
"context"
"log"
ensync "github.com/EnSync-engine/Go-SDK/grpc"
)
func main() {
ctx := context.Background()
// Create engine - establishes gRPC connection
engine, err := ensync.NewGRPCEngine(ctx, "grpc://localhost:50051")
if err != nil {
log.Fatal(err)
}
defer engine.Close()
// Authenticate with EnSync protocol
err = engine.CreateClient("your-access-key")
if err != nil {
log.Fatal(err)
}
log.Println("Connected to EnSync!")
}go run main.gopackage main
import (
"context"
"log"
"github.com/EnSync-engine/Go-SDK/common"
ensync "github.com/EnSync-engine/Go-SDK/grpc"
)
func main() {
ctx := context.Background()
// Create engine - establishes gRPC connection
engine, _ := ensync.NewGRPCEngine(ctx, "grpc://localhost:50051")
defer engine.Close()
// Authenticate with EnSync protocol
engine.CreateClient("your-access-key")
// Publish an event
eventID, err := engine.Publish(
"myapp/user/created", // Event name
[]string{"recipient-public-key-base64"}, // Recipients
map[string]interface{}{ // Payload
"userId": "12345",
"email": "user@example.com",
"name": "John Doe",
},
nil, // Metadata (optional)
nil, // Options (optional)
)
if err != nil {
log.Fatal(err)
}
log.Printf("Event published with ID: %s", eventID)
}package main
import (
"context"
"log"
"os"
"os/signal"
"syscall"
"github.com/EnSync-engine/Go-SDK/common"
ensync "github.com/EnSync-engine/Go-SDK/grpc"
)
func main() {
ctx := context.Background()
// Create engine - establishes gRPC connection
engine, _ := ensync.NewGRPCEngine(ctx, "grpc://localhost:50051")
defer engine.Close()
// Authenticate with EnSync protocol
engine.CreateClient("your-access-key")
// Subscribe to events
subscription, err := engine.Subscribe(
"myapp/user/created",
&common.SubscribeOptions{AutoAck: true},
)
if err != nil {
log.Fatal(err)
}
// Handle events
subscription.AddHandler(func(event *common.EventPayload) error {
log.Printf("New user created!")
log.Printf("User ID: %v", event.Payload["userId"])
log.Printf("Email: %v", event.Payload["email"])
log.Printf("Name: %v", event.Payload["name"])
return nil
})
log.Println("Listening for events... Press Ctrl+C to exit")
// Wait for interrupt
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
<-sigChan
log.Println("Shutting down...")
subscription.Unsubscribe()
}import (
"context"
ensync "github.com/EnSync-engine/Go-SDK/grpc"
)
ctx := context.Background()
// Insecure (development)
engine, _ := ensync.NewGRPCEngine(ctx, "grpc://localhost:50051")
// Secure (production)
engine, _ := ensync.NewGRPCEngine(ctx, "grpcs://node.ensync.cloud:50051")Best for:
- Server-to-server communication
- High-performance requirements
- Binary protocol efficiency
import (
"context"
ensync "github.com/EnSync-engine/Go-SDK/websocket"
)
ctx := context.Background()
// Insecure (development)
engine, _ := ensync.NewWebSocketEngine(ctx, "ws://localhost:8082")
// Secure (production)
engine, _ := ensync.NewWebSocketEngine(ctx, "wss://node.ensync.cloud:8082")Best for:
- Real-time applications
- Browser compatibility
- Bidirectional streaming
// Publisher
eventID, _ := engine.Publish(
"myapp/request/data",
[]string{recipientKey},
map[string]interface{}{"requestId": "123"},
nil, nil,
)
// Subscriber
subscription.AddHandler(func(event *common.EventPayload) error {
requestId := event.Payload["requestId"]
// Process request and send response
engine.Publish(
"myapp/response/data",
[]string{event.Sender},
map[string]interface{}{
"requestId": requestId,
"data": "response data",
},
nil, nil,
)
return nil
})// Send to multiple recipients
recipients := []string{
"recipient1-key",
"recipient2-key",
"recipient3-key",
}
eventID, _ := engine.Publish(
"myapp/notification/broadcast",
recipients,
map[string]interface{}{"message": "Hello everyone!"},
nil,
&common.PublishOptions{UseHybridEncryption: true},
)subscription.AddHandler(func(event *common.EventPayload) error {
// Try to process
if err := processEvent(event); err != nil {
// Defer for retry in 5 seconds
subscription.Defer(event.Idem, 5000, "Processing failed, will retry")
return err
}
// Success - acknowledge
return subscription.Ack(event.Idem, event.Block)
})var failureCount int
var maxFailures = 5
subscription.AddHandler(func(event *common.EventPayload) error {
if failureCount >= maxFailures {
// Pause processing
subscription.Pause("Too many failures")
log.Println("Circuit breaker opened - pausing events")
// Schedule resume after cooldown
go func() {
time.Sleep(1 * time.Minute)
subscription.Resume()
failureCount = 0
log.Println("Circuit breaker closed - resuming events")
}()
return nil
}
if err := processEvent(event); err != nil {
failureCount++
return err
}
failureCount = 0 // Reset on success
return nil
})export ENSYNC_URL="grpc://localhost:50051"
export ENSYNC_ACCESS_KEY="your-access-key"
export ENSYNC_APP_SECRET="your-app-secret"import (
"context"
"os"
"github.com/EnSync-engine/Go-SDK/common"
ensync "github.com/EnSync-engine/Go-SDK/grpc"
)
ctx := context.Background()
engine, _ := ensync.NewGRPCEngine(ctx, os.Getenv("ENSYNC_URL"))
engine.CreateClient(
os.Getenv("ENSYNC_ACCESS_KEY"),
common.WithAppSecretKey(os.Getenv("ENSYNC_APP_SECRET")),
)import (
"context"
"time"
"github.com/EnSync-engine/Go-SDK/common"
ensync "github.com/EnSync-engine/Go-SDK/grpc"
)
ctx := context.Background()
engine, _ := ensync.NewGRPCEngine(
ctx,
"grpc://localhost:50051",
common.WithRetryConfig(5, 2*time.Second, 30*time.Second, 0.2),
)import (
"context"
"time"
"github.com/EnSync-engine/Go-SDK/common"
ensync "github.com/EnSync-engine/Go-SDK/grpc"
)
ctx := context.Background()
engine, _ := ensync.NewGRPCEngine(
ctx,
"grpc://localhost:50051",
// Circuit breaker - pause after 5 failures for 30 seconds
common.WithCircuitBreaker(5, 30 * time.Second),
// Retry logic - 3 attempts with exponential backoff
common.WithRetryConfig(3, time.Second, 10 * time.Second, 0.1),
// Custom logger (implement common.Logger interface)
// common.WithLogger(myCustomLogger),
)
// Client authentication with options
engine.CreateClient(
"your-access-key",
common.WithAppSecretKey("your-app-secret"),
common.WithClientID("my-service-v1"),
)import (
"context"
"time"
"github.com/EnSync-engine/Go-SDK/common"
ensync "github.com/EnSync-engine/Go-SDK/websocket"
)
ctx := context.Background()
engine, _ := ensync.NewWebSocketEngine(
ctx,
"ws://localhost:8082",
// Same common options as gRPC
)import "log"
// Set log flags for detailed output
log.SetFlags(log.LstdFlags | log.Lshortfile)
// The SDK logs important events automaticallyerr := engine.CreateClient(accessKey)
if err != nil {
if ensyncErr, ok := err.(*common.EnSyncError); ok {
log.Printf("Error type: %s", ensyncErr.Type)
log.Printf("Error message: %s", ensyncErr.Message)
}
}eventID, err := engine.Publish(
"test/event",
[]string{"recipient-public-key-base64"},
map[string]interface{}{"test": "data"},
nil, nil,
)
if err != nil {
log.Printf("Publish failed: %v", err)
} else {
log.Printf("Published: %s", eventID)
}- Read the full documentation: README.md
- Explore examples: Check the
examples/directory - Learn design patterns: Read DESIGN.md
- Build something: Start with the QUICKSTART.md
- Ensure EnSync server is running
- Check the URL and port
- Verify firewall settings
- Verify your access key is correct
- Check if the key has expired
- Ensure you're connecting to the right server
- Verify subscription is active
- Check event name matches exactly
- Ensure your program keeps running (use signal handling)
- Verify you have the correct decryption key
- Verify recipient public key is valid base64
- Ensure key is 32 bytes when decoded
- Check if using the correct key format
- Always use
defer engine.Close()to ensure cleanup - Handle errors explicitly - don't ignore them
- Use environment variables for credentials
- Test with self-publishing first (send to your own public key)
- Start with AutoAck: true then move to manual acknowledgment
- Use hybrid encryption for multiple recipients
- Quick Start: QUICKSTART.md
- Full API Reference: README.md
- Design Patterns: DESIGN.md
- Examples:
examples/directory - Contributing: CONTRIBUTING.md
- GitHub Issues: Report bugs or request features
- Documentation: https://docs.tryensync.com
- EnSync Cloud: https://ensync.cloud
Ready to build? Start with the QUICKSTART.md guide! π