最近公司微信小程式需要集成騰訊IM實作實時聊天功能,這篇文章就記錄我在集成程序中所踩得坑和心得
首先第一步: 當然是進官網讀檔案
檔案地址 : https://cloud.tencent.com/document/product/269/36838
第一個看到的就是這個一分鐘跑通demo(實際上我感覺看了跟沒看一樣,沒啥太大幫助)也就清楚了一下前期準備作業:
- 首先你要有一個可用的騰訊云賬號
- 然后你需要登錄 即時通信IM控制臺
- 在控制臺中添加新應用
- 創建應用后點進去可以拿到應用的 SDKAppId 以及 密鑰
- 注意:大哥些這里可以把demo源檔案下載下來,一會兒有大用處
接下來繼續翻,真正符合我需求的還是檔案 常規集成 這一塊

根據檔案要求先將依賴搞好(其實也可以直接在源檔案里面把 tim-wx.js 直接拷過來放你專案里也行)
// IM 小程式 SDK
npm install tim-wx-sdk --save
// 發送圖片、檔案等訊息需要的 COS SDK
npm install cos-wx-sdk-v5 --save
依賴安好,參考,搞到這里我就出現了第一個問題,搞得我頭痛,我參考依賴后報了個錯誤
import TIM from '../../tim-wx-sdk/tim-wx';

一開始把我搞蒙了,然后就當然網上查,然后得到的資訊是小程式開啟ES6轉碼后async函式無法使用,說到底就是這依賴語法用得有點高唄,然后網上給的解決辦法最為直接有效的有兩種(都是在小程式專案詳情的本地設定里處理):

- 關了ES6 轉 ES5 (我當時就否決了,他娘的這個一關我小程式其它地方不得崩死?誰還不用點es6啊)
- 開啟增強編譯( √ 這就好辦了,立刻我就把增強編譯打開了 注意:如果你沒有這個選項,你就更新你的開發者工具,別用老古董版本了)
然后我滿懷希望的再次編譯得到的還是它(當時我就急了,網友這不騙人嗎!!!)

然后又是慢慢網搜路,還是不知道哪兒出問題了 就是不行…最后的最后,被我找到了,還是本地設定里

我他娘的用了老古董除錯基礎庫= =(怪我,不該質疑無私的碼友們)我火速改到最新的!!!

