#!/usr/bin/env elixir # Basic usage example for OddSockets Elixir SDK # Run with: elixir examples/basic_usage.exs defmodule BasicUsageExample do @moduledoc """ Basic usage example demonstrating core OddSockets functionality. """ def run do IO.puts("๐Ÿš€ OddSockets Elixir SDK - Basic Usage Example") IO.puts("=" |> String.duplicate(50)) # Start the client IO.puts("\n๐Ÿ“ก Starting OddSockets client...") {:ok, client} = OddSockets.start_link( api_key: get_api_key(), user_id: "example_user_#{:rand.uniform(1000)}", auto_connect: true ) # Subscribe to client events :ok = OddSockets.subscribe_events(client) IO.puts("โœ… Client started and event subscription enabled") # Wait for connection wait_for_connection() # Get a channel IO.puts("\n๐Ÿ“บ Creating channel...") channel = OddSockets.channel(client, "example-channel") IO.puts("โœ… Channel created: example-channel") # Subscribe to channel messages IO.puts("\n๐Ÿ”” Subscribing to channel messages...") :ok = OddSockets.Channel.subscribe(channel, &handle_message/1, %{ max_history: 50, retain_history: true, enable_presence: true }) IO.puts("โœ… Subscribed to channel messages") # Publish some messages IO.puts("\n๐Ÿ“ค Publishing messages...") publish_example_messages(channel) # Get message history IO.puts("\n๐Ÿ“œ Getting message history...") case OddSockets.Channel.get_history(channel, %{count: 10}) do {:ok, messages} -> IO.puts("โœ… Retrieved #{length(messages)} messages from history") {:error, reason} -> IO.puts("โŒ Failed to get history: #{inspect(reason)}") end # Get presence information IO.puts("\n๐Ÿ‘ฅ Getting presence information...") case OddSockets.Channel.get_presence(channel) do {:ok, presence} -> IO.puts("โœ… Current presence: #{presence.count} users online") {:error, reason} -> IO.puts("โŒ Failed to get presence: #{inspect(reason)}") end # Update user state IO.puts("\n๐Ÿ”„ Updating user state...") case OddSockets.Channel.update_state(channel, %{ status: "online", location: "Example City", mood: "excited" }) do {:ok, _result} -> IO.puts("โœ… User state updated") {:error, reason} -> IO.puts("โŒ Failed to update state: #{inspect(reason)}") end # Demonstrate bulk publishing IO.puts("\n๐Ÿ“ฆ Bulk publishing messages...") bulk_messages = [ %{channel: "example-channel", message: %{text: "Bulk message 1", type: "bulk"}}, %{channel: "example-channel", message: %{text: "Bulk message 2", type: "bulk"}}, %{channel: "example-channel", message: %{text: "Bulk message 3", type: "bulk"}} ] case OddSockets.publish_bulk(client, bulk_messages) do {:ok, results} -> successful = Enum.count(results, & &1.success) IO.puts("โœ… Bulk publish completed: #{successful}/#{length(results)} successful") {:error, reason} -> IO.puts("โŒ Bulk publish failed: #{inspect(reason)}") end # Get client information IO.puts("\n๐Ÿ“Š Client information:") IO.puts(" State: #{OddSockets.get_state(client)}") IO.puts(" Client ID: #{OddSockets.get_client_identifier(client)}") case OddSockets.get_worker_info(client) do nil -> IO.puts(" Worker: Not assigned") worker_info -> IO.puts(" Worker: #{worker_info.worker_id} (#{worker_info.worker_url})") end # Listen for events for a while IO.puts("\n๐Ÿ‘‚ Listening for events (10 seconds)...") listen_for_events(10_000) # Clean up IO.puts("\n๐Ÿงน Cleaning up...") :ok = OddSockets.Channel.unsubscribe(channel) :ok = OddSockets.disconnect(client) IO.puts("โœ… Disconnected and cleaned up") IO.puts("\n๐ŸŽ‰ Example completed successfully!") end defp get_api_key do case System.get_env("ODDSOCKETS_API_KEY") do nil -> IO.puts("โš ๏ธ Using demo API key. Set ODDSOCKETS_API_KEY environment variable for your own key.") "demo-api-key-for-testing" api_key -> IO.puts("โœ… Using API key from environment") api_key end end defp wait_for_connection do receive do {:oddsockets_event, :connected} -> IO.puts("โœ… Connected to OddSockets!") {:oddsockets_event, {:worker_assigned, info}} -> IO.puts("โœ… Assigned to worker: #{info.worker_id}") wait_for_connection() {:oddsockets_event, {:error, reason}} -> IO.puts("โŒ Connection error: #{inspect(reason)}") wait_for_connection() {:oddsockets_event, :connecting} -> IO.puts("๐Ÿ”„ Connecting...") wait_for_connection() after 15_000 -> IO.puts("โฐ Connection timeout - continuing anyway") end end defp handle_message(message) do case message do %{"text" => text, "user" => user} -> IO.puts("๐Ÿ’ฌ [#{user}]: #{text}") %{"type" => "presence_change", "action" => action, "user" => user} -> IO.puts("๐Ÿ‘ค User #{user["user_id"]} #{action}") %{"text" => text} -> IO.puts("๐Ÿ’ฌ Message: #{text}") _ -> IO.puts("๐Ÿ“จ Received: #{inspect(message)}") end end defp publish_example_messages(channel) do messages = [ %{text: "Hello from Elixir SDK!", user: "elixir_example", timestamp: DateTime.utc_now()}, %{text: "This is a test message", user: "elixir_example", priority: "normal"}, %{text: "OddSockets is working great! ๐ŸŽ‰", user: "elixir_example", mood: "excited"} ] Enum.each(messages, fn message -> case OddSockets.Channel.publish(channel, message, %{ttl: 300}) do {:ok, result} -> IO.puts("โœ… Published message: #{result.message_id}") {:error, reason} -> IO.puts("โŒ Failed to publish: #{inspect(reason)}") end # Small delay between messages Process.sleep(500) end) end defp listen_for_events(timeout) do receive do {:oddsockets_event, event} -> case event do :connected -> IO.puts("๐Ÿ”— Event: Connected") :disconnected -> IO.puts("๐Ÿ”Œ Event: Disconnected") {:error, reason} -> IO.puts("โŒ Event: Error - #{inspect(reason)}") {:reconnecting, info} -> IO.puts("๐Ÿ”„ Event: Reconnecting (attempt #{info.attempt}/#{info.max_attempts})") {:worker_assigned, info} -> IO.puts("๐Ÿญ Event: Worker assigned - #{info.worker_id}") :max_reconnect_attempts_reached -> IO.puts("๐Ÿšซ Event: Max reconnect attempts reached") _ -> IO.puts("๐Ÿ“ก Event: #{inspect(event)}") end listen_for_events(timeout) after timeout -> IO.puts("โฐ Event listening timeout") end end end # Run the example try do BasicUsageExample.run() rescue e -> IO.puts("\nโŒ Example failed with error:") IO.puts(" #{Exception.format(:error, e, __STACKTRACE__)}") System.halt(1) end