默认
发表评论 20
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?别走弯路了... 找站长给点建议
[已回复] 求教MobileIMSDK客户端退出登录后,再次登录无效
退出登录的时候,我用了LocalDataSender.getInstance().sendLoginout()和IMClientManager.getInstance(com.van.course.mbase.app.AppInfo.getApplication())
    .resetInitFlag();再次登录的时候,重新调用IMClientManager.getInstance(app).initMobileIMSDK(),也收不到登录回调,再次登录日志是,“登陆/连接信息已成功发出!”,收不到后续Login OK的回调

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:[已回复] 如何从MobileIMSDK中的Protocal对象获取与dataContent同级参数下一篇:[已回复] 求教MobileIMSDK h5端vite中掉线频繁是什么原因

本帖已收录至以下技术专辑

推荐方案
评论 20
你仔细读一下这个贴子里我的回复:《[已解决] 求助MobileIMSDK 退出登录再重新登录后出现203错误
引用:JackJiang 发表于 2026-01-27 19:22
你仔细读一下这个贴子里我的回复:《[已解决] 求助MobileIMSDK 退出登录再重新登录后出现203错误》

这些都加了,目前也不是报203错误,就是单纯的收不到登录回调状态,,显示IMCORE-TCP】收到服务端的“尚未登陆”的错误消息,心跳线程将停止,请应用层重新登陆.,收不到后续的“           IMClientManager.getInstance(app).getChatBaseListener()
                .setLoginOkForLaunchObserver(onLoginSuccessObserver)”,        private fun ensureLoginSuccessObserver() {
            if (onLoginSuccessObserver != null) return
            onLoginSuccessObserver = Observer { _, data ->
                val code = data as? Int
                if (code == null) {
                    Log.w(TAG, "Login observer received non-int data: $data")
                    return@Observer
                }
                if (code == 0) {
                    //** 提示:登陆/连接 MobileIMSDK服务器成功后的事情在此实现即可
                    Log.d(TAG, "Login OK")
                } else {
                    Log.w(TAG, "Login failed, code=$code")
                }
            }
        }
引用:JackJiang 发表于 2026-01-27 19:22
你仔细读一下这个贴子里我的回复:《[已解决] 求助MobileIMSDK 退出登录再重新登录后出现203错误》

我是退出登录用的是
        @JvmStatic
        fun doLogout() {
            // 发出退出登陆请求包(Android系统要求必须要在独立的线程中发送哦)
            object : MBAsyncTask() {
                override fun doInBackground(vararg params: Any?): Int {
                    var code = -1
                    try {
                        code = LocalDataSender.getInstance().sendLoginout()
                    } catch (e: Exception) {
                        Log.w(TAG, e)
                    }

                    //## BUG FIX: 20170713 START by JackJiang
                    // 退出登陆时记得一定要调用此行,不然不退出APP的情况下再登陆时会报 code=203错误哦!
                    IMClientManager.getInstance(AppInfo.getApplication())
                        .resetInitFlag();

                    hasInited = false
                    //## BUG FIX: 20170713 END by JackJiang
                    return code
                }

                override fun onPostExecute(code: Int) {
                    if (code == 0) {
                        Log.d(
                            TAG,
                            "注销登陆请求已完成!"
                        )
                    } else {
                        Log.d(TAG, "注销登陆请求发送失败。错误码是:" + code + "!")
                    }
                }
            }.execute()
        },然后登录的时候用的                   // 设置 IM 用户信息
                            MobileIMInfo.init(AppInfo.getApplication()),都是application层面
