请选择 进入手机版 | 继续访问电脑版

默认
发表评论 16
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
[已回复] 求助我Android端切换账号代码可能用的不对,导致间隔45秒会断开重连
多台设备连接,其中一台连接及其不稳定,间隔三四十秒重连一次,网络环境相同。ping 结果也相近。直接导入的github 这个月最新的SDK。
QQ图片20200923114325.png ----------------------------------------------------------
1.128 这一台:坚果 R1 android 8.1.0
1.17   这一台:OPPO R15 android 9
微信截图_20200923114516.png


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

标签:MobileIMSDK
上一篇:[已解决] 求助MobileIMSDK安卓消息过长导致无法收到的问题下一篇:[已回复] 求java springboot+MobileIMSDK的案例,可有偿
推荐方案
评论 16
按照你的Log显示,每隔45秒断一次,这一定是另有原因。

检查一下:这台手机的登陆ID,是否有别的手机有用同样的ID,也就是看看是否存在同一个ID重复登际的情况。
签名: 《零基础IM开发入门(三):什么是IM系统的可靠性?》http://www.52im.net/thread-3182-1-1.html
引用:JackJiang 发表于 2020-09-23 12:47
按照你的Log显示,每隔45秒断一次,这一定是另有原因。

检查一下:这台手机的登陆ID,是否有别的手机有 ...

我找到了触发条件:当我下线切换账号,重复几次就会出先这样的情况,应该是我退出登录或者登录写的有问题,麻烦站长帮我看下
引用:JackJiang 发表于 2020-09-23 12:47
按照你的Log显示,每隔45秒断一次,这一定是另有原因。

检查一下:这台手机的登陆ID,是否有别的手机有 ...

退出登录代码:
-----------------------------------------
注销登录之后初始化的代码

-----------------------------------------------------
再次登录的代码



引用:JackJiang 发表于 2020-09-23 12:47
按照你的Log显示,每隔45秒断一次,这一定是另有原因。

检查一下:这台手机的登陆ID,是否有别的手机有 ...

退出登录代码:
111111111111924091353.png -----------------------------------------
注销登录之后初始化的代码
22222222222222924091417.png
-----------------------------------------------------
再次登录的代码
333333333333391440.png


引用:暄落 发表于 2020-09-24 09:16
退出登录代码:
-----------------------------------------
注销登录之后初始化的代码

你贴的这个内容,跟你发的帖子问题,是有关联的吗?
签名: 《零基础IM开发入门(三):什么是IM系统的可靠性?》http://www.52im.net/thread-3182-1-1.html
引用:JackJiang 发表于 2020-09-24 10:45
你贴的这个内容,跟你发的帖子问题,是有关联的吗?

有一个回复提示进审核了,没有显示出来
引用:JackJiang 发表于 2020-09-24 10:45
你贴的这个内容,跟你发的帖子问题,是有关联的吗?

我断开重连,早上怀疑是退出登录-登录,多次导致的问题,结果刚刚我连接sdk中的 run.bat ,发现连接自己的没有什么问题,可能是后端同学那里的问题。现在所有连接那个地址的都是 45s 断一次。
引用:暄落 发表于 2020-09-24 10:50
我断开重连,早上怀疑是退出登录-登录,多次导致的问题,结果刚刚我连接sdk中的 run.bat ,发现连接自己 ...

这么规律,一定是其它问题。你排查过,不存在同一账号重复登陆是吧
签名: 《零基础IM开发入门(三):什么是IM系统的可靠性?》http://www.52im.net/thread-3182-1-1.html
引用:JackJiang 发表于 2020-09-24 12:27
这么规律,一定是其它问题。你排查过,不存在同一账号重复登陆是吧

是的,我在出现的时候去后端那里看了一下,不存在同一账号重复登陆的情况。
引用:暄落 发表于 2020-09-24 13:13
是的,我在出现的时候去后端那里看了一下,不存在同一账号重复登陆的情况。

