腾讯云im接入实现c2c聊天

1.准备工作 : 应用接入指引

注意 sdkappid 和 accounttype ,之后将会在代码中用到。

2.了解用户集成体系:独立模式和托管模式

如果您的APP自主维护用户的注册、用户身份的验证,则应当使用独立模式,
如果您只是想快速开发一个APP原型,云通信可以为您提供一套符合业界通用安全标准的用户体系,用户的注册、用户身份的验证将全部由云通信提供,此时应当选用托管模式。

【独立模式】:用户帐号信息由开发者保存,用户身份验证(比如注册与验密)也由开发者负责;
【托管模式】:由腾讯为开发者提供帐号的密码注册、存储和密码验证,以及第三方 openid 和 token 的托管验证服务。

公私钥(密码学中非对称加密算法中的概念,用于鉴别开发者用户的身份合法性)

【独立模式】:私钥由开发者保存,公钥由腾讯保存。开发者使用私钥生成用户签名 UserSig,腾讯使用公钥对签名 UserSig 进行校验。
【托管模式】:私钥由腾讯保存,公钥由开发者保存。腾讯使用私钥生成用户签名 UserSig,开发者可以使用公钥对签名 UserSig 进行校验,注意,对于第三方开放帐号,此时不需要公私钥。

本测试案例选择的是托管模式,这里由 TLS 为开发者提供 App 帐号的密码注册、存储和密码验证。帐号验证成功后,派发私钥加密生成的签名到客户端,App 业务服务器可以通过 下载的公钥 解密签名进行验证。

腾讯云im接入实现c2c聊天_第1张图片

3.开始项目

