diff --git a/README.md b/README.md
index c54060c..9cf3d44 100644
--- a/README.md
+++ b/README.md
@@ -148,7 +148,7 @@ val service = RetrofitFactory.create(MyApiService::class.java)
- 会话置顶/免打扰/已读/草稿/删除同步服务端
- IM 连接状态提示
- SDK 登录态恢复后自动重连
-- IM token 自动续签,过期前会静默刷新并重连
+- IM 登录态更新后自动重连,不在 SDK 侧做静默续签
- 群聊支持 `@userId` 提及,并写入 `mentionedUserIds`
- 关系链支持好友申请、接受/拒绝、黑名单
- 支持图片 / 视频 / 音频 / 文件消息,文件通过独立文件服务上传后再发 IM
diff --git a/TEST_REPORT.md b/TEST_REPORT.md
index cf55eb9..53b0150 100644
--- a/TEST_REPORT.md
+++ b/TEST_REPORT.md
@@ -41,7 +41,7 @@
| 字段 | 内容 |
|------|------|
| **测试目的** | 验证 UserSig 鉴权模式下的登录与登出 |
-| **测试步骤** | 1. 调用 `XuqmSDK.login(userId, userSig, nickname, avatar, userSigExpiresAt)`
2. 观察 `ImSDK.onSdkLogin` 是否自动触发 WebSocket 连接
3. 监听 `ImEventListener.onConnected()`
4. 调用 `XuqmSDK.logout()`
5. 确认 `ImSDK.onSdkLogout` 断开 WebSocket 并清空 Token |
+| **测试步骤** | 1. 调用 `XuqmSDK.login(userId, userSig)`
2. 观察 `ImSDK.onSdkLogin` 是否自动触发 WebSocket 连接
3. 监听 `ImEventListener.onConnected()`
4. 调用 `XuqmSDK.logout()`
5. 确认 `ImSDK.onSdkLogout` 断开 WebSocket 并清空 Token |
| **预期结果** | 1. 登录返回 `XuqmLoginSession`
2. WebSocket 建立 101 连接并 STOMP CONNECTED
3. `onConnected()` 回调触发
4. 登出后 `connectionState` 变为 `Disconnected`
5. `TokenStore` 被清空 |
| **实际结果** | 通过 |
| **通过状态** | ✅ |
@@ -108,13 +108,13 @@
---
-### TC-08 UserSig 续签测试(新增)
+### TC-08 UserSig 登录态更新测试(新增)
| 字段 | 内容 |
|------|------|
-| **测试目的** | 验证 UserSig 即将过期时的静默续签回调机制 |
-| **测试步骤** | 1. 登录时传入 `userSigExpiresAt`(如当前时间 + 6 分钟)
2. 设置 `XuqmSDK.setUserSigRefreshListener { ... }`
3. 等待 1 分钟后观察 `UserSigRefresher` 检查逻辑
4. 在回调中获取新 UserSig 并重新调用 `XuqmSDK.login()`
5. 验证旧定时器被停止,新定时器启动 |
-| **预期结果** | 1. `UserSigRefresher.start(expiryTimeMs)` 启动
2. 到期前 5 分钟触发 `onUserSigRefreshRequired()`
3. 回调在主线程执行
4. 重新登录后 WebSocket 使用新 Token 连接
5. 无内存泄漏,定时器正确替换 |
+| **测试目的** | 验证业务侧重新签发登录态后,SDK 能覆盖旧会话并重连 |
+| **测试步骤** | 1. 登录后保持 WebSocket 连接
2. 业务服务端重新签发新的 UserSig
3. 重新调用 `XuqmSDK.login()`
4. 观察 `ImSDK.onSdkLogin` 与 `ImEventListener.onConnected()`
5. 确认旧会话被替换 |
+| **预期结果** | 1. 新登录态生效
2. WebSocket 使用新登录态重连
3. 不存在 SDK 侧定时续签逻辑
4. 旧会话被覆盖
5. 无内存泄漏 |
| **实际结果** | 待测试 |
| **通过状态** | ⬜ |
@@ -143,5 +143,5 @@
| TC-05 | 会话列表/置顶/静音测试 | ⬜ 待测试 |
| TC-06 | Push 设备注册测试 | ⬜ 待测试 |
| TC-07 | 版本更新检查测试 | ⬜ 待测试 |
-| TC-08 | UserSig 续签测试 | ⬜ 待测试 |
+| TC-08 | UserSig 登录态更新测试 | ⬜ 待测试 |
| TC-09 | 多厂商 Push 检测测试 | ⬜ 待测试 |
diff --git a/sample-app/src/main/java/com/xuqm/sdk/sample/data/api/DemoApi.kt b/sample-app/src/main/java/com/xuqm/sdk/sample/data/api/DemoApi.kt
index ef19960..6d66280 100644
--- a/sample-app/src/main/java/com/xuqm/sdk/sample/data/api/DemoApi.kt
+++ b/sample-app/src/main/java/com/xuqm/sdk/sample/data/api/DemoApi.kt
@@ -6,7 +6,6 @@ import okhttp3.logging.HttpLoggingInterceptor
import com.xuqm.sdk.sample.BuildConfig
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
-import com.google.gson.annotations.SerializedName
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
@@ -38,19 +37,10 @@ data class AuthProfile(
data class AuthResult(
val demoToken: String,
- val demoTokenExpiresAt: Long? = null,
- @SerializedName(value = "imToken", alternate = ["userSig"])
- val userSig: String? = null,
- val imTokenExpiresAt: Long? = null,
+ val imToken: String,
val profile: AuthProfile,
)
-data class ImRefreshResult(
- @SerializedName(value = "imToken", alternate = ["userSig"])
- val userSig: String,
- val imTokenExpiresAt: Long? = null,
-)
-
data class UserData(
val userId: String,
val nickname: String,
@@ -74,9 +64,6 @@ interface DemoApi {
@POST("api/demo/auth/register")
suspend fun register(@Body request: RegisterRequest): DemoResponse
- @POST("api/demo/auth/refresh-im")
- suspend fun refreshImToken(@Query("appId") appId: String = DEMO_APP_ID): DemoResponse
-
@POST("api/demo/auth/reset-password")
suspend fun resetPassword(@Body request: ResetPasswordRequest): DemoResponse
diff --git a/sample-app/src/main/java/com/xuqm/sdk/sample/data/repo/AuthRepository.kt b/sample-app/src/main/java/com/xuqm/sdk/sample/data/repo/AuthRepository.kt
index 75580fb..9fea73c 100644
--- a/sample-app/src/main/java/com/xuqm/sdk/sample/data/repo/AuthRepository.kt
+++ b/sample-app/src/main/java/com/xuqm/sdk/sample/data/repo/AuthRepository.kt
@@ -5,7 +5,6 @@ import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import com.xuqm.sdk.XuqmSDK
import com.xuqm.sdk.sample.data.api.AuthResult
-import com.xuqm.sdk.sample.data.api.ImRefreshResult
import com.xuqm.sdk.sample.data.api.ChangePasswordRequest
import com.xuqm.sdk.sample.data.api.DEMO_APP_ID
import com.xuqm.sdk.sample.data.api.DemoApi
@@ -55,22 +54,19 @@ class AuthRepository(context: Context) {
val demoToken = getDemoToken().orEmpty()
val userId = getCurrentUserId().orEmpty()
val userSig = getCurrentUserSig().orEmpty()
- val demoTokenExpiresAt = prefs.getLong("demo_token_expires_at", 0L)
return demoToken.isNotBlank() &&
userId.isNotBlank() &&
- userSig.isNotBlank() &&
- demoTokenExpiresAt > System.currentTimeMillis()
+ userSig.isNotBlank()
}
private fun saveSession(result: AuthResult) {
val profile = result.profile
prefs.edit()
.putString("demo_token", result.demoToken)
- .putLong("demo_token_expires_at", result.demoTokenExpiresAt ?: 0L)
.putString("user_id", profile.userId)
.putString("nickname", profile.nickname)
.putString("avatar", profile.avatar)
- .putString("user_sig", result.userSig)
+ .putString("user_sig", result.imToken)
.apply()
}
@@ -80,7 +76,7 @@ class AuthRepository(context: Context) {
val res = api.login(LoginRequest(DEMO_APP_ID, userId, password))
val data = requireNotNull(res.data) { res.message ?: "Login failed" }
saveSession(data)
- val userSig = requireNotNull(data.userSig?.takeIf { it.isNotBlank() }) {
+ val userSig = requireNotNull(data.imToken.takeIf { it.isNotBlank() }) {
"Login succeeded but IM credential is missing"
}
XuqmSDK.login(
@@ -98,7 +94,7 @@ class AuthRepository(context: Context) {
val res = api.register(RegisterRequest(DEMO_APP_ID, userId, password, nickname))
val data = requireNotNull(res.data) { res.message ?: "Register failed" }
saveSession(data)
- val userSig = requireNotNull(data.userSig?.takeIf { it.isNotBlank() }) {
+ val userSig = requireNotNull(data.imToken.takeIf { it.isNotBlank() }) {
"Register succeeded but IM credential is missing"
}
XuqmSDK.login(