騰訊云im接入實現(xiàn)c2c聊天

1.準備工作 : 應用接入指引

注意 sdkappid 和 accounttype ,之后將會在代碼中用到。

2.了解用戶集成體系:獨立模式和托管模式

如果您的APP自主維護用戶的注冊、用戶身份的驗證,則應當使用獨立模式,
如果您只是想快速開發(fā)一個APP原型,云通信可以為您提供一套符合業(yè)界通用安全標準的用戶體系,用戶的注冊、用戶身份的驗證將全部由云通信提供,此時應當選用托管模式。

【獨立模式】:用戶帳號信息由開發(fā)者保存,用戶身份驗證(比如注冊與驗密)也由開發(fā)者負責;
【托管模式】:由騰訊為開發(fā)者提供帳號的密碼注冊、存儲和密碼驗證,以及第三方 openid 和 token 的托管驗證服務。

公私鑰(密碼學中非對稱加密算法中的概念,用于鑒別開發(fā)者用戶的身份合法性)

【獨立模式】:私鑰由開發(fā)者保存,公鑰由騰訊保存。開發(fā)者使用私鑰生成用戶簽名 UserSig,騰訊使用公鑰對簽名 UserSig 進行校驗。
【托管模式】:私鑰由騰訊保存,公鑰由開發(fā)者保存。騰訊使用私鑰生成用戶簽名 UserSig,開發(fā)者可以使用公鑰對簽名 UserSig 進行校驗,注意,對于第三方開放帳號,此時不需要公私鑰。

本測試案例選擇的是托管模式,這里由 TLS 為開發(fā)者提供 App 帳號的密碼注冊、存儲和密碼驗證。帳號驗證成功后,派發(fā)私鑰加密生成的簽名到客戶端,App 業(yè)務服務器可以通過 下載的公鑰 解密簽名進行驗證。

3.開始項目

首先下載demo,并按照demo格式將以下四個moudle集成
更改sdk庫中的參數(shù)
demo中是三個tab,我們測試的例子中只有一個聊天列表的頁面。主要為ConversationFragment,這里是為了測試是我們自己的邏輯,不同于demo中的ConversationFragment。
想要實現(xiàn)點對點聊天,如果為了方便 我們可以直接在騰訊云通信后臺中配置中手動添加兩個管理員
并下載用戶憑證,分別得到admin1和admin2的 usersig 用戶登錄所需的兩個參數(shù)一個是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();
                    }
                });
}
發(fā)送消息
  //通用消息發(fā)送
    //為了生成對話,每次跳轉到這里都發(fā)送一條消息給對方
    @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;
        }

        //發(fā)送消息
        timConversation.sendMessage(msg, new TIMValueCallBack<TIMMessage>() {//發(fā)送消息回調
            @Override
            public void onError(int code, String desc) {//發(fā)送消息失敗
                //錯誤碼code和錯誤描述desc,可用于定位請求失敗原因
                //錯誤碼code含義請參見錯誤碼表
                Log.d("tencentim", "send message failed. code: " + code + " errmsg: " + desc);
            }

            @Override
            public void onSuccess(TIMMessage msg) {//發(fā)送消息成功
                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用來結束本次循環(huán)
            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中,更新列表。當然,我們前提會注冊監(jiān)聽器

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

    private TLSHelper tlsHelper;


    public ConversationPresenter(ConversationContract.View view) {
        //注冊消息監(jiān)聽
        MessageEvent.getInstance().addObserver(this);
        //注冊刷新監(jiān)聽
        RefreshEvent.getInstance().addObserver(this);
        //注冊好友關系鏈監(jiān)聽
        FriendshipEvent.getInstance().addObserver(this);
        //注冊群關系監(jiān)聽
        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 模擬發(fā)消息給admin2


登錄admin1 模擬發(fā)消息給admin2
再登錄admin2 模擬發(fā)消息給admin1 同時他也收到admin1之前給admin2發(fā)的消息
如此以來 通過手動添加實現(xiàn)一個簡單的c2c聊天
但是我們不能都通過后臺添加管理員 我們需要注冊登錄實現(xiàn)聊天,那我們開始通過代碼實現(xiàn)。首先我們要模擬注冊和模擬登錄,托管模式我們主要依靠的是tls。主要寫模擬注冊和模擬登錄 省略頁面部分。
主要流程 simulateRegistered();//模擬注冊--->simulateLogin();//模擬登錄,主要是為了獲得usersig-->客戶端登錄驗證-->發(fā)送消息
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) {
                /* 注冊失敗,請?zhí)崾居脩羰≡?*/

            }

            @Override
            public void OnStrAccRegTimeout(TLSErrInfo tlsErrInfo) {
                /* 網(wǎng)絡超時,可能是用戶網(wǎng)絡環(huán)境不穩(wěn)定,一般讓用戶重試即可。*/


            }
        });
        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) {

            }
        });
    }

如果賬戶存在,則不能注冊,進行登錄驗證即可。注意注冊時要數(shù)字字母都有,位數(shù)不能過少,具體看官方規(guī)定,自行測試。
登錄usertest1,收到usertest2的消息

本示例只是簡單的一個demo測試,想要更深了解,需要好好閱讀官方文檔 --- 新手指引

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,694評論 19 139
  • 以后項目會用到即時通信,寫了一個demo,這里整理下集成騰訊云IM過程。 云通信架構 提供單聊、群聊、資料托管、關...
    uli閱讀 5,502評論 0 6
  • 淺析一下這里面的機會和比較容易成功的地方。 先講一下選擇,對于創(chuàng)業(yè)來講,擇業(yè)和選擇的方向要遠遠超過努力,做正確的事...
    周子翼閱讀 716評論 0 1
  • 時光荏苒,歲月如梭,關鍵地一點是我在這條路上,走得有些艱難,也有些心累,可是終究你選擇的路徑,無論結果如何,依舊要...
    海豚的世界_0820閱讀 247評論 0 0

友情鏈接更多精彩內容