OddSockets Kotlin SDK

Official Kotlin SDK for OddSockets real-time messaging platform

Android Ready JVM Compatible Coroutines High Performance Type Safe

Overview & Features

The OddSockets Kotlin SDK provides a powerful, coroutine-based interface for real-time messaging in Android applications and JVM environments.

Android Native

Built specifically for Android with lifecycle-aware components and modern architecture patterns.

Kotlin Coroutines

Fully async with Kotlin coroutines and Flow for reactive programming patterns.

Type Safety

Complete type safety with Kotlin's null safety and comprehensive error handling.

High Performance

Optimized for mobile with efficient WebSocket connections and smart resource management.

Cost Effective

No per-message pricing, industry-standard 32KB message limits, transparent pricing.

Session Stickiness

Built-in session management for consistent worker assignment and optimal performance.

Installation

kotlin
dependencies {
    implementation("com.oddsockets:kotlin-sdk:1.0.0")
}
groovy
dependencies {
    implementation 'com.oddsockets:kotlin-sdk:1.0.0'
}
xml
<dependency>
    <groupId>com.oddsockets</groupId>
    <artifactId>kotlin-sdk</artifactId>
    <version>1.0.0</version>
</dependency>

Quick Start

Basic Usage

kotlin
import com.oddsockets.OddSocketsClient
import com.oddsockets.config.OddSocketsConfig
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val client = OddSocketsClient(
        OddSocketsConfig.default("ak_live_1234567890abcdef")
    )

    val channel = client.channel("my-channel")

    // Subscribe to messages
    channel.subscribe { message ->
        println("Received: ${message.message}")
    }

    // Publish a message
    channel.publish("Hello, World!")
}

Android Usage

kotlin
class MainActivity : AppCompatActivity() {
    private lateinit var client: OddSocketsClient
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        client = OddSocketsClient(
            OddSocketsConfig.default("ak_live_1234567890abcdef")
        )
        
        val channel = client.channel("chat-room")
        
        // Subscribe with lifecycle awareness
        lifecycleScope.launch {
            channel.messageFlow.collect { message ->
                // Update UI with new message
                updateChatUI(message)
            }
        }
        
        // Publish message
        lifecycleScope.launch {
            channel.publish("Hello from Android!")
        }
    }
    
    override fun onDestroy() {
        super.onDestroy()
        client.close()
    }
}

Coroutines & Flow

kotlin
// Using Flow for reactive programming
channel.messageFlow
    .filter { it.metadata?.get("priority") == "high" }
    .map { it.message.toString() }
    .collect { highPriorityMessage ->
        handleUrgentMessage(highPriorityMessage)
    }

// Connection state monitoring
client.connectionState
    .collect { state ->
        when (state) {
            ConnectionState.CONNECTED -> showConnectedUI()
            ConnectionState.DISCONNECTED -> showDisconnectedUI()
            ConnectionState.RECONNECTING -> showReconnectingUI()
        }
    }

Configuration

Client Configuration

kotlin
val client = OddSocketsClient.create("ak_live_1234567890abcdef") {
    userId = "user-123"                    // Optional: User identifier
    autoConnect = true                     // Optional: Auto-connect on creation
    reconnectAttempts = 5                  // Optional: Max reconnection attempts
    heartbeatInterval = 30.seconds         // Optional: Heartbeat interval
    timeout = 10.seconds                   // Optional: Operation timeout
}

Channel Configuration

kotlin
// Subscribe with options
channel.subscribe(messageHandler) {
    enablePresence = true                  // Enable presence tracking
    retainHistory = true                   // Retain message history
    filterExpression = "user.premium == true"  // Message filter
}

// Publish with options
channel.publish("Hello World!") {
    ttl = 3600                            // Time to live (seconds)
    metadata = mapOf("priority" to "high") // Additional metadata
    storeInHistory = true                 // Store in message history
}

Examples

Explore comprehensive examples demonstrating the OddSockets Kotlin SDK in action:

Performance & Compatibility

OddSockets Kotlin SDK delivers superior performance with broad compatibility:

<50ms
Latency
99.9%
Uptime
32KB
Max Message
1M+
Messages/sec

Platform Support

  • Android API 21+ (5.0 Lollipop)
  • JVM 8+ (Server-side)
  • Kotlin 1.8+
  • Kotlin Multiplatform

Dependencies

  • Kotlin Coroutines
  • Ktor Client
  • Kotlinx Serialization
  • Kotlin Flow

