XuqmGroup-AndroidSDK/sdk-im/src/main/java/com/xuqm/sdk/im/ImSDK.kt
XuqmGroup 5a0378d579 feat(sdk): 实现动态服务端点配置和环境切换功能
- 移除硬编码的基础URL常量,改为可配置的服务端点
- 添加ServiceEndpointRegistry用于统一管理所有服务端点地址
- 实现ApiClient支持多基础URL的Retrofit实例缓存机制
- 新增XuqmSDK.configureServiceEndpoints等方法用于运行时切换环境
- 为sample-app添加SampleEnvironmentConfig支持本地联调环境切换
- 创建独立的IM、Push、Update SDK模块并集成服务端点配置
- 更新文档说明如何进行联调环境切换操作
2026-04-27 19:30:06 +08:00

147 行
5.4 KiB
Kotlin

package com.xuqm.sdk.im
import com.xuqm.sdk.XuqmLoginSession
import com.xuqm.sdk.XuqmSDK
import com.xuqm.sdk.core.ServiceEndpointRegistry
import com.xuqm.sdk.im.api.AddMemberRequest
import com.xuqm.sdk.im.api.CreateGroupRequest
import com.xuqm.sdk.im.api.ImApi
import com.xuqm.sdk.im.api.SetMutedRequest
import com.xuqm.sdk.im.api.SetPinnedRequest
import com.xuqm.sdk.im.api.UpdateGroupRequest
import com.xuqm.sdk.im.listener.ImEventListener
import com.xuqm.sdk.im.model.ConversationData
import com.xuqm.sdk.im.model.ImGroup
import com.xuqm.sdk.im.model.ImMessage
import com.xuqm.sdk.network.ApiClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
object ImSDK {
private var client: ImClient? = null
private val api: ImApi get() = ApiClient.create(ImApi::class.java, ServiceEndpointRegistry.imApiBaseUrl)
var currentUserId: String = ""
private set
init {
XuqmSDK.currentLoginSession?.let { onSdkLogin(it) }
}
suspend fun login(
userId: String,
userSig: String,
nickname: String? = null,
avatar: String? = null,
) = withContext(Dispatchers.IO) {
XuqmSDK.requireInit()
currentUserId = userId
connectWithToken(userSig)
}
suspend fun loginWithUserSig(userId: String, userSig: String) =
withContext(Dispatchers.IO) {
XuqmSDK.requireInit()
currentUserId = userId
connectWithToken(userSig)
}
@Deprecated("Use loginWithUserSig(userId, userSig) instead.")
suspend fun loginWithToken(userId: String, token: String) =
loginWithUserSig(userId, token)
fun sendMessage(toId: String, chatType: String, msgType: String, content: String) {
client?.sendMessage(toId, chatType, msgType, content)
}
suspend fun fetchHistory(toId: String, page: Int = 0, size: Int = 20): List<ImMessage> =
withContext(Dispatchers.IO) {
api.fetchHistory(toId, XuqmSDK.appId, page, size).data ?: emptyList()
}
suspend fun fetchGroupHistory(groupId: String, page: Int = 0, size: Int = 20): List<ImMessage> =
withContext(Dispatchers.IO) {
api.fetchGroupHistory(groupId, XuqmSDK.appId, page, size).data ?: emptyList()
}
suspend fun listGroups(): List<ImGroup> =
withContext(Dispatchers.IO) { api.listGroups(XuqmSDK.appId).data ?: emptyList() }
suspend fun createGroup(name: String, memberIds: List<String>): ImGroup? =
withContext(Dispatchers.IO) { api.createGroup(XuqmSDK.appId, CreateGroupRequest(name, memberIds)).data }
suspend fun getGroupInfo(groupId: String): ImGroup? =
withContext(Dispatchers.IO) { api.getGroupInfo(groupId).data }
suspend fun updateGroupInfo(groupId: String, name: String? = null, announcement: String? = null) =
withContext(Dispatchers.IO) { api.updateGroupInfo(groupId, UpdateGroupRequest(name, announcement)) }
suspend fun addGroupMember(groupId: String, userId: String) =
withContext(Dispatchers.IO) { api.addGroupMember(groupId, AddMemberRequest(userId)) }
suspend fun removeGroupMember(groupId: String, userId: String) =
withContext(Dispatchers.IO) { api.removeGroupMember(groupId, userId) }
suspend fun leaveGroup(groupId: String) =
withContext(Dispatchers.IO) { api.removeGroupMember(groupId, currentUserId) }
suspend fun listFriends(): List<String> =
withContext(Dispatchers.IO) { api.listFriends(XuqmSDK.appId).data ?: emptyList() }
suspend fun addFriend(friendId: String) =
withContext(Dispatchers.IO) { api.addFriend(XuqmSDK.appId, friendId) }
suspend fun removeFriend(friendId: String) =
withContext(Dispatchers.IO) { api.removeFriend(friendId, XuqmSDK.appId) }
suspend fun listConversations(): List<ConversationData> =
withContext(Dispatchers.IO) { api.listConversations(XuqmSDK.appId).data ?: emptyList() }
suspend fun setConversationPinned(targetId: String, chatType: String, pinned: Boolean) =
withContext(Dispatchers.IO) {
api.setConversationPinned(targetId, chatType, SetPinnedRequest(pinned))
}
suspend fun setConversationMuted(targetId: String, chatType: String, muted: Boolean) =
withContext(Dispatchers.IO) {
api.setConversationMuted(targetId, chatType, SetMutedRequest(muted))
}
suspend fun markRead(targetId: String, chatType: String = "SINGLE") =
withContext(Dispatchers.IO) { api.markRead(targetId, XuqmSDK.appId, chatType) }
fun addListener(listener: ImEventListener) = client?.addListener(listener)
fun removeListener(listener: ImEventListener) = client?.removeListener(listener)
fun disconnect() {
disconnectInternal(clearTokenStore = true)
}
fun onSdkLogin(session: XuqmLoginSession) {
XuqmSDK.requireInit()
currentUserId = session.userId
connectWithToken(session.userSig)
}
fun onSdkLogout() {
disconnectInternal(clearTokenStore = false)
}
private fun connectWithToken(token: String) {
XuqmSDK.tokenStore.saveToken(token)
client?.disconnect()
client = ImClient(ServiceEndpointRegistry.imWsUrl, token, XuqmSDK.appId)
client?.connect()
}
private fun disconnectInternal(clearTokenStore: Boolean) {
client?.disconnect()
client = null
currentUserId = ""
if (clearTokenStore) {
XuqmSDK.tokenStore.clear()
}
}
}