然后就不報錯了!!!淚目啊淚目,我算是把第一個坑踩過了
接下來就是按部就班初始化im了(直接把檔案的扒下來就行)
init_TIM() {//初始化im實時聊天
let options = {
SDKAppID: 0// 接入時需要將0替換為您的即時通信 IM 應用的 SDKAppID
};
let that = this
// 創建 SDK 實體,`TIM.create()`方法對于同一個 `SDKAppID` 只會回傳同一份實體
this.tim = TIM.create(options);// SDK 實體通常用 tim 表示
// 設定 SDK 日志輸出級別,詳細分級請參見 setLogLevel 介面的說明
this.tim.setLogLevel(0); // 普通級別,日志量較多,接入時建議使用
// tim.setLogLevel(1); // release 級別,SDK 輸出關鍵資訊,生產環境時建議使用
// 注冊 COS SDK 插件
// tim.registerPlugin({'cos-wx-sdk': COS})
// 監聽事件,例如:
this.tim.on(TIM.EVENT.SDK_READY, function(event) {
// 收到離線訊息和會話串列同步完畢通知,接入側可以呼叫 sendMessage 等需要鑒權的介面
// event.name - TIM.EVENT.SDK_READY
});
this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, function(event) {
// 收到推送的單聊、群聊、群提示、群系統通知的新訊息,可通過遍歷 event.data 獲取訊息串列資料并渲染到頁面
// event.name - TIM.EVENT.MESSAGE_RECEIVED
// event.data - 存盤 Message 物件的陣列 - [Message]
});
this.tim.on(TIM.EVENT.MESSAGE_REVOKED, function(event) {
// 收到訊息被撤回的通知
// event.name - TIM.EVENT.MESSAGE_REVOKED
// event.data - 存盤 Message 物件的陣列 - [Message] - 每個 Message 物件的 isRevoked 屬性值為 true
});
this.tim.on(TIM.EVENT.MESSAGE_READ_BY_PEER, function(event) {
// SDK 收到對端已讀訊息的通知,即已讀回執,使用前需要將 SDK 版本升級至 v2.7.0 或以上,僅支持單聊會話,
// event.name - TIM.EVENT.MESSAGE_READ_BY_PEER
// event.data - event.data - 存盤 Message 物件的陣列 - [Message] - 每個 Message 物件的 isPeerRead 屬性值為 true
});
this.tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATED, function(event) {
// 收到會話串列更新通知,可通過遍歷 event.data 獲取會話串列資料并渲染到頁面
// event.name - TIM.EVENT.CONVERSATION_LIST_UPDATED
// event.data - 存盤 Conversation 物件的陣列 - [Conversation]
});
this.tim.on(TIM.EVENT.GROUP_LIST_UPDATED, function(event) {
// 收到群組串列更新通知,可通過遍歷 event.data 獲取群組串列資料并渲染到頁面
// event.name - TIM.EVENT.GROUP_LIST_UPDATED
// event.data - 存盤 Group 物件的陣列 - [Group]
});
this.tim.on(TIM.EVENT.PROFILE_UPDATED, function(event) {
// 收到自己或好友的資料變更通知
// event.name - TIM.EVENT.PROFILE_UPDATED
// event.data - 存盤 Profile 物件的陣列 - [Profile]
});
this.tim.on(TIM.EVENT.BLACKLIST_UPDATED, function(event) {
// 收到黑名單串列更新通知
// event.name - TIM.EVENT.BLACKLIST_UPDATED
// event.data - 存盤 userID 的陣列 - [userID]
});
this.tim.on(TIM.EVENT.ERROR, function(event) {
// 收到 SDK 發生錯誤通知,可以獲取錯誤碼和錯誤資訊
// event.name - TIM.EVENT.ERROR
// event.data.code - 錯誤碼
// event.data.message - 錯誤資訊
});
this.tim.on(TIM.EVENT.SDK_NOT_READY, function(event) {
// 收到 SDK 進入 not ready 狀態通知,此時 SDK 無法正常作業
// event.name - TIM.EVENT.SDK_NOT_READY
});
this.tim.on(TIM.EVENT.KICKED_OUT, function(event) {
// 收到被踢下線通知
// event.name - TIM.EVENT.KICKED_OUT
// event.data.type - 被踢下線的原因,例如:
// - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多實體登錄被踢
// - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多終端登錄被踢
// - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 簽名過期被踢 (v2.4.0起支持),
});
this.tim.on(TIM.EVENT.NET_STATE_CHANGE, function(event) {
// 網路狀態發生改變(v2.5.0 起支持),
// event.name - TIM.EVENT.NET_STATE_CHANGE
// event.data.state 當前網路狀態,列舉值及說明如下:
// \- TIM.TYPES.NET_STATE_CONNECTED - 已接入網路
// \- TIM.TYPES.NET_STATE_CONNECTING - 連接中,很可能遇到網路抖動,SDK 在重試,接入側可根據此狀態提示“當前網路不穩定”或“連接中”
// \- TIM.TYPES.NET_STATE_DISCONNECTED - 未接入網路,接入側可根據此狀態提示“當前網路不可用”,SDK 仍會繼續重試,若用戶網路恢復,SDK 會自動同步訊息
});
console.log('執行了init');
// this.login_TIM();
},
呼叫 , 執行

看到這一串大寶貝兒,我就舒了口氣,成功了嘛,那接下來我就登陸嘛!
login_TIM() {//登錄im實時聊天
let promise = this.tim.login({userID: '', userSig: ''});
promise.then(function(imResponse) {
console.log(imResponse.data); // 登錄成功
if (imResponse.data.repeatLogin === true) {
// 標識賬號已登錄,本次登錄操作為重復登錄,v2.5.1 起支持
console.log(imResponse.data.errorInfo);
}
}).catch(function(imError) {
console.warn('login error:', imError); // 登錄失敗的相關資訊
});
},
到這里userID隨便填一個測驗的就行,那userSig不行啊,要計算啊,那我就看檔案 : https://cloud.tencent.com/document/product/269/32688
他倒是給了客戶端計算的方法和原始碼

