OddSockets Elixir SDK
Official Elixir SDK for OddSockets real-time messaging platform
Overview & Features
The OddSockets Elixir SDK provides a powerful, fault-tolerant interface for real-time messaging built on Elixir/OTP principles.
Elixir/OTP Native
Built with GenServers and supervision trees for maximum fault tolerance.
JavaScript Compatible
Full API compliance with JavaScript SDK pattern while maintaining Elixir idioms.
High Performance
Leverages Elixir's lightweight processes for concurrent message handling.
Fault Tolerant
Automatic reconnection and supervision for 99.9% uptime.
Cost Effective
No per-message pricing, industry-standard 32KB message limits.
Presence Tracking
Real-time user presence and state management with OTP patterns.
Installation
Add oddsockets to your list of dependencies in mix.exs:
def deps do
[
{:oddsockets, "~> 1.0.0"}
]
end
Then run:
mix deps.get
def deps do
[
{:oddsockets, git: "https://github.com/oddsockets/elixir-sdk.git"}
]
end
def deps do
[
{:oddsockets, path: "../oddsockets"}
]
end
Quick Start
Basic Usage
# Start a client
{:ok, client} = OddSockets.start_link(api_key: "ak_live_1234567890abcdef")
# Get a channel
channel = OddSockets.channel(client, "my-channel")
# Subscribe to messages
:ok = OddSockets.Channel.subscribe(channel, fn message ->
IO.inspect(message, label: "Received")
end)
# Publish a message
{:ok, result} = OddSockets.Channel.publish(channel, %{text: "Hello World!"})
GenServer Integration
defmodule MyApp.ChatServer do
use GenServer
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
def init(_opts) do
{:ok, client} = OddSockets.start_link(api_key: "your-api-key")
channel = OddSockets.channel(client, "chat-room")
:ok = OddSockets.Channel.subscribe(channel, &handle_message/1)
{:ok, %{client: client, channel: channel}}
end
defp handle_message(message) do
IO.puts("Chat message: #{inspect(message)}")
end
end
Event Handling
# Subscribe to client events
:ok = OddSockets.subscribe_events(client)
# Handle events in your process
receive do
{:oddsockets_event, :connected} ->
IO.puts("Connected to OddSockets!")
{:oddsockets_event, {:error, reason}} ->
IO.puts("Connection error: #{inspect(reason)}")
{:oddsockets_event, {:worker_assigned, info}} ->
IO.puts("Assigned to worker: #{info.worker_id}")
end
Configuration
Client Options
{:ok, client} = OddSockets.start_link(
api_key: "your-api-key", # Required: Your OddSockets API key
user_id: "user-id", # Optional: User identifier
auto_connect: true, # Optional: Auto-connect on creation
options: %{
timeout: 10_000 # Optional: Connection timeout (ms)
}
)
Channel Options
:ok = OddSockets.Channel.subscribe(channel, callback, %{
max_history: 100, # Maximum history messages to retain
retain_history: true, # Whether to retain message history
enable_presence: false # Enable presence tracking
})
{:ok, result} = OddSockets.Channel.publish(channel, message, %{
ttl: 3600, # Time to live (seconds)
metadata: %{priority: "high"} # Additional metadata
})
Application Configuration
# config/config.exs
config :oddsockets,
api_key: "your-api-key",
manager_url: "https://manager.oddsockets.com"
Examples
Explore comprehensive examples demonstrating the OddSockets Elixir SDK in action:
Performance & Compatibility
OddSockets Elixir SDK delivers superior performance with Elixir/OTP advantages:
Elixir Support
- Elixir 1.12+ (OTP 24+)
- Phoenix Framework
- LiveView Integration
- GenServer Patterns
OTP Features
- Supervision Trees
- Fault Tolerance
- Hot Code Reloading
- Distributed Systems
OTP Patterns & Integration
The OddSockets Elixir SDK is designed to work seamlessly with Elixir/OTP patterns and popular frameworks:
Phoenix Framework
defmodule MyAppWeb.ChatLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
{:ok, client} = OddSockets.start_link(api_key: "your-api-key")
channel = OddSockets.channel(client, "chat-room")
:ok = OddSockets.Channel.subscribe(channel, fn message ->
send(self(), {:new_message, message})
end)
{:ok, assign(socket, client: client, channel: channel, messages: [])}
end
def handle_info({:new_message, message}, socket) do
messages = [message | socket.assigns.messages]
{:noreply, assign(socket, messages: messages)}
end
def handle_event("send_message", %{"message" => text}, socket) do
{:ok, _} = OddSockets.Channel.publish(socket.assigns.channel, %{
text: text,
user: "current_user"
})
{:noreply, socket}
end
end
Supervision Tree
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
# Start OddSockets client as part of supervision tree
{OddSockets, api_key: "your-api-key", name: MyApp.OddSocketsClient},
# Other supervised processes
MyApp.Repo,
MyAppWeb.Endpoint,
{MyApp.ChatManager, []}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
GenServer Pattern
defmodule MyApp.NotificationManager do
use GenServer
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
def init(_opts) do
{:ok, client} = OddSockets.start_link(api_key: "your-api-key")
# Subscribe to multiple channels
channels = ["notifications", "alerts", "updates"]
|> Enum.map(fn name ->
channel = OddSockets.channel(client, name)
:ok = OddSockets.Channel.subscribe(channel, &handle_notification/1)
{name, channel}
end)
|> Map.new()
{:ok, %{client: client, channels: channels}}
end
def broadcast_notification(type, message) do
GenServer.cast(__MODULE__, {:broadcast, type, message})
end
def handle_cast({:broadcast, type, message}, state) do
case Map.get(state.channels, type) do
nil ->
{:noreply, state}
channel ->
{:ok, _} = OddSockets.Channel.publish(channel, message)
{:noreply, state}
end
end
defp handle_notification(message) do
# Process incoming notifications
IO.puts("Notification received: #{inspect(message)}")
end
end
Task and Agent Integration
defmodule MyApp.MessageProcessor do
def start_processing(api_key) do
{:ok, client} = OddSockets.start_link(api_key: api_key)
channel = OddSockets.channel(client, "processing-queue")
# Use Agent to store state
{:ok, agent} = Agent.start_link(fn -> %{processed: 0, errors: 0} end)
# Subscribe with async processing
:ok = OddSockets.Channel.subscribe(channel, fn message ->
Task.start(fn ->
process_message_async(message, agent)
end)
end)
{:ok, {client, channel, agent}}
end
defp process_message_async(message, agent) do
try do
# Process the message
result = process_message(message)
# Update success counter
Agent.update(agent, fn state ->
%{state | processed: state.processed + 1}
end)
result
rescue
error ->
# Update error counter
Agent.update(agent, fn state ->
%{state | errors: state.errors + 1}
end)
{:error, error}
end
end
defp process_message(message) do
# Your message processing logic here
IO.puts("Processing: #{inspect(message)}")
:ok
end
def get_stats(agent) do
Agent.get(agent, & &1)
end
end