你想做的是,在不退出app的情况下,实现退出当前账号,前重新登陆这样的功能逻辑是吗?

如果是,我就把RainbowChat产品中的实现,贴给你参一下。
签名: 《零基础IM开发入门(三):什么是IM系统的可靠性?》http://www.52im.net/thread-3182-1-1.html
引用:JackJiang 发表于 2020-09-24 13:26
你想做的是,在不退出app的情况下,实现退出当前账号,前重新登陆这样的功能逻辑是吗?

如果是,我就 ...

嗯嗯,我怀疑是 退出账号→登录另一账号 这样的情况导致的。上边有我的退出登录与登录逻辑,我是仿写的 SDK Demo 里面的代码实现的
引用:暄落 发表于 2020-09-24 13:29
嗯嗯,我怀疑是 退出账号→登录另一账号 这样的情况导致的。上边有我的退出登录与登录逻辑,我是仿写的 S ...

好,我来把RainbowChat中的“退出登陆”这个功能的主要实现代码,发你参一下,具体如果你不太理解功能是怎么样UI交互的,你就自已下载APP体验一下

具体的功能体验就是:RainbowChat的“退出登陆”功能在下图中,点退出登陆时,会关闭当前连接并释放im sdk这一层的资源并跳转到登陆界面。

我贴的是没有删减的代码,你不需要关注的业务内容,跳过不看就行。

下面是“退出登陆”按钮,点击时的事件处理:
                // 点击"退出登陆"
                exitBtn.setOnClickListener(new OnClickListener(){
                                @Override
                                public void onClick(View v)
                                {
                                        new AlertDialog.Builder(MoreActivity.this)
                                                        .setTitle($$(R.string.general_are_u_sure))
                                                        .setMessage($$(R.string.main_more_msg_tone_exit_to_login))
                                                        .setPositiveButton($$(R.string.general_ok),  new DialogInterface.OnClickListener(){
                                                                @Override
                                                                public void onClick(DialogInterface dialog,int which)
                                                                {
                                                                        // 退出登陆(但不退出JVM——即不通出APP进程)
                                                                        LoginActivity.doLogoutNoConfirm(MyApplication.getInstance2(), false, new Observer(){

                                                                                // 此通知将在注册与IM服务器的连接、释放IM资源、释放本APP中所有activity后被通知
                                                                                @Override
                                                                                public void update(Observable arg0, Object arg1)
                                                                                {
                                                                                        // 退出登陆时,取消"自动登陆"的开关量设置
                                                                                        PreferencesToolkits.setAutoLogin(MoreActivity.this, false);

                                                                                        // 代码执行至此,表示APP中所有的activity都已被回收(包括本MoreAcvitity),
                                                                                        // 而要再次显示登陆界面activity的话,只能借助APP全局唯一的Context——即
                                                                                        // Application实例,以下代码千万不可引用错了Context哦
                                                                                        Context ctx = MyApplication.getInstance2();

                                                                                        Intent iLogin = IntentFactory.createLoginIntent(ctx);
                                                                                        // 因Application对象并不是Activity,所以必须要加此flag,否则无法启动Activity
                                                                                        iLogin.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                                                                                        // 进入登陆activity
                                                                                        ctx.startActivity(iLogin);
                                                                                }
                                                                        });
                                                                }
                                                        })
                                                        .setNegativeButton($$(R.string.general_cancel), null)
                                                        .show();
                                }
                });