引用:nidexingshi 发表于 2026-01-27 21:20
我是退出登录用的是
        @JvmStatic
        fun doLogout() {

我退出登录是跳转到什么界面?是跳转到登录界面吗?

另外,你用原版的官方demo工程,这些回调都能正常执行吗?你自已可以比照一下,到底是为什么没有被回调?
引用:JackJiang 发表于 2026-01-27 21:41
我退出登录是跳转到什么界面?是跳转到登录界面吗?

另外,你用原版的官方demo工程,这些回调都能正常 ...

对,跳转到了登录页面,demo感觉不完善,都是Activity中执行的,不是Application,而且,每次启动都是进入登录页面,正常软件都是首页判断登录态看跳转主页还是登录,退出登录直接跳转登录页,目前主要问题是切换账户或者退出登录是不会退出app的,只是跳转登录,然后光靠,                  try {
                        code = LocalDataSender.getInstance().sendLoginout()
                    } catch (e: Exception) {
                        Log.w(TAG, e)
                    }

                    //## BUG FIX: 20170713 START by JackJiang
                    // 退出登陆时记得一定要调用此行,不然不退出APP的情况下再登陆时会报 code=203错误哦!
                    IMClientManager.getInstance(AppInfo.getApplication())
                        .resetInitFlag();,这个代码,退出不完全,登录后再调用                IMClientManager.getInstance(app).initMobileIMSDK(),两个线程会自己挂掉,收不到回调
引用:JackJiang 发表于 2026-01-27 21:41
我退出登录是跳转到什么界面?是跳转到登录界面吗?

另外,你用原版的官方demo工程,这些回调都能正常 ...

我目前临时做法是定时检测KeepAliveDaemon在不在,然后再            ClientCoreSDK.getInstance()
                            .setCurrentLoginInfo(PLoginInfo(userId, token))
                        KeepAliveDaemon.getInstance().start(true),但不是正统做法
引用:nidexingshi 发表于 2026-01-28 10:29
我目前临时做法是定时检测KeepAliveDaemon在不在,然后再            ClientCoreSDK.getInstance()
     ...

我还是不太理解你为什么会出现这样的问题:按你的描述,你是第一次登录时回调都正常,但退出登录后,再次登录时确收不到回调,是这样吗?

如果是这样的话:你这个退出登录,是退出整个APP呢,还是只是退出到登录界面(app的生命周期并没有结束)?
引用:nidexingshi 发表于 2026-01-28 10:27
对,跳转到了登录页面,demo感觉不完善,都是Activity中执行的,不是Application,而且,每次启动都是进入 ...

我没有明白你说的两个线程会自已挂掉,指的是什么线程挂掉?

这个退出登录逻辑,你可以安装 RainbowChat ,看看它的表现是否符合你的预期?然后对照参考一下。
引用:JackJiang 发表于 2026-01-28 10:49
我没有明白你说的两个线程会自已挂掉,指的是什么线程挂掉?

这个退出登录逻辑,你可以安装 RainbowCh ...

只是退出到登录页面,不是退出整个app,线程是指的是AutoReLoginDaemon和KeepAliveDaemon,这两个
引用:nidexingshi 发表于 2026-01-28 11:13
只是退出到登录页面,不是退出整个app,线程是指的是AutoReLoginDaemon和KeepAliveDaemon,这两个

你退出登录了,这两个线程肯定就停止了,直到下次重新登陆成功才会启动
引用:JackJiang 发表于 2026-01-28 12:28
你退出登录了,这两个线程肯定就停止了,直到下次重新登陆成功才会启动

退出登录后,再次登录,然后 IMClientManager.getInstance(app).initMobileIMSDK(),sdk只会有,服务端也没连上,然后两个线程都停止了
引用:JackJiang 发表于 2026-01-28 12:28
你退出登录了,这两个线程肯定就停止了,直到下次重新登陆成功才会启动


【IMCORE-TCP】发送登陆指令时,socket连接未就绪,首先开始尝试发起连接(登陆指令将在连接成功后的回调中自动发出)。。。。
【IMCORE-TCP】tryConnectToHost并获取connection开始了...
【IMCORE-TCP】tryConnectToHost并获取connectio已完成。 .... continue ...
【IMCORE-tryConnectToHost-异步回调】Connection established successfully
【IMCORE-TCP】isLocalSocketReady()==true,直接返回本地socket引用哦。
[IMCORE-netty-send异步回调] >> 数据已成功发出[dataLen=416].
【IMCORE-netty-channelActive】连接已成功建立!(isLocalSocketReady=true)
【IMCORE-TCP】【本地网络通知】检测本地网络已连接上了!
【IMCORE-TCP】channel优雅退出开始。。。
【IMCORE-TCP】channel优雅退出结束。
【IMCORE-netty-channelInactive】连接已断开。。。。(isLocalSocketReady=false, ClientCoreSDK.connectedToServer=false)
登陆/连接信息已成功发出!
引用:nidexingshi 发表于 2026-01-28 14:19
退出登录后,再次登录,然后 IMClientManager.getInstance(app).initMobileIMSDK(),sdk只会有,服务端也 ...

你参考 RainbowChat里的实现,在跳转到登录界面的intent之前就调用initMobileIMSDK:
        /**
         * 打开LoginActivity的Intent构造方法. 此方法通常用于无法普通地打开登陆界面的场景.
         * 
         * @param thisActivity
         * @return
         */
        public static Intent createLoginIntent(Context thisActivity)
        {
                // init MobileIMSDK first(必须保证此代码被调用,否则IM框架无法完成IM服务器的连接等工作)
                // 通常在打开登陆界面调用此方法,是合理的,因为它下一步就是登陆im框架啊
            MyApplication.getInstance(thisActivity).getIMClientManager().initMobileIMSDK();
            
                Intent intent = new Intent(thisActivity, LoginActivity.class);
                return intent;
        }
引用:JackJiang 发表于 2026-01-28 15:51
你参考 RainbowChat里的实现,在跳转到登录界面的intent之前就调用initMobileIMSDK:
[mw_shl_code=java ...

退出登录后,立马SDK重置,和SDK初始化,会不会冲突?
引用:nidexingshi 发表于 2026-01-28 17:05
退出登录后,立马SDK重置,和SDK初始化,会不会冲突?

不会冲突,但你再次初始化的时候必须在跳转登录界面之前去调用,参考14楼的代码逻辑
引用:JackJiang 发表于 2026-01-28 17:25
不会冲突,但你再次初始化的时候必须在跳转登录界面之前去调用,参考14楼的代码逻辑

这个可以,就是必须等SDK重置完全结束才行,还得等异步线程结束,我目前是这样搞得,  // 使用 Kotlin 协程进行异步操作
            CoroutineScope(Dispatchers.IO).launch {
                var code = -1
                try {
                    code = LocalDataSender.getInstance().sendLoginout()
                } catch (e: Exception) {
                    Log.w(TAG, e)
                }

                //## BUG FIX: 20170713 START by JackJiang
                // 退出登陆时记得一定要调用此行,不然不退出APP的情况下再登陆时会报 code=203错误哦!
                IMClientManager.getInstance(AppInfo.getApplication())
                    .resetInitFlag()

                hasInited = false

                // 切换回主线程处理结果并重新初始化
                withContext(Dispatchers.Main) {
                    if (code == 0) {
                        Log.d(TAG, "注销登陆请求已完成!")
                    } else {
                        Log.d(TAG, "注销登陆请求发送失败。错误码是:$code!")
                    }
                    // 确保异步操作完成后重新初始化
                    init(AppInfo.getApplication())
                }
            }
引用:JackJiang 发表于 2026-01-28 17:25
不会冲突,但你再次初始化的时候必须在跳转登录界面之前去调用,参考14楼的代码逻辑

大佬,再帮忙看看,目前我是定时检测来保活,这样可以不,    // 定期检查IM连接变化(每10秒检查一次,防止im挂了)
    LaunchedEffect(Unit) {
        while (true) {
            kotlinx.coroutines.delay(10 * 1000) // 10秒
            val isKeepAliveRunning = KeepAliveDaemon.getInstance().isKeepAliveRunning;
            val isLocalSocketReady = LocalSocketProvider.getInstance().isLocalSocketReady
            Log.d(
                "StudyScreen", "isKeepAliveRunning=$isKeepAliveRunning"
            )
            Log.d(
                "StudyScreen", "isLocalSocketReady=$isLocalSocketReady"
            )

            if (MLoginCache.instance()
                    .getToken() != null && !isLocalSocketReady && !isKeepAliveRunning
            ) {
                //Socket连接失效表示保活线程不在的时候,需要启动保活线程
                if (ClientCoreSDK.getInstance().getCurrentLoginInfo() == null) {
                    val userId = LoginUtils.getStudentNumber()
                    val token = MLoginCache.instance().token
                    if (!userId.isNullOrBlank() && !token.isNullOrBlank()) {
                        ClientCoreSDK.getInstance()
                            .setCurrentLoginInfo(PLoginInfo(userId, token))
                        KeepAliveDaemon.getInstance().start(true)
                    }
                } else {
                    KeepAliveDaemon.getInstance().start(true)
                }

            }
        }
    }
引用:JackJiang 发表于 2026-01-28 17:25
不会冲突,但你再次初始化的时候必须在跳转登录界面之前去调用,参考14楼的代码逻辑

大佬,还有个稳定性问题,我发现,时间长了,IM会链接不上,报错-1,不知道跟我这个定时检测保活有没有关系,我等到第二天,然后掉了就一直连不上
引用:JackJiang 发表于 2026-01-28 17:25
不会冲突,但你再次初始化的时候必须在跳转登录界面之前去调用,参考14楼的代码逻辑

【IMCORE-TCP】心跳机制已判定网络断开,将进入断网通知和重连处理逻辑 ...
2026-01-29 14:58:47.481  9976-9976  VAN.ChatBaseEventImpl   com.van.course                       E  【DEBUG_UI】与IM服务器的网络连接出错关闭了,error:-1
【IMCORE-TCP】自动重新登陆线程执行中, autoReLogin?true...

时间长了,会触发链接不上的问题,一直报这个
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部