下載下來一看原始碼
global.webpackJsonpMpvue([18],{
/***/ "dutN":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _SDKAPPID; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return genTestUserSig; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__lib_generate_test_usersig_es_min_js__ = __webpack_require__("n7IX");
/*eslint-disable*/
const _SDKAPPID = 0;
const _SECRETKEY = '';
/*
* Module: GenerateTestUserSig
*
* Function: 用于生成測驗用的 UserSig,UserSig 是騰訊云為其云服務設計的一種安全保護簽名,
* 其計算方法是對 SDKAppID、UserID 和 EXPIRETIME 進行加密,加密演算法為 HMAC-SHA256,
*
* Attention: 請不要將如下代碼發布到您的線上正式版本的 App 中,原因如下:
*
* 本檔案中的代碼雖然能夠正確計算出 UserSig,但僅適合快速調通 SDK 的基本功能,不適合線上產品,
* 這是因為客戶端代碼中的 SECRETKEY 很容易被反編譯逆向破解,尤其是 Web 端的代碼被破解的難度幾乎為零,
* 一旦您的密鑰泄露,攻擊者就可以計算出正確的 UserSig 來盜用您的騰訊云流量,
*
* 正確的做法是將 UserSig 的計算代碼和加密密鑰放在您的業務服務器上,然后由 App 按需向您的服務器獲取實時算出的 UserSig,
* 由于破解服務器的成本要高于破解客戶端 App,所以服務器計算的方案能夠更好地保護您的加密密鑰,
*
* Reference:https://cloud.tencent.com/document/product/647/17275#Server
*/
function genTestUserSig(userID) {
/**
* 騰訊云 SDKAppId,需要替換為您自己賬號下的 SDKAppId,
*
* 進入騰訊云實時音視頻[控制臺](https://console.cloud.tencent.com/rav ) 創建應用,即可看到 SDKAppId,
* 它是騰訊云用于區分客戶的唯一標識,
*/
var SDKAPPID = _SDKAPPID;
/**
* 簽名過期時間,建議不要設定的過短
* <p>
* 時間單位:秒
* 默認時間:7 x 24 x 60 x 60 = 604800 = 7 天
*/
var EXPIRETIME = 604800;
/**
* 計算簽名用的加密密鑰,獲取步驟如下:
*
* step1. 進入騰訊云實時音視頻[控制臺](https://console.cloud.tencent.com/rav ),如果還沒有應用就創建一個,
* step2. 單擊“應用配置”進入基礎配置頁面,并進一步找到“帳號體系集成”部分,
* step3. 點擊“查看密鑰”按鈕,就可以看到計算 UserSig 使用的加密的密鑰了,請將其拷貝并復制到如下的變數中
*
* 注意:該方案僅適用于除錯Demo,正式上線前請將 UserSig 計算代碼和密鑰遷移到您的后臺服務器上,以避免加密密鑰泄露導致的流量盜用,
* 檔案:https://cloud.tencent.com/document/product/647/17275#Server
*/
var SECRETKEY = _SECRETKEY;
var generator = new __WEBPACK_IMPORTED_MODULE_0__lib_generate_test_usersig_es_min_js__["a" /* default */](SDKAPPID, SECRETKEY, EXPIRETIME);
var userSig = generator.genTestUserSig(userID);
return {
sdkappid: SDKAPPID,
userSig: userSig
};
}
/***/ })
});
好家伙你倒是用了Vue模板去搞,我要是不用Vue,你讓我原生js怎么去引,怎么去用,他娘的,這算是第二個坑了嘛,又開始網搜,最后的最后,我們下在的demo源檔案發揮大作用了

這個檔案路徑下面有兩個js檔案

把這兩個甩到專案里去再去參考這個 GenerateTestUserSig.js 檔案,他是好孩子,是原生的
參考
import { genTestUserSig } from '../../utils/GenerateTestUserSig'
輸出
onl oad:function(){
console.log(genTestUserSig('TEST-1'));
},
列印

乖乖 , 總算是有了,至此第二個坑踩完了(這里我要吐槽一下開發檔案,你他娘的有原生的就不能告知一下?非要人自己去找)
接下來登錄(注意:userID必須是字串型別)
login_TIM() {//登錄im實時聊天
let promise = this.tim.login({userID: 'TEST-1', userSig: genTestUserSig('TEST-1').userSig});
promise.then(function(imResponse) {
console.log(imResponse.data); // 登錄成功
if (imResponse.data.repeatLogin === true) {
// 標識賬號已登錄,本次登錄操作為重復登錄,v2.5.1 起支持
console.log(imResponse.data.errorInfo);
}
}).catch(function(imError) {
console.warn('login error:', imError); // 登錄失敗的相關資訊
});
},