首先下载demo,并按照demo格式将以下四个moudle集成
腾讯云im接入实现c2c聊天_第2张图片
更改sdk库中的参数
腾讯云im接入实现c2c聊天_第3张图片
demo中是三个tab,我们测试的例子中只有一个聊天列表的页面。主要为ConversationFragment,这里是为了测试是我们自己的逻辑,不同于demo中的ConversationFragment。
想要实现点对点聊天,如果为了方便 我们可以直接在腾讯云通信后台中配置中手动添加两个管理员
腾讯云im接入实现c2c聊天_第4张图片
并下载用户凭证,分别得到admin1和admin2的 usersig 用户登录所需的两个参数一个是id,另一个就是UserSig
腾讯云im接入实现c2c聊天_第5张图片
初始化配置
 @Override
    public void initTencentImConfig() {
        //初始化IMSDK
        InitBusiness.start(mView.getApplicationContext(), TIMLogLevel.DEBUG.ordinal());
        //初始化TLS
        TlsBusiness.init(mView.getApplicationContext());
        Log.d("tencentim", "初始化腾讯云Im");
        String id = TLSService.getInstance().getLastUserIdentifier();
        UserInfo.getInstance().setId(id);
        UserInfo.getInstance().setUserSig(TLSService.getInstance().getUserSig(id));
        // 初始化TLSSDK
       TLSHelper   tlsHelper = TLSHelper.getInstance().init(mView.getApplicationContext(), Constant.SDK_APPID);

//登录
login();
//simulateRegistered();//模拟注册
}
3登录
private void login(){
        LoginBusiness.loginIm("admin1",
                "eJx1z09PgzAYx-E7r6LpVWNoiwxMPLCNsC7imMM-eGmAduYJ0nVQF6fxvRtxiVx8rr9P8s3z6SCEcH6zuSjrevemrbBHozC6QpgxFlJ8-geMASlKK1gnB0A81yWUTggbKfVuoFOi3FrV-arLiR*4PzdSIJW2sIWTKWULmoz2XjZi6P0f6uFlGNP4fsYT6S9YlUyrffC4mpuP43Ma8Wy*uivyPuN6Rj2Z5E8*OVQmgjhqikIHTbrTSQNn1XT-cKhjEoYZvG5aWsiA6wVdrvntMl1fj5IWWnX6iTE-DJhHsfPlfAPflld1",
                new TIMCallBack() {
                    @Override
                    public void onError(int i, String s) {
                        Log.d("tencentim", s);
                        Toast.makeText(mView.getContext(), s, Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onSuccess() {
                        Toast.makeText(mView.getContext(), "admin1登录成功", Toast.LENGTH_SHORT).show();
                        sendConversation();
                    }
                });
}
发送消息
  //通用消息发送
    //为了生成对话,每次跳转到这里都发送一条消息给对方
    @Override
    public void sendConversation() {
        TIMConversation timConversation;
        //获取单聊会话
        String peer = "admin2";  //获取与用户 "xxx" 的会话
        timConversation = TIMManager.getInstance().getConversation(
                TIMConversationType.C2C,    //会话类型:单聊
                peer);                      //会话对方用户帐号//对方id


        //构造一条消息
        TIMMessage msg = new TIMMessage();

        //添加文本内容
        TIMTextElem elem = new TIMTextElem();
        elem.setText("你好admin2,我是admin1,哈哈哈");

        //将elem添加到消息
        if (msg.addElement(elem) != 0) {
            Log.d("tencentim", "addElement failed");
            return;
        }

        //发送消息
        timConversation.sendMessage(msg, new TIMValueCallBack() {//发送消息回调
            @Override
            public void onError(int code, String desc) {//发送消息失败
                //错误码code和错误描述desc,可用于定位请求失败原因
                //错误码code含义请参见错误码表
                Log.d("tencentim", "send message failed. code: " + code + " errmsg: " + desc);
            }

            @Override
            public void onSuccess(TIMMessage msg) {//发送消息成功
                Log.e("tencentim", "SendMsg ok");

            }
        });

    }

取得会话
    /**
     * 取得会话
     */
    @Override
    public void getConversation() {

        List list = TIMManagerExt.getInstance().getConversationList();
        List result = new ArrayList<>();
        for (TIMConversation conversation : list) {
            //continue用来结束本次循环
            if (conversation.getType() == TIMConversationType.System) continue;
            result.add(conversation);
            TIMConversationExt conversationExt = new TIMConversationExt(conversation);
            conversationExt.getMessage(1, null, new TIMValueCallBack>() {
                @Override
                public void onError(int i, String s) {
                    Log.e("tencentim", "get message error" + s);
                }

                @Override
                public void onSuccess(List timMessages) {
                    if (timMessages.size() > 0) {
                        mView.updateMessage(timMessages.get(0));
                    }

                }
            });

        }
        mView.initView(result);

    }
通知view更新列表,将conversations添加到adapter中,更新列表。当然,我们前提会注册监听器

public class ConversationPresenter implements ConversationContract.Presenter, Observer {
    private ConversationContract.View mView;
    private TLSStrAccRegListener strAccRegListener;

    private TLSHelper tlsHelper;


    public ConversationPresenter(ConversationContract.View view) {
        //注册消息监听
        MessageEvent.getInstance().addObserver(this);
        //注册刷新监听
        RefreshEvent.getInstance().addObserver(this);
        //注册好友关系链监听
        FriendshipEvent.getInstance().addObserver(this);
        //注册群关系监听
        GroupEvent.getInstance().addObserver(this);
        this.mView = view;
        mView.setPresenter(this);

    }

......
......

 @Override
    public void update(Observable observable, Object data) {

        if (observable instanceof MessageEvent) {
            Log.d("tencentim", "更新消息");
            if (data instanceof TIMMessage) {
                TIMMessage msg = (TIMMessage) data;
                mView.updateMessage(msg);
            }
        } else if (observable instanceof FriendshipEvent) {
            Log.d("tencentim", "更新好友链");
            FriendshipEvent.NotifyCmd cmd = (FriendshipEvent.NotifyCmd) data;
            switch (cmd.type) {
                case ADD_REQ:
                case READ_MSG:
                case ADD:
                    mView.updateFriendshipMessage();
                    break;
            }
        } else if (observable instanceof GroupEvent) {
            Log.d("tencentim", "更新群组");
            GroupEvent.NotifyCmd cmd = (GroupEvent.NotifyCmd) data;
            switch (cmd.type) {
                case UPDATE:
                case ADD:
                    mView.updateGroupInfo((TIMGroupCacheInfo) cmd.data);
                    break;
                case DEL:
                    mView.removeConversation((String) cmd.data);
                    break;

            }
        } else if (observable instanceof RefreshEvent) {
            Log.d("tencentim", "更新会话列表");
            getConversation();
            mView.refresh();
        }
    }
}
更改登录 admin1 admin2 的信息(id,和usersig) 分别运行,效果如下图

登录admin1 模拟发消息给admin2


腾讯云im接入实现c2c聊天_第6张图片
登录admin1 模拟发消息给admin2
再登录admin2 模拟发消息给admin1 同时他也收到admin1之前给admin2发的消息
腾讯云im接入实现c2c聊天_第7张图片
如此以来 通过手动添加实现一个简单的c2c聊天
但是我们不能都通过后台添加管理员 我们需要注册登录实现聊天,那我们开始通过代码实现。首先我们要模拟注册和模拟登录,托管模式我们主要依靠的是tls。主要写模拟注册和模拟登录 省略页面部分。
主要流程 simulateRegistered();//模拟注册--->simulateLogin();//模拟登录,主要是为了获得usersig-->客户端登录验证-->发送消息
private void simulateRegistered() {

        // 引导用户输入合法的用户名和密码
        int result = tlsHelper.TLSStrAccReg("用户1", "12345678", new TLSStrAccRegListener() {
            @Override
            public void OnStrAccRegSuccess(TLSUserInfo tlsUserInfo) {
                /* 成功注册了一个字符串帐号, 可以引导用户使用刚注册的用户名和密码登录 */
                simulateLogin("用户1","12345678");
            }

            @Override
            public void OnStrAccRegFail(TLSErrInfo tlsErrInfo) {
                /* 注册失败,请提示用户失败原因 */

            }

            @Override
            public void OnStrAccRegTimeout(TLSErrInfo tlsErrInfo) {
                /* 网络超时,可能是用户网络环境不稳定,一般让用户重试即可。*/


            }
        });
        if (result == TLSErrInfo.INPUT_INVALID){
            Log.d("tencentim","注册失败");
        }

    }

    private void simulateLogin(final String username, String password) {

        tlsHelper.TLSPwdLogin(username, password.getBytes(), new TLSPwdLoginListener() {
            @Override
            public void OnPwdLoginSuccess(TLSUserInfo tlsUserInfo) {
                String usersig = tlsHelper.getUserSig(tlsUserInfo.identifier);
                Log.d("tencentim","usersig:"+usersig);
//获得usersig后登录
                LoginBusiness.loginIm(username, usersig,
                        new TIMCallBack() {
                            @Override
                            public void onError(int i, String s) {
                                Log.d("tencentim", s);
                                Toast.makeText(mView.getContext(), s, Toast.LENGTH_SHORT).show();
                            }

                            @Override
                            public void onSuccess() {
                                Toast.makeText(mView.getContext(), username + "登录成功", Toast.LENGTH_SHORT).show();
                                sendConversation();
                                getConversation();
                            }
                        });
            }

            @Override
            public void OnPwdLoginReaskImgcodeSuccess(byte[] bytes) {

            }

            @Override
            public void OnPwdLoginNeedImgcode(byte[] bytes, TLSErrInfo tlsErrInfo) {
                    Log.d("tencentim","用户需要进行图片验证码的验证");
            }

            @Override
            public void OnPwdLoginFail(TLSErrInfo tlsErrInfo) {

            }

            @Override
            public void OnPwdLoginTimeout(TLSErrInfo tlsErrInfo) {

            }
        });
    }

如果账户存在,则不能注册,进行登录验证即可。注意注册时要数字字母都有,位数不能过少,具体看官方规定,自行测试。
腾讯云im接入实现c2c聊天_第8张图片
登录usertest1,收到usertest2的消息

本示例只是简单的一个demo测试,想要更深了解,需要好好阅读官方文档 --- 新手指引

你可能感兴趣的:(腾讯云im接入实现c2c聊天)