LoginActivity.doLogoutNoConfirm()方法的主要代码如下:
        /**
         * 退出APP的登陆,并释放所有资源。
         * <p>
         * 注:方法中不涉及任何GUI,用在多线程中调用也没事。
         * 
         * @param context
         * @param exitJVM true表示完成退出APP(可用于完关闭应用时),否则表
         * 示仅退出所有Activity(可用于切换到登陆界面重新登陆等场景下)
         * @param obsAfterLogoutIMServer 本观察者将在logout im server完成后,被
         * 调用,当前此参数已知的是在更多界面中的”退出登陆“时使用了。一般来说,本参数
         * 的设置只在exitJVM参数=false时才有意义,请参见源码
         */
        public static void doLogoutNoConfirm(final Context context, final boolean exitJVM
                        , final Observer obsAfterLogoutIMServer)
        {
                // TODO 退出登陆时如有其它事情要处理,可在此补充!

               // 【1】注销HTTP服务器的登陆
              。。。。。。。。
                
                // 【2】注销IM服务器连接并释放IM框架所占的所有资源
                IMClientManager.doLogoutIMServer(context
                                , new Observer(){// 为何要使用观察者?因退出登陆数据发送是在异步线程中实现的,
                                                                 // 使用观察者的目的是确保退出JVM等是在数据已发送完成后再行的哦!!!!
                        @Override
                        public void update(Observable observable, Object data) {
                                // 释放APP应用占用的资源
                                systemExit(context, exitJVM);
                                
                                // 
                                if(obsAfterLogoutIMServer != null)
                                        obsAfterLogoutIMServer.update(null, null);
                        }
                });

                // 【3】重置大文件下载管理器
               。。。。。。。
        }

