Real-world examples showing how to use the OddSockets Kotlin SDK in Android applications and JVM environments
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!")
}
@Composable
fun ChatScreen(viewModel: ChatViewModel) {
val messages by viewModel.messages.collectAsState()
val connectionState by viewModel.connectionState.collectAsState()
Column {
// Connection status
ConnectionStatusBar(connectionState)
// Messages list
LazyColumn(modifier = Modifier.weight(1f)) {
items(messages) { message ->
MessageItem(message = message)
}
}
// Input field
MessageInput { text ->
viewModel.sendMessage(text)
}
}
}
class MessageProcessor(private val client: OddSocketsClient) {
fun processHighPriorityMessages() = flow {
client.channel("notifications")
.messageFlow
.filter { it.metadata?.get("priority") == "high" }
.map { it.message.toString() }
.collect { message ->
emit(processUrgentMessage(message))
}
}
fun monitorConnectionHealth() =
client.connectionState
.distinctUntilChanged()
.onEach { state ->
when (state) {
ConnectionState.CONNECTED -> logInfo("Connected")
ConnectionState.RECONNECTING -> logWarning("Reconnecting...")
ConnectionState.FAILED -> logError("Connection failed")
}
}
}
class ChatViewModel @Inject constructor(
private val oddSocketsClient: OddSocketsClient
) : ViewModel() {
private val channel = oddSocketsClient.channel("chat")
private val _messages = MutableLiveData<List<Message>>()
val messages: LiveData<List<Message>> = _messages
init {
viewModelScope.launch {
channel.subscribe { message ->
val current = _messages.value ?: emptyList()
_messages.value = current + message
}
}
}
fun sendMessage(text: String) {
viewModelScope.launch {
channel.publish(text)
}
}
}
@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() {
val messages = oddSocketsClient.channel("chat")
.messageFlow
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
}
@Entity(tableName = "messages")
data class MessageEntity(
@PrimaryKey val id: String,
val channel: String,
val content: String,
val timestamp: Long,
val userId: String
)
class ChatRepository @Inject constructor(
private val messageDao: MessageDao,
private val oddSocketsClient: OddSocketsClient
) {
suspend fun subscribeToChannel(channelName: String) {
val channel = oddSocketsClient.channel(channelName)
channel.subscribe { message ->
// Store in local database
messageDao.insertMessage(
MessageEntity(
id = message.id,
channel = channelName,
content = message.message.toString(),
timestamp = message.timestamp.toEpochMilli(),
userId = message.userId
)
)
}
}
}
@RestController
class NotificationController(
private val oddSocketsClient: OddSocketsClient
) {
@PostMapping("/notify")
suspend fun sendNotification(@RequestBody notification: Notification) {
val channel = oddSocketsClient.channel("notifications")
channel.publish(notification) {
metadata = mapOf(
"priority" to notification.priority,
"timestamp" to System.currentTimeMillis()
)
storeInHistory = true
}
return ResponseEntity.ok("Notification sent")
}
}
// commonMain
expect class PlatformOddSocketsClient {
fun createClient(apiKey: String): OddSocketsClient
}
class SharedChatRepository {
private val client = PlatformOddSocketsClient()
.createClient("ak_live_1234567890abcdef")
fun subscribeToChat(channelName: String): Flow<Message> {
return client.channel(channelName).messageFlow
}
suspend fun sendMessage(channelName: String, message: String) {
client.channel(channelName).publish(message)
}
}