85 行
2.9 KiB
Kotlin
85 行
2.9 KiB
Kotlin
|
|
package com.xuqm.sdk.im
|
||
|
|
|
||
|
|
import com.google.gson.Gson
|
||
|
|
import com.xuqm.sdk.im.listener.ImEventListener
|
||
|
|
import com.xuqm.sdk.im.model.ChatType
|
||
|
|
import com.xuqm.sdk.im.model.ImMessage
|
||
|
|
import com.xuqm.sdk.im.model.MsgType
|
||
|
|
import kotlinx.coroutines.CoroutineScope
|
||
|
|
import kotlinx.coroutines.Dispatchers
|
||
|
|
import kotlinx.coroutines.Job
|
||
|
|
import kotlinx.coroutines.launch
|
||
|
|
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) {
|
||
|
|
try {
|
||
|
|
val msg = gson.fromJson(text, ImMessage::class.java)
|
||
|
|
if (msg.chatType == ChatType.GROUP) {
|
||
|
|
listeners.forEach { it.onGroupMessage(msg) }
|
||
|
|
} else {
|
||
|
|
listeners.forEach { it.onMessage(msg) }
|
||
|
|
}
|
||
|
|
} catch (e: Exception) {
|
||
|
|
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: ChatType, msgType: MsgType, content: String) {
|
||
|
|
val payload = mapOf(
|
||
|
|
"appId" to appId, "toId" to toId,
|
||
|
|
"chatType" to chatType.name, "msgType" to msgType.name,
|
||
|
|
"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
|
||
|
|
}
|
||
|
|
}
|