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() 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 { val msg = gson.fromJson(text, ImMessage::class.java) if (msg.chatType == "GROUP") { listeners.forEach { it.onGroupMessage(msg) } } else { listeners.forEach { it.onMessage(msg) } } }.onFailure { e -> 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) { val payload = mapOf( "appId" to appId, "toId" to toId, "chatType" to chatType, "msgType" to msgType, "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 } }