Framework Integrations

The OddSockets Kotlin SDK works seamlessly with modern Android architecture patterns and frameworks:

Jetpack Compose

kotlin
@Composable
fun ChatScreen(client: OddSocketsClient) {
    val messages by client.channel("chat")
        .messageFlow
        .collectAsState(initial = emptyList())
    
    val connectionState by client.connectionState
        .collectAsState()
    
    Column {
        // Connection status
        when (connectionState) {
            ConnectionState.CONNECTED -> {
                Text("Connected", color = Color.Green)
            }
            ConnectionState.RECONNECTING -> {
                Text("Reconnecting...", color = Color.Orange)
            }
            else -> {
                Text("Disconnected", color = Color.Red)
            }
        }
        
        // Messages list
        LazyColumn {
            items(messages) { message ->
                MessageItem(message = message)
            }
        }
        
        // Send message
        var inputText by remember { mutableStateOf("") }
        Row {
            TextField(
                value = inputText,
                onValueChange = { inputText = it }
            )
            Button(
                onClick = {
                    client.channel("chat").publish(inputText)
                    inputText = ""
                }
            ) {
                Text("Send")
            }
        }
    }
}

MVVM with ViewModel

kotlin
class ChatViewModel : ViewModel() {
    private val client = OddSocketsClient(
        OddSocketsConfig.default("ak_live_1234567890abcdef")
    )
    
    private val channel = client.channel("chat-room")
    
    private val _messages = MutableLiveData<List<Message>>()
    val messages: LiveData<List<Message>> = _messages
    
    private val _connectionState = MutableLiveData<ConnectionState>()
    val connectionState: LiveData<ConnectionState> = _connectionState
    
    init {
        // Observe connection state
        viewModelScope.launch {
            client.connectionState.collect { state ->
                _connectionState.value = state
            }
        }
        
        // Subscribe to messages
        viewModelScope.launch {
            channel.subscribe { message ->
                val currentMessages = _messages.value ?: emptyList()
                _messages.value = currentMessages + message
            }
        }
    }
    
    fun sendMessage(text: String) {
        viewModelScope.launch {
            try {
                channel.publish(text)
            } catch (e: OddSocketsException) {
                // Handle error
                Log.e("ChatViewModel", "Failed to send message", e)
            }
        }
    }
    
    override fun onCleared() {
        super.onCleared()
        client.close()
    }
}

Dagger Hilt Integration

kotlin
@Module
@InstallIn(SingletonComponent::class)
object OddSocketsModule {
    
    @Provides
    @Singleton
    fun provideOddSocketsClient(): OddSocketsClient {
        return OddSocketsClient(
            OddSocketsConfig.default("ak_live_1234567890abcdef")
        )
    }
}

@HiltViewModel
class ChatViewModel @Inject constructor(
    private val oddSocketsClient: OddSocketsClient
) : ViewModel() {
    
    private val channel = oddSocketsClient.channel("chat")
    
    val messages = channel.messageFlow
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5000),
            initialValue = emptyList()
        )
    
    fun sendMessage(text: String) {
        viewModelScope.launch {
            channel.publish(text)
        }
    }
}

Room Database Integration

kotlin
@Entity(tableName = "messages")
data class MessageEntity(
    @PrimaryKey val id: String,
    val channel: String,
    val content: String,
    val timestamp: Long,
    val userId: String
)

@Dao
interface MessageDao {
    @Query("SELECT * FROM messages WHERE channel = :channel ORDER BY timestamp ASC")
    fun getMessagesForChannel(channel: String): Flow<List<MessageEntity>>
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertMessage(message: MessageEntity)
}

class ChatRepository @Inject constructor(
    private val messageDao: MessageDao,
    private val oddSocketsClient: OddSocketsClient
) {
    
    fun getMessages(channelName: String): Flow<List<MessageEntity>> {
        return messageDao.getMessagesForChannel(channelName)
    }
    
    suspend fun subscribeToChannel(channelName: String) {
        val channel = oddSocketsClient.channel(channelName)
        
        channel.subscribe { message ->
            // Store message in local database
            val entity = MessageEntity(
                id = message.id,
                channel = channelName,
                content = message.message.toString(),
                timestamp = message.timestamp.toEpochMilli(),
                userId = message.userId
            )
            messageDao.insertMessage(entity)
        }
    }
    
    suspend fun sendMessage(channelName: String, content: String) {
        oddSocketsClient.channel(channelName).publish(content)
    }
}