OJBK ! 成了,總算了給他登進去了
--------更新割----------
接下來就是收發訊息了,看了下檔案,這就比較簡單跑通了直接調介面,官方檔案還是寫得很通俗易懂了
// 發送文本訊息,Web 端與小程式端相同
// 1. 創建訊息實體,介面回傳的實體可以上屏
let message = tim.createTextMessage({
to: 'user1',
conversationType: TIM.TYPES.CONV_C2C,
// 訊息優先級,用于群聊(v2.4.2起支持),如果某個群的訊息超過了頻率限制,后臺會優先下發高優先級的訊息,詳細請參考:https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
// 支持的列舉值:TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL(默認), TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
// priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
payload: {
text: 'Hello world!'
}
});
// 2. 發送訊息
let promise = tim.sendMessage(message);
promise.then(function(imResponse) {
// 發送成功
console.log(imResponse);
}).catch(function(imError) {
// 發送失敗
console.warn('sendMessage error:', imError);
});
執行后列印如下

然后看看我在收訊息的那方獲取到的資訊(這里是通過最開始 tim.on(TIM.EVENT.MESSAGE_RECEIVED, function(event) {}所監聽到的事件)

當然還有發送圖片訊息,音頻訊息,檔案訊息等等,官方檔案還是寫得很清楚,也沒碰到什么坑,所以我就不一一列出了.至此騰訊im主要的功能算是完全跑通了,接下來就是按照自己的專案需求繼續開發了.然后我將整個騰訊IM的初始化/登錄/發送訊息等都放到了一個js檔案中,這里就貼上來供大家參考下:
const app = getApp() //獲取APP.js便于設定操作全域變數
import TIM from '../tim-wx-sdk/tim-wx';
import { genTestUserSig } from '../tim-wx-sdk/GenerateTestUserSig'
var tim = '';
function init_TIM() {//初始化im實時聊天
if(app.globalData_TIM.isInit){
//這里設定了一個全域變數isLogin來標記是否已登錄,避免重復創建im實體
return false
}
let options = {
SDKAppID: 0// 接入時需要將0替換為您的即時通信 IM 應用的 SDKAppID
};
let that = this
// 創建 SDK 實體,`TIM.create()`方法對于同一個 `SDKAppID` 只會回傳同一份實體
tim = TIM.create(options);// SDK 實體通常用 tim 表示
// 設定 SDK 日志輸出級別,詳細分級請參見 setLogLevel 介面的說明
tim.setLogLevel(0); // 普通級別,日志量較多,接入時建議使用
// tim.setLogLevel(1); // release 級別,SDK 輸出關鍵資訊,生產環境時建議使用
// 注冊 COS SDK 插件 此處暫時隱藏有需求要傳圖片,檔案等的請放開進行配置,記住頭部引入
// tim.registerPlugin({'cos-wx-sdk': COS})
// 監聽事件,例如:
tim.on(TIM.EVENT.SDK_READY, function(event) {
// 收到離線訊息和會話串列同步完畢通知,接入側可以呼叫 sendMessage 等需要鑒權的介面
// event.name - TIM.EVENT.SDK_READY
});
tim.on(TIM.EVENT.MESSAGE_RECEIVED, function(event) {
console.log('收到訊息');
// 收到推送的單聊、群聊、群提示、群系統通知的新訊息,可通過遍歷 event.data 獲取訊息串列資料并渲染到頁面
// event.name - TIM.EVENT.MESSAGE_RECEIVED
// event.data - 存盤 Message 物件的陣列 - [Message]
});
tim.on(TIM.EVENT.MESSAGE_REVOKED, function(event) {
// 收到訊息被撤回的通知
// event.name - TIM.EVENT.MESSAGE_REVOKED
// event.data - 存盤 Message 物件的陣列 - [Message] - 每個 Message 物件的 isRevoked 屬性值為 true
});
tim.on(TIM.EVENT.MESSAGE_READ_BY_PEER, function(event) {
// SDK 收到對端已讀訊息的通知,即已讀回執,使用前需要將 SDK 版本升級至 v2.7.0 或以上,僅支持單聊會話,
// event.name - TIM.EVENT.MESSAGE_READ_BY_PEER
// event.data - event.data - 存盤 Message 物件的陣列 - [Message] - 每個 Message 物件的 isPeerRead 屬性值為 true
});
tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATED, function(event) {
// 收到會話串列更新通知,可通過遍歷 event.data 獲取會話串列資料并渲染到頁面
// event.name - TIM.EVENT.CONVERSATION_LIST_UPDATED
// event.data - 存盤 Conversation 物件的陣列 - [Conversation]
});
tim.on(TIM.EVENT.GROUP_LIST_UPDATED, function(event) {
// 收到群組串列更新通知,可通過遍歷 event.data 獲取群組串列資料并渲染到頁面
// event.name - TIM.EVENT.GROUP_LIST_UPDATED
// event.data - 存盤 Group 物件的陣列 - [Group]
});
tim.on(TIM.EVENT.PROFILE_UPDATED, function(event) {
// 收到自己或好友的資料變更通知
// event.name - TIM.EVENT.PROFILE_UPDATED
// event.data - 存盤 Profile 物件的陣列 - [Profile]
});
tim.on(TIM.EVENT.BLACKLIST_UPDATED, function(event) {
// 收到黑名單串列更新通知
// event.name - TIM.EVENT.BLACKLIST_UPDATED
// event.data - 存盤 userID 的陣列 - [userID]
});
tim.on(TIM.EVENT.ERROR, function(event) {
// 收到 SDK 發生錯誤通知,可以獲取錯誤碼和錯誤資訊
// event.name - TIM.EVENT.ERROR
// event.data.code - 錯誤碼
// event.data.message - 錯誤資訊
});
tim.on(TIM.EVENT.SDK_NOT_READY, function(event) {
// 收到 SDK 進入 not ready 狀態通知,此時 SDK 無法正常作業
// event.name - TIM.EVENT.SDK_NOT_READY
});
tim.on(TIM.EVENT.KICKED_OUT, function(event) {
// 收到被踢下線通知
// event.name - TIM.EVENT.KICKED_OUT
// event.data.type - 被踢下線的原因,例如:
// - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多實體登錄被踢
// - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多終端登錄被踢
// - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 簽名過期被踢 (v2.4.0起支持),
});
tim.on(TIM.EVENT.NET_STATE_CHANGE, function(event) {
// 網路狀態發生改變(v2.5.0 起支持),
// event.name - TIM.EVENT.NET_STATE_CHANGE
// event.data.state 當前網路狀態,列舉值及說明如下:
// \- TIM.TYPES.NET_STATE_CONNECTED - 已接入網路
// \- TIM.TYPES.NET_STATE_CONNECTING - 連接中,很可能遇到網路抖動,SDK 在重試,接入側可根據此狀態提示“當前網路不穩定”或“連接中”
// \- TIM.TYPES.NET_STATE_DISCONNECTED - 未接入網路,接入側可根據此狀態提示“當前網路不可用”,SDK 仍會繼續重試,若用戶網路恢復,SDK 會自動同步訊息
});
app.globalData_TIM.isInit = true; //完成im實體創建后設定標志為true
}
function login_TIM(userID) {//登錄im實時聊天
let promise = tim.login({userID: userID, userSig: genTestUserSig(userID).userSig});
promise.then(function(imResponse) {
console.log('登錄成功')
console.log(imResponse.data); // 登錄成功
if (imResponse.data.repeatLogin === true) {
// 標識賬號已登錄,本次登錄操作為重復登錄,v2.5.1 起支持
console.log('當前重復登錄')
console.log(imResponse.data.errorInfo);
}
}).catch(function(imError) {
console.warn('login error:', imError); // 登錄失敗的相關資訊
});
}
function sendMessage_TIM( sendTo , msg ) {
//這里是文字訊息的發送,有需求可以增加個type引數控制發送方式,文字/圖片/音視頻/檔案 呼叫不同的tim介面
let message = tim.createTextMessage({
to: sendTo,
conversationType: TIM.TYPES.CONV_C2C,
payload: {
text: msg
}
});
let promise = tim.sendMessage(message);
promise.then(function(imResponse) {
// 發送成功
console.log('發送成功')
console.log(imResponse);
}).catch(function(imError) {
// 發送失敗
console.log('發送失敗')
console.warn('sendMessage error:', imError);
});
}
function logout_TIM() {
let promise = tim.logout();
promise.then(function(imResponse) {
console.log(imResponse.data); // 登出成功
}).catch(function(imError) {
console.warn('logout error:', imError);
});
}
//匯出初始化,登錄,訊息發送介面供外部使用
module.exports = {
init_TIM,
login_TIM,
logout_TIM,
sendMessage_TIM
}
在需要使用的頁面通過以下方式使用
const app = getApp()
//頭部參考
import { init_TIM,login_TIM,sendMessage_TIM,logout_TIM } from '../../../js/tim-init';
Page({
data: {
userID: ''
},
onLoad() {
init_TIM();//在需要的頁面初始化
},
loginTim() {
login_TIM(this.data.userID);//根據頁面需求登錄并傳入登錄userID
},
logoutTim() {
logout_TIM();//根據頁面需求登出
},
sendMessage() {
sendMessage_TIM(sendTo ,msg) //sendTo為資訊接受者的userID , msg為訊息資料
}
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/212435.html
標籤:其他
上一篇:天貓雙十一成交額突破3723億元
