概述
最近跟朋友做了一個小程序項目腰埂,用到了即時通訊,選擇了網(wǎng)易信Im即時通訊因妇,不得不說欲逃,網(wǎng)易信的文檔寫的相當不友好找蜜,文檔鏈接:https://dev.yunxin.163.com/docs/product/IM%E5%8D%B3%E6%97%B6%E9%80%9A%E8%AE%AF/%E6%96%B0%E6%89%8B%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
誰看誰懵逼。稳析。洗做。
長話短說弓叛,進入正題。
介紹:這里對接是小程序sdk版本
第一步
先去注冊網(wǎng)易信賬號建立應用诚纸,拿到appKey 邪码,appSecret。理解為小程序的appid就OK咬清,應用唯一標識碼
const appKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
const appSecret = "xxxxxxxxxxxx"
export default {
appKey,
appSecret
}
第二步
先把demo拷貝下來闭专,看看代碼,這個真的要看看旧烧,很有幫助影钉,地址:https://dev.yunxin.163.com/docs/product/IM%E5%8D%B3%E6%97%B6%E9%80%9A%E8%AE%AF/SDK%E5%BC%80%E5%8F%91%E9%9B%86%E6%88%90/Web%E5%BC%80%E5%8F%91%E9%9B%86%E6%88%90/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F
第三步
把文檔過一遍,不理解跟著我往下看
第四步
去控制臺打開自己的賬號建立幾個IM賬戶掘剪,注意這里是純前端實現(xiàn)平委,IM用戶體系來自網(wǎng)易信數(shù)據(jù)庫,不通過我們自己的服務端后臺夺谁,記住賬戶和密碼用來測試的
然后跟我寫下面代碼試試
import config from '@/im/config.js'
let orderCounter=1
class IMController {
constructor(headers) {
this.onConnect = this.onConnect.bind(this)
/* 初始化SDk */
app.globalData.nim = NIM.getInstance({
// debug: true,
db: false, // 小程序不支持數(shù)據(jù)庫
syncSessionUnread: true, // 同步會話的未讀數(shù)
autoMarkRead: false, // 不開啟自動標記消息已讀 此時服務器下推的所有離線消息算未讀廉赔,漫游消息算已讀
appKey: config.appKey, // 在云信管理后臺查看應用的 appKey
token: headers.token, // 帳號的唯一標識, 用于建立連接
account: headers.account, // 帳號, 應用內唯一
onconnect: this.onConnect, // 連接成功
})
}
/** 1 abnormal closure
* 連接成功
*/
onConnect() {
console.log(orderCounter++, '連接成功: ')
console.log(app.globalData.nim)
}
}
const appNim=new IMController({
token: '測試賬號密碼',
account: ‘測試賬號’
})
//下面是一段發(fā)送消息的方法
// 他人account
let to = this.otherParam.account
let text='測試消息'
appNim.sendText({
scene: 'p2p',
to,
text,
done: (err, msg) => {
console.log('發(fā)送文本消息回調')
console.log(err)
console.log(msg)
}
})
這樣一個Im賬號登錄連接就成功了,你可以把im類放在全局對象上以便使用,請繼續(xù)看下代碼匾鸥,它只是一個消息Mock
// 這里我只介紹幾個重點的字段及狀態(tài),
/*
* @param {string} flow 發(fā)送方 (‘out’=>自己) and (‘in’ =>他人)
* @param {string} fromNick 目標名稱
* @param {string} scene 聊天類型 ‘p2p’ 點對點
* @param {string} to 發(fā)送者賬戶
* @param {string} sessionId 會話id
* @param {number} time 發(fā)送時間
*
*/
export default {
cc: true,
flow: "out",
from: "19b82a32aa30c50fc4c943ff398dfcae",
fromClientType: "Web",
fromDeviceId: "f1cbf57270cfe916c270a842085ce75a",
fromNick: "woshichunlogn",
idClient: "0376a3107b0d200744be4c87523b7838",
idServer: "306034218126",
isHistoryable: true,
isLocal: false,
isOfflinable: true,
isPushable: true,
isReplyMsg: true,
isRoamingable: true,
isSyncable: true,
isUnreadable: true,
needMsgReceipt: false,
needPushNick: true,
resend: false,
scene: "p2p",
sessionId: "p2p-dc46c6ede64c2c7595f0246e8cd146a7",
status: "success",
target: "dc46c6ede64c2c7595f0246e8cd146a7",
text: "fasf",
time: 1566653977065,
to: "dc46c6ede64c2c7595f0246e8cd146a7",
type: "text",
userUpdateTime: 1566543003373,
}
看了各項字段應該已經(jīng)猜到對應的什么了吧蜡塌,如text消息文案,time發(fā)送時間勿负,scene點對點,等等馏艾,也可以自己去看看文檔。
這里我要講重點
離線消息與漫游消息
離線消息
只能拿到他人的消息列奴愉,漫游消息
需要在后臺管理開啟漫游琅摩,不然我們是拿不到漫游消息
的,漫游消息
指的是自己最近發(fā)送的消息列锭硼,當然會有本地庫存儲的房资,但是小程序里是不支持本地數(shù)據(jù)庫的,當然我也是第一次對接檀头,現(xiàn)在我的理解是這樣轰异,如有錯誤請指出。
會話
會話
指的是你最近跟某個用戶產生的一次對話鳖擒,他是有消息輸出的溉浙,如QQ會話列表,千萬不要把會話
跟消息弄混淆了蒋荚,會話包括消息或多個消息
第五步
看到這里,你也大概了解這個流程是怎么建立的馆蠕,你現(xiàn)在首要的任務是期升,寫好UI界面惊奇,然后把我上面登錄的方法調通,然后用實例發(fā)送一個消息播赁,看看真實的數(shù)據(jù)颂郎,在把官方給的demo模板里的回調方法一個一個抽出來,我把我的例子放出來如下,有些方法和模塊搜不到你不用管容为,因為這個都是邏輯層乓序,自己懂了之后,每個人才會有自己的實現(xiàn)方式坎背,當然我用的uni.app里的vuex....
import NIM from '@/vendors/NIM_Web_NIM_weixin_v6.7.0.js'
import NetcallController from './netcall.js'
import config from '@/im/config.js'
import store from '@/api/request/store/home.js' // 刪除本地緩存
import common from '@/common/common.js'
import { hexMD5, utf8 } from '@/utils/md5-utf8'
let app = getApp()
let orderCounter = 1
export default class IMController {
constructor(headers) {
// vuex對象賦給im類
this.store = headers.$store
this.onConnect = this.onConnect.bind(this)
this.onSessions = this.onSessions.bind(this)
this.onMsg = this.onMsg.bind(this)
this.onRoamingMsgs = this.onRoamingMsgs.bind(this)
this.onUpdateSession = this.onUpdateSession.bind(this)
this.onOfflineMsgs = this.onOfflineMsgs.bind(this)
this.onMyInfo = this.onMyInfo.bind(this)
/* 初始化SDk */
app.globalData.nim = NIM.getInstance({
// debug: true,
db: false, // 小程序不支持數(shù)據(jù)庫
syncSessionUnread: true, // 同步會話的未讀數(shù)
autoMarkRead: false, // 不開啟自動標記消息已讀 此時服務器下推的所有離線消息算未讀替劈,漫游消息算已讀
appKey: config.appKey, // 在云信管理后臺查看應用的 appKey
token: headers.token, // 帳號的唯一標識, 用于建立連接
account: headers.account, // 帳號, 應用內唯一
onconnect: this.onConnect, // 連接成功
onwillreconnect: this.onWillReconnect, // 斷開重連
ondisconnect: this.onDisconnect, // 丟失連接
onerror: this.onError, // onError
/* 收到onconnect后,鏈接已經(jīng)建立(登錄成功), SDK會開始同步數(shù)據(jù), 在收到onsyncdone回調后表示SDK完成了數(shù)據(jù)同步工作, 此時開發(fā)者可以進行渲染 UI 等操作了得滤。*/
onsyncdone: this.onSyncDone,
// 用戶名片
onmyinfo: this.onMyInfo, // 同步登錄用戶資料的回調, 會傳入用戶資料
// onupdatemyinfo: this.onUpdateMyInfo, // 當前登錄用戶在其它端修改自己的個人名片之后的回調, 會傳入用戶資料
onusers: this.onUsers, // 同步好友用戶資料的回調, 會傳入用戶資料數(shù)組 此回調是增量回調, 可以調用nim.mergeUsers來合并數(shù)據(jù)
// onupdateuser: this.onUpdateUser, // 用戶資料更新后的回調, 會傳入用戶資料陨献,請參考用戶資料更新時機
// // 機器人列表的回調
// onrobots: this.onRobots, // 機器人列表事件
// // 會話
onsessions: this.onSessions, // 同步最近會話列表回調, 會傳入會話列表, 按時間正序排列, 即最近聊過天的放在列表的最后面 此回調是增量回調, 可以調用nim.mergeSessions來合并數(shù)據(jù)
onupdatesession: this.onUpdateSession, // 更新會話的回調, 會傳入會話對象, 以下情況會收到此回調 收到消息 發(fā)送消息 設置當前會話 重置會話未讀數(shù)
// // 消息
onroamingmsgs: this.onRoamingMsgs, // 漫游消息, 對應回調
onofflinemsgs: this.onOfflineMsgs, // 離線消息, 對應回調
onmsg: this.onMsg, // 收到消息
// // 系統(tǒng)通知
// onofflinesysmsgs: this.onOfflineSysMsgs, // 同步離線系統(tǒng)通知的回調, 會傳入系統(tǒng)通知數(shù)組
// onsysmsg: this.onSysMsg, // 收到系統(tǒng)通知的回調, 會傳入系統(tǒng)通知
// onsysmsgunread: this.onSysMsgUnread, // 收到系統(tǒng)通知未讀數(shù)的回調
// onupdatesysmsgunread: this.onUpdateSysMsgUnread, // 更新系統(tǒng)通知未讀數(shù)的回調
// onofflinecustomsysmsgs: this.onOfflineCustomSysMsgs, // 同步離線自定義系統(tǒng)通知的回調, 會傳入系統(tǒng)通知數(shù)組
// oncustomsysmsg: this.onCustomSysMsg, // 收到自定義系統(tǒng)通知的回調, 會傳入系統(tǒng)通知
// // 收到廣播消息
// onbroadcastmsg: this.onBroadcastMsg,
// onbroadcastmsgs: this.onBroadcastMsgs,
// // 事件訂閱
// onpushevents: this.onPushEvents,
})
// 發(fā)送消息開始登陸
// store.dispatch({
// type: 'Login_StartLogin'
// })
}
/** 1 abnormal closure
* 連接成功
*/
onConnect() {
console.log(orderCounter++, '連接成功: ')
console.log(app.globalData.nim)
app.globalData.netcallController = new NetcallController({
// debug: false,
debug: true,
nim: app.globalData.nim,
store: this.store
})
}
/**
* 連接出錯
*/
onError(error) {
console.log('連接出錯')
common.msgHint()
toLogin()
}
/**
* 此時說明 SDK 處于斷開狀態(tài), 開發(fā)者此時應該根據(jù)錯誤碼提示相應的錯誤信息, 并且跳轉到登錄頁面
*/
onDisconnect(error) {
console.log('丟失連接');
if (error) {
switch (error.code) {
// 賬號或者密碼錯誤, 請?zhí)D到登錄頁面并提示錯誤
case 302:
common.msgHint({
title: 'im的賬戶或密碼錯誤,需重新登錄'
})
toLogin()
break;
// 重復登錄, 已經(jīng)在其它端登錄了, 請?zhí)D到登錄頁面并提示錯誤
case 417:
common.msgHint({
title: '已經(jīng)在其它端登錄了'
})
toLogin()
break;
// 被踢, 請?zhí)崾惧e誤后跳轉到登錄頁面
case 'kicked':
common.msgHint({
title: '你被一名用戶踢了'
})
toLogin()
break;
default:
break;
}
}
}
/** 1 abnormal closure
* 斷線重連
*/
onWillReconnect(obj) {
// 此時說明 SDK 已經(jīng)斷開連接, 請開發(fā)者在界面上提示用戶連接已斷開, 而且正在重新建立連接
console.log('斷線重連');
common.msgHint({
title: '斷線重連中懂更,請稍后眨业!',
duration: 3000
})
}
/** 6
* 個人名片:存儲個人信息到全局數(shù)據(jù)
*/
onMyInfo(user) {
console.log(orderCounter++, ' 個人信息: ')
console.log(user)
if (user) {
this.store.commit('setMyImData', user)
}
}
/** 7
* 包含名片的好友信息(可能某些字段不全),[{account,avatar,birth,createTime,email,gender,nick,sign,updateTime}]
*/
onUsers(friends) {
console.log(orderCounter++, ' 好友信息: ')
console.log(friends)
}
/** 9
* 同步完成
*/
onSyncDone() {
console.log(orderCounter++, '同步完成')
}
/**會話
* [ {id:"p2p-liuxuanlin",lastMsg:{from:'wujie',text:'222',to:"liuxuanlin"}} ]
*/
onSessions(session) {
console.log('會話: ')
console.log(session)
if (session) {
// 會話列表
let chatList = JSON.parse(JSON.stringify(this.store.state.chatList || []))
// 合并會話列表
let list = app.globalData.nim.mergeSessions(chatList, session);
}
}
/**
* 會話更新:收到消息沮协、發(fā)送消息龄捡、設置當前會話、重置會話未讀數(shù) 觸發(fā)
* {id:'p2p-zys2',lastMsg:{},scene,to,unread,updateTime}
* {id:'team-1389946935',lastMsg:{attach:{accounts,team},type,users},scene,to,from,type,unread,updateTime}
*/
onUpdateSession(session) {
console.log('會話更新: ', session)
if (session) {
// 更新會話列表
app.globalData.netcallController.mergeChatList(session)
}
}
/**
* 收到消息
* {cc,flow:"in",from,fromClientType:"Web",fromDeviceId,fromNick,idClient,idServer:"9680840912",isHistoryable:true,isLocal,isMuted, isOfflinable,isPushable,isRoamingable,isSyncable,isUnreadable,needPushNick,resend,scene:"p2p",sessionId:"p2p-zys2",status:"success",target:"zys2",text:"[嘔吐]",time,to:"wujie",type:"text",userUpdateTime}
*/
onMsg(msg) {
console.log('收到消息', msg.scene, msg.type);
console.log(msg);
if (msg) {
// 更新消息列表
app.globalData.netcallController.mergeMsg(msg)
}
}
/**
* 漫游消息:會多次收到慷暂,每次只會收到指定人的漫游消息
// {scene:"p2p",sessionId:"p2p-cs4",timetag:1513153729257,to:"cs4",msg:[{from:'wujie',text:'222',to:'cs4'}]}
// {scene:"team",sessionId:"team-3944051",timetag:1513153729257,to:"3944051",msg:[{from:'wujie',text:'222',to:'cs4'}]}
*/
onRoamingMsgs(session) {
console.log(orderCounter++, ' 漫游消息')
console.log(session)
if (session) {
// 合并漫游消息列表
app.globalData.netcallController.mergeMsgList(session)
}
}
/**
* 會話離線消息 拿到每條會話的消息列表
*/
onOfflineMsgs(session) {
console.log(orderCounter++, ' 會話離線消息')
console.log(session)
if (session) {
// 合并離線消息列表
app.globalData.netcallController.mergeMsgList(session)
}
}
}
let toLogin = res => {
setTimeout(() => {
// 刪除本地緩存
store.clear()
uni.reLaunch({
url: '/pages/login/index'
})
}, 1000)
}
我是個懶人墅茉,~~喜歡把知識放在腦子里,寫了這么多累了呜呐,有什么需要咨詢的可以私信給我哦就斤,bey