美文网首页从0到1开发一款APPAndroid 直播APPAndroid技术知识
【从 0 开始开发一款直播 APP】11 IM 登录实现

【从 0 开始开发一款直播 APP】11 IM 登录实现

作者: 菜鸟窝 | 来源:发表于2017-05-08 09:11 被阅读268次

    本文为菜鸟窝作者蒋志碧的连载。“从 0 开始开发一款直播 APP ”系列来聊聊时下最火的直播 APP,如何完整的实现一个类"腾讯直播"的商业化项目


    【从 0 开始开发一款直播 APP】10 腾讯云通信及SDK集成
    【从 0 开始开发一款直播 APP】11 IM 登录实现


    对上一篇文章中留下两个问题没有解决。

    1、独立模式和托管模式

    账号登录集成说明
    打开该文档,先看看账号集成的大致步骤,请读者仔细阅读上面的文字,既然笔者都贴出来了,就是经过筛选并对开发有一定用处的。
    step 3 创建应用在上一章已经讲过,这里不再讲解。


    TLS 登录支持三种模式:1、托管模式 3、独立模式 3、游客模式

    1、托管模式

    1.1、用户名密码等账号信息托管在腾讯后台,这是我们在苹果 AppStore 上的 APP 所采用的模式
    1.2、调用 TLS(tencent login service) 获取 TLSUserInfo,内部包含了短期有效的id和签名,这段逻辑详见 LoginActivity.java
    1.3、使用 TLS 登录返回的 id 和签名,调用 TCLoginMgr 的 imLogin() 函数完成IM模块的登录,之后就可以收发消息了

    2、独立模式

    2.1、 如果您已有帐号体系且需要支持可靠的 C2C 消息,则需要使用此种方式。
    此模式的目标是将腾讯云通讯模块跟您的账号体系结合起来实现安全可靠的消息通讯。
    2.2、您先使用自己的登录逻辑进行登录,之后交给您的服务器验证当前用户是不是一个合法的用户。
    2.3、如果当前用户通过验证,您的登录服务器要使用跟腾讯云协商的非对称加密密钥对用户 ID 进行签名。
    这就好比您的服务器给这个用户 ID 做了担保:“这是个好孩子,我给他担保,有公章在此,请给他通过。”
    2.4、APP在收到用户 ID 和签名后,TCLoginMgr的imLogin() 函数完成IM模块的登录,之后就可以收发消息了

    3、游客模式

    3.1、 如果您已有帐号体系,适合使用这种模式,该模式下腾讯云通讯模块会使用内部的一些匿名账号进行消息的收发。
    3.2、这种模式下,您只需要调用TCLoginMgr的guestLogin()函数即可实现,内部流程跟托管模式类似,只是账号换成了随机生成的匿名账号。
    3.3、 如果想要将IM模块跟您的账号体系进行结合,实现您的两个账号间的私信收发,请看独立模式。


    2、sdkAppId 和 accountType。

    sdkAppId:用于标识接入SDK的应用Id,由腾讯分配。
    accountType:帐号类型,由腾讯分配。

    注意:

    sdkAppId 和 accountType 这两个参数在利用菜鸟窝账号发起直播才会用到,现在登录的时候返回的都是 null,在后面发起直播会详细介绍。

    从图中可以看出,登录需要使用到这两个参数,accountType 是 TIMUser 的一个成员变量。


    登录 SDK 简介

    打开 登录 SDK 文档,主要有以下几个功能。

    1、登录

    查看登录方法以及参数列表。



    登录官方示例


    2、登出

    暂时只用到这两个功能,其它方法读者自己查看。


    IM 登录功能封装

    登录具体实现请查看 【从 0 开始开发一款直播 APP】5.1 MVP 完全解析 -- 实现直播登录

    1、创建 IMLogin 类

    IMLogin 主要封装 IM 登录需要的相关方法和回调。

    public class IMLogin {
    
        public static final String TAG = IMLogin.class.getSimpleName();
        private static IMLogin mInstace = null;
    
        public IMLogin() {
        }
    
        public static IMLogin getInstace() {
            if (mInstace == null) {
                synchronized (IMLogin.class) {
                    mInstace = new IMLogin();
                }
            }
            return mInstace;
        }
    }
    

    2、IM 登录方法

    根据官方文档中提供的 login() ,方法,封装我们自己的 IMLogin() 方法,里面只需要实现登录逻辑即可,具体调用在 presenter 中实现。

    public void login(int sdkAppId,//用于标识接入SDK的应用Id,由腾讯分配。
             //用户帐号:
             //accountType,帐号类型,由腾讯分配。
             //appIdAt3rd,使用自有帐号或腾讯开放帐号时,填写为与sdkAppId相同的字符串。
             //identifier,用户帐号。
             TIMUser user,
             java.lang.String userSig,//userSig,用户帐号签名,由私钥加密获得,具体请参考帐号相关文档。
             TIMCallBack callback)//回调接口。
    //-----------------------------------split line ------------------------------------ 
     //云通信服务相关配置
    //从之前创建的应用中获取 SdkAppId 和 accountType 
    public static int IMSDK_ACCOUNT_TYPE = 12242;
    public static int IMSDK_APPID = 1400029483;
    //-----------------------------------split line ------------------------------------
     private IMLoginListener mIMLoginListener;
    /**
     * imsdk登录接口,与tls登录验证成功后调用
     * @param identify 用户id,后台生成的 user_sig 的用户信息
     * @param sigId    用户签名(托管模式下由TLSSDK生成,独立模式下由开发者在IMSDK云通信后台确定加密秘钥)
     */
    public void imLogin(String identify, String sigId) {
        //用户实体类
        TIMUser user = new TIMUser();
        user.setAccountType(String.valueOf(Constants.IMSDK_ACCOUNT_TYPE));
        user.setAppIdAt3rd(String.valueOf(Constants.IMSDK_APPID));
        user.setIdentifier(identify);
        //发起登录请求,调用腾讯的IMLogin
        TIMManager.getInstance().login(Constants.IMSDK_APPID, user, sigId, new TIMCallBack() {
            @Override
            public void onError(int i, String s) {
                Log.e(TAG, "imLogin onError i:" + i + ",info:" + s);
                if (null != mIMLoginListener)
                    mIMLoginListener.onFailure(i, s);
            }
    
            @Override
            public void onSuccess() {
                Log.e(TAG, "imLogin onSuccess");
                if (null != mIMLoginListener)
                    mIMLoginListener.onSuccess();
            }
        });
    }
    

    登录中使用到接口回调,具体如下:

    /**
     * 腾讯云登录回调接口
     * Login 回调
     */
    public interface IMLoginListener {
        /**
         * 登录成功
         */
        void onSuccess();
        /**
         * 登录失败
         * @param code 错误码
         * @param msg  错误信息
         */
        void onFailure(int code, String msg);
    }
    

    3、IM 登出方法

    // 登出
    public void logout(TIMCallBack callback)//IM 登出
    //-----------------------------------split line -----------------------------------   
    //IMSDK登出
    public void imLoginOut() {
        TIMManager.getInstance().logout(new TIMCallBack() {
            @Override
            public void onError(int i, String s) {
                Log.e(TAG, "IMLogout failure :" + i + " msg " + s);
            }
            @Override
            public void onSuccess() {
                Log.e(TAG, "IMLogout success");
            }
        });
    }
    

    IM 登录初始化

    public class LiveApplication extends Application{
        private static LiveApplication instance;
        @Override
        public void onCreate() {
            super.onCreate();
            instance = this;
            //初始化 IMSDK
            IMInitMgr.init(getApplicationContext());
            //初始化 IMLogin
            IMLogin.getInstace();
            Log.e("imLogin",TIMManager.getInstance().getVersion());
        }
        public static LiveApplication getInstance(){
            return instance;
        }
    }
    

    IM 登录实现

    在 LoginPresenter.java 类中定义 IMLogin,并实现 IMLogin.IMLoginListener 接口。

    public class LoginPresenter extends ILoginPresenter implements IMLogin.IMLoginListener {
      //IMLogin
      private IMLogin mIMLogin = IMLogin.getInstace();
        
      @Override
      public void onSuccess() {
      }
      
      @Override
      public void onFailure(int code, String msg) { 
      }
    }
    

    在用户名登录方法中调用 IM 登录方法。只需要将原来的 login 方法替换即可。

    @Override
    public void userNameLogin(final String userName, final String password) {
    
            if (checkUserNameLogin(userName, password)) {
                LoginRequest request = new LoginRequest(RequestComm.loginUsername, userName, password);
                AsyncHttp.instance().postJson(request, new AsyncHttp.IHttpListener() {
                    @Override
                    public void onStart(int requestId) {
                        mLoginView.showLoading();
                    }
    
                    @Override
                    public void onSuccess(int requestId, Response response) {
                        if (response.getStatus() == RequestComm.SUCCESS) {
                            UserInfo info = (UserInfo) response.getData();
    UserInfoCache.saveCache(mLoginView.getContext(), info);
    ACache.get(mLoginView.getContext()).put(CacheConstants.LOGIN_USERNAME, userName);
    ACache.get(mLoginView.getContext()).put(CacheConstants.LOGIN_PASSWORD, password);
                            //设置监听回调
                            mIMLogin.setIMLoginListener(LoginPresenter.this);
                            //IM登录
                            mIMLogin.imLogin(info.getUserId(), info.getSigId());
                            //将原来的 login 方法替换即可
                            //mLoginView.loginSuccess();
                        } else {
                            mLoginView.loginFailed(response.getStatus(), response.getMsg());
                            mLoginView.dismissLoading();
                        }
                    }
    
                    @Override
                    public void onFailure(int requestId, int httpStatus, Throwable error) {
                        mLoginView.loginFailed(httpStatus, error.getMessage());
                        mLoginView.dismissLoading();
                    }
                });
            }
    }
    

    实现 onSuccess() 和 onFailure() 即可。

    @Override
    public void onSuccess() {
       Log.e(TAG, "onSuccess:login success");
       //移除监听
       mIMLogin.removeIMLoginListener();
       //登录成功提示
       mLoginView.dismissLoading();
       mLoginView.loginSuccess();
    }
    
    @Override
    public void onFailure(int code, String msg) {
       Log.e(TAG, "onFailure:login failed");
       mLoginView.dismissLoading();
       mLoginView.loginFailed(code,msg);
    }
    

    运行程序

    在控制台过滤之后可以看到登录成功并打印出登录信息.。


    每个程序猿必备的110本经典编程书,免费领取地址:http://mp.weixin.qq.com/s/cx433vAj_CDLzmhOoUS6zA

    相关文章

      网友评论

        本文标题:【从 0 开始开发一款直播 APP】11 IM 登录实现

        本文链接:https://www.haomeiwen.com/subject/wccmtxtx.html