XuqmGroup-AndroidSDK/sdk-im/src/main/java/com/xuqm/sdk/im/ImClient.kt

82 行
2.8 KiB
Kotlin

2026-04-21 22:07:29 +08:00
package com.xuqm.sdk.im
import com.google.gson.Gson
import com.xuqm.sdk.im.listener.ImEventListener
import com.xuqm.sdk.im.model.ImMessage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit
class ImClient(
private val wsUrl: String,
private val token: String,
private val appId: String,
) {
private var webSocket: WebSocket? = null
private val listeners = CopyOnWriteArrayList<ImEventListener>()
private val scope = CoroutineScope(Dispatchers.IO + Job())
private val gson = Gson()
private val okhttp = OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(0, TimeUnit.SECONDS)
.build()
fun connect() {
val request = Request.Builder()
.url(wsUrl)
.header("Authorization", "Bearer $token")
.build()
webSocket = okhttp.newWebSocket(request, object : WebSocketListener() {
override fun onOpen(ws: WebSocket, response: Response) {
listeners.forEach { it.onConnected() }
}
override fun onMessage(ws: WebSocket, text: String) {
runCatching {
2026-04-21 22:07:29 +08:00
val msg = gson.fromJson(text, ImMessage::class.java)
if (msg.chatType == "GROUP") {
2026-04-21 22:07:29 +08:00
listeners.forEach { it.onGroupMessage(msg) }
} else {
listeners.forEach { it.onMessage(msg) }
}
}.onFailure { e ->
2026-04-21 22:07:29 +08:00
listeners.forEach { it.onError("Parse error: ${e.message}") }
}
}
override fun onFailure(ws: WebSocket, t: Throwable, response: Response?) {
listeners.forEach { it.onDisconnected(t.message) }
}
override fun onClosed(ws: WebSocket, code: Int, reason: String) {
listeners.forEach { it.onDisconnected(reason) }
}
})
}
fun sendMessage(toId: String, chatType: String, msgType: String, content: String) {
2026-04-21 22:07:29 +08:00
val payload = mapOf(
"appId" to appId, "toId" to toId,
"chatType" to chatType, "msgType" to msgType,
2026-04-21 22:07:29 +08:00
"content" to content,
)
webSocket?.send(gson.toJson(mapOf("type" to "chat.send", "data" to payload)))
}
fun addListener(listener: ImEventListener) = listeners.add(listener)
fun removeListener(listener: ImEventListener) = listeners.remove(listener)
fun disconnect() {
webSocket?.close(1000, "User disconnect")
webSocket = null
}
}