腾讯云im接入实现c2c聊天

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

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

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

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

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

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

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

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

3.开始项目

首先下载demo,并按照demo格式将以下四个moudle集成
更改sdk库中的参数
demo中是三个tab,我们测试的例子中只有一个聊天列表的页面。主要为ConversationFragment,这里是为了测试是我们自己的逻辑,不同于demo中的ConversationFragment。
想要实现点对点聊天,如果为了方便 我们可以直接在腾讯云通信后台中配置中手动添加两个管理员
并下载用户凭证,分别得到admin1和admin2的 usersig 用户登录所需的两个参数一个是id,另一个就是UserSig
初始化配置
 @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<TIMMessage>() {//发送消息回调
            @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<TIMConversation> list = TIMManagerExt.getInstance().getConversationList();
        List<TIMConversation> 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<List<TIMMessage>>() {
                @Override
                public void onError(int i, String s) {
                    Log.e("tencentim", "get message error" + s);
                }

                @Override
                public void onSuccess(List<TIMMessage> 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


登录admin1 模拟发消息给admin2
再登录admin2 模拟发消息给admin1 同时他也收到admin1之前给admin2发的消息
如此以来 通过手动添加实现一个简单的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) {

            }
        });
    }

如果账户存在,则不能注册,进行登录验证即可。注意注册时要数字字母都有,位数不能过少,具体看官方规定,自行测试。
登录usertest1,收到usertest2的消息

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容