IMClientManager.doLogoutIMServer()方法的实现代码:
        /**
         * 退出IM服务器连接并释放IM所占的所有资源(含退出IM框架连接、再释放IM框架所占的资源)。
         * <p>
         * 在切换账号等功能场景下,使用本方法可以保证重新登陆时IM框架
         * 已回到重初状态,从而完全正常的重新登陆。
         * 
         * @see LocalDataSender#sendLoginout()
         * @see IMClientManager#releaseMobileIMSDK()
         */
        public static void doLogoutIMServer(final Context context, final Observer obsForSucess)
        {
                // 退出登陆
                new AsyncTask<Object, Integer, Integer>(){
                        
                        private Observer obsForSucess = null;
                        
                        @Override
                        protected Integer doInBackground(Object... params)
                        {
                                int code = -1;
                                try
                                {
                                        if(params != null)
                                                obsForSucess = (Observer)params[0];
                                        
                                        // local user info 为空即意味着用户极是打开了登陆界面而尚未有登陆过,那当然就不需要退出登陆罗
                                        if(MyApplication.getInstance(context).getIMClientManager().getLocalUserInfo() != null)
                                                code = LocalDataSender.getInstance().sendLoginout();
                                }
                                catch (Exception e)
                                {
                                        Log.e(TAG, "错误发生于doLogout:sendLoginout时:"+e.getMessage(), e);
                                }
                                return code;
                        }

                        @Override
                        protected void onPostExecute(Integer code)
                        {
                                // local user info 为空即意味着用户极是打开了登陆界面而尚未有登陆过,那当然就不需要退出登陆罗
                                if(MyApplication.getInstance(context).getIMClientManager().getLocalUserInfo() != null)
                                {
                                        if(code == 0)
                                                Log.d(LoginActivity.class.getSimpleName(), "注销登陆请求已成功发出!");
                                        else
                                                Log.w(LoginActivity.class.getSimpleName(), "注销登陆请求发送失败。错误码是:"+code+"!");
                                }
                                
                                try
                                {
                                        // 释放IM所占资源
                                        MyApplication.getInstance(context).getIMClientManager().releaseMobileIMSDK();
                                }
                                catch (Exception e)
                                {
                                        Log.e(TAG, "错误发生于logoutMobileIMSDK:onPostExecute:releaseMobileIMSDK()时:"+e.getMessage(), e);
                                }
                                
                                // * 处理完成后通知观察者做其它事哦
                                if(obsForSucess != null)
                                        obsForSucess.update(null, null);
                        }
                }.execute(obsForSucess);

IMClientManager.releaseMobileIMSDK()方法的实现代码:
        /**
         * 释放IM框架所占用的资源,在退出登陆时请务必调用本方法,否则重
         * 新登陆将不能正常实现(指APP进程不退出时切换账号这种情况)。
         */
        public void releaseMobileIMSDK()
        {
                // 释放IM核心库资源
                ClientCoreSDK.getInstance().release();
                
                // 重置本类的初始化标识
                this.resetInitFlag();
                
                // 清空设置的回调
                ClientCoreSDK.getInstance().setChatBaseEvent(null);
                ClientCoreSDK.getInstance().setChatMessageEvent(null);
                ClientCoreSDK.getInstance().setMessageQoSEvent(null);

                // 清空本量中的关键全局变量
                 this.localUserInfo = null;
                this.currentFrontGroupChattingGroupID = null;
                this.currentFrontTempChattingUserUID = null;
                this.currentFrontChattingUserUID = null;

                // 重置关键数据模型变量
                this.friendsListProvider = null;
                this.groupsProvider = null;
                this.messagesProvider = null;
                this.groupsMessagesProvider = null;
                this.alarmsProvider = null;
            
                this.currentVideoChattingActivity = null;

                ProhibitSpeechCheckerProvider.getInstance().clear();

                // 释放实时音视频相关资源
                VVP2PProvider.getInstance(context).release();
        }


注意一点:RainbowChat中,在登陆界面跳转前,就进行是IM SDK的Init,所以即使是你看到的“退出登陆”这种情况,也可以确保再次登陆前已经完成im sdk的init:
        /**
         * 打开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;
        }

IMClientManager.initMobileIMSDK()的代码实现:
/**
         * IM框架初始化方法,本方法在连接IM服务器前必须被调用1次,否则IM底层框架将无法工作。
         */
        public void initMobileIMSDK() 
        {
                if(!this._init)
                {
                        baseEventListener = new ChatBaseEventListener(context);
                        transDataListener = new ChatMessageEventListener(context);
                        messageQoSListener = new MessageQoSListener(context);

                        ClientCoreSDK.getInstance().init(context);
                        ClientCoreSDK.getInstance().setChatBaseEvent(baseEventListener);
                        ClientCoreSDK.getInstance().setChatMessageEvent(transDataListener);
                        ClientCoreSDK.getInstance().setMessageQoSEvent(messageQoSListener);

//                        ClientCoreSDK.DEBUG = true;

                        friendsListProvider = new FriendsListProvider();
                        groupsProvider = new GroupsProvider();
                        messagesProvider = new MessagesProvider();
                        groupsMessagesProvider = new GroupsMessagesProvider();
                        alarmsProvider = new AlarmsProvider(this.context);

                        this._init = true;
                }
        }
签名: 《零基础IM开发入门(三):什么是IM系统的可靠性?》http://www.52im.net/thread-3182-1-1.html
[已回复] 求助关于MobileIMSDK聊天消息指纹码的生成以及其它疑问 这段代码解决了我的这个问题。我在退出登录的时候没有解绑监听器。
引用:JackJiang 发表于 2020-09-24 13:40
好,我来把RainbowChat中的“退出登陆”这个功能的主要实现代码,发你参一下,具体如果你不太理解功能是 ...

新进展是我这边连接github 项目中的
MobileIMSDK-master\demo_binary\Server\MobileIMSDKServerDemo_deploy_v5.0b20200905\run.bat在我本地是不会断开的,应该是我们后端的同学那里代码有问题。现在那边正在排查
引用:暄落 发表于 2020-09-24 13:58
新进展是我这边连接github 项目中的
MobileIMSDK-master\demo_binary\Server\MobileIMSDKServerDemo_de ...

嗯,以官方的Demo为参照点,如果搞不定,你就开贴,需要什么协助会尽力帮你
签名: 《零基础IM开发入门(三):什么是IM系统的可靠性?》http://www.52im.net/thread-3182-1-1.html
友情围观,群主的耐心,我等菜鸟自愧不如
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部