最近把Vue+Element二次封裝持續完善了,而後開始着手處理即時通信這一塊了。html
以前的老代碼用的是融雲2.x版本,如今4.x了,天然要更新下,融雲4.x變化仍是挺大的,不少API都換掉了,可是相對來說仍是比較簡單上手的。前端
因爲沒有原型圖,我直接邊設計辦coding,對於這種本身發揮的需求,我仍然保持微笑。(這應該是對我審美的確定吧!)先整了個樣圖出來以下git
高處不勝寒,起舞弄清影。github
接下來我們步入正題npm
項目是一個社交APP的後臺管理項目,項目中有個模塊是關於聊天室的,連接APP內的聊天大廳,若是有用戶發佈不良信息,能夠禁言用戶,同時也能夠發佈公告消息。後端
融雲提供的即時通信服務,不須要在 App 以外創建並行的用戶體系,不用同步 App 下用戶信息到融雲,不影響 App 現有的系統架構與賬號體系,與現有業務體系可以實現完美融合。瀏覽器
Chrome | Firefox | Safari | IE | Edge | QQ 瀏覽器 | 微信 瀏覽器 | Android |
---|---|---|---|---|---|---|---|
✔ | ✔ | ✔ | 9+ | ✔ | ✔ | ✔ | ✔ |
融雲 4.x 底層使用 Typescript 進行了重構,對 Typescript 的使用者提供了友好的類型化支持,推薦開發者使用 Typescript 進行業務開發以提高代碼健壯性及可維護性。服務器
npm install @rongcloud/imlib-v4
複製代碼
// 非 ESModule
const RongIMLib = require('@rongcloud/imlib-v4')
// ESModule
import * as RongIMLib from '@rongcloud/imlib-v4'
複製代碼
index.html
<script src="https://cdn.ronghub.com/RongIMLib-4.3.latest.js"></script>
複製代碼
App Key
是使用 IMLib 進行即時通信功能開發的必要條件,也是應用的惟一性標識。在集成使用 IMLib
以前,請務必先經過 融雲開發者後臺 (opens new window)註冊並獲取開發者的專屬 App Key
。微信
只有在 App Key 相同的狀況下,不一樣用戶之間的消息纔有可能互通。markdown
IMLib 提供的全部能力基於 IMLib 初始化後獲取的實例對象,所以在使用 IMLib 的能力以前,必須先調用 IMLib 的初始化接口,且務必保證該接口在應用全生命週期內僅被調用一次。
// 應用初始化以獲取 RongIMLib 實例對象,請務必保證此過程只被執行一次
const im = RongIMLib.init({ appkey: '<Your-App-Key>' });
複製代碼
後續全部代碼示例中的 im 均指經過初始化獲取到的 RongIMLib 實例對象
初始化完成後,應在創建鏈接以前對 im 對象添加事件監聽器,及時獲取相關事件通知。
// 添加事件監聽
im.watch({
// 監聽會話列表變動事件
conversation (event) {
// 假定存在 getExistedConversationList 方法,以獲取當前已存在的會話列表數據
const conversationList = getExistedConversationList()
// 發生變動的會話列表
const updatedConversationList = event.updatedConversationList;
// 經過 im.Conversation.merge 計算最新的會話列表
const latestConversationList = im.Conversation.merge({ conversationList, updatedConversationList })
},
// 監聽消息通知
message (event) {
// 新接收到的消息內容
const message = event.message;
},
// 監聽 IM 鏈接狀態變化
status (event) {
console.log('connection status:', event.status);
},
// 監聽聊天室 KV 數據變動
chatroom (event) {
/** * 聊天室 KV 存儲數據更新 * @example * [ * { * "key": "name", * "value": "我是小融融", * "timestamp": 1597591258338, * "chatroomId": "z002", * "type": 1 // 1: 更新( 含:修改和新增 )、2: 刪除 * }, * ] */
const updatedEntries = event.updatedEntries
},
expansion (event) {
/** * 更新的消息拓展數據 * @example { * expansion: { key: 'value' }, // 設置或更新的擴展值 * messageUId: 'URIT-URIT-ODMF-DURR' // 設置或更新擴展的消息 uid * } */
const updatedExpansion = event.updatedExpansion;
/** * 刪除的消息拓展數據 * @example { * deletedKeys: ['key1', 'key2'], // 設置或更新的擴展值 * messageUId: 'URIT-URIT-ODMF-DURR' // 設置或更新擴展的消息 uid * } */
const deletedExpansion = event.deletedExpansion;
});
複製代碼
App Key
是應用的惟一性標識,Token
則是用戶的惟一性標識,是用戶鏈接融雲 IM
服務所必需的身份憑證。Token
通常由開發者的應用服務器調用融雲 Server API
獲取 Token 接口獲取以後,由應用服務器下發到應用客戶端。
個人這個token是從後端獲取的,而後存儲到本地,用的時候看看過時沒,過時了就從新獲取。至關於前端只進行部分交互。
// 獲取token
getIMToken() {
getIMToken().then(res => {
var time = new Date().getTime()
res.time = time
// 將token保存下來
this.gobalToken = res
var tokenStr = JSON.stringify(res)
localStorage.setItem('token', tokenStr)
// 初始化融雲
this.linkToRongs(res.data)
})
},
// 判斷token是否過時
isToken() {
var now = new Date().getTime()
// 獲取上一次存儲的token
var oldToken = JSON.parse(localStorage.getItem('token'))
// 判斷以前獲取的token
if (oldToken) {
var tokenTime = oldToken.time
// 判斷時間是否過時了
if (now - tokenTime > 29 * 24 * 60 * 60 * 1000) {
this.getIMToken()
} else {
this.gobalToken = JSON.parse(localStorage.getItem('token'))
this.linkToRongs(this.gobalToken.data)
return
}
}
this.getIMToken()
}
複製代碼
im.connect({ token: '<Your-Token>' }).then(user => {
console.log('連接成功, 連接用戶 id 爲: ', user.id);
}).catch(error => {
console.log('連接失敗: ', error.code, error.msg);
});
複製代碼
Web 端不具有持久化的數據存儲能力,須要開發者開啓 IM 商用版 - 單羣聊雲存儲 (opens new window)功能才能生效。 該功能須要在調用
im.connect()
而且創建鏈接成功以後執行。
IMLib
經過會話數據中的 conversationType
與 targetId
兩個屬性值來標識會話的惟一性,對於兩個屬性的定義以下:
conversationType
用來標識會話類型(如:單聊、羣聊...),其值爲 RongIMLib.CONVERSATION_TYPE
中的常量定義targetId
用來標識與本端進行對話的人員或羣組 Id:conversationType
值爲 RongIMLib.CONVERSATION_TYPE.PRIVATE,targetId 爲對方用戶 IdconversationType
值爲 RongIMLib.CONVERSATION_TYPE.GROUP,targetId 爲當前羣組 IdconversationType
值爲 RongIMLib.CONVERSATION_TYPE.CHATROOM,targetId 爲聊天室 Id// 獲取會話列表
im.Conversation.getList().then(conversationList => {
console.log('獲取會話列表成功', conversationList);
}).catch(error => {
console.log('獲取會話列表失敗: ', error.code, error.msg);
});
複製代碼
該功能須要在調用
im.connect()
而且創建鏈接成功以後執行。 IMLib 內置消息類型可經過 RongIMLib.MESSAGE_TYPE 獲取其常量定義
// 獲取指定會話的抽象實例,對於會話的操做基於此實例完成
const conversation = im.Conversation.get({
// targetId
targetId: '<TargetId>',
// 會話類型:RongIMLib.CONVERSATION_TYPE.PRIVATE | RongIMLib.CONVERSATION_TYPE.GROUP
type: '<Conversation-Type>'
});
// 向會話內發消息
conversation.send({
// 消息類型,其中 RongIMLib.MESSAGE_TYPE 爲 IMLib 內部的內置消息類型常量定義
messageType: RongIMLib.MESSAGE_TYPE.TEXT, // 'RC:TxtMsg'
// 消息內容
content: {
content: 'Hello RongCloud' // 文本內容
}
}).then(function(message){
console.log('發送文字消息成功', message);
}).catch(error => {
console.log('發送文字消息失敗', error.code, error.msg);
});
複製代碼
當本端做爲消息接收的一方,所接收的消息將經過 im.watch()
註冊的消息監聽向業務層拋出。具體可參考上述 設置監聽 部分
Web 端不具有持久化的數據存儲能力,須要開發者開啓 IM 商用版 - 單羣聊雲存儲 (opens new window)功能才能生效。 該功能須要在調用 im.connect() 而且創建鏈接成功以後執行。
const conversation = im.Conversation.get({
targetId: '<TargetId>',
type: '<Conversation-Type>'
});
const option = {
// 獲取歷史消息的時間戳,默認爲 0,表示從當前時間獲取
timestamp: +new Date(),
// 獲取條數,有效值 1-20,默認爲 20
count: 20,
};
conversation.getMessages(option).then(result => {
const list = result.list; // 獲取到的消息列表
const hasMore = result.hasMore; // 是否還有歷史消息可獲取
console.log('獲取歷史消息成功', list, hasMore);
}).catch(error => {
console.log('發送文字消息失敗', error.code, error.msg);
});
複製代碼
斷開當前用戶鏈接,鏈接斷開後沒法接收消息、發送消息、獲取歷史消息、獲取會話列表... 在下次鏈接融雲成功後,會收取上次離線後的消息,離線消息默認保存 7 天。
im.disconnect().then(() => console.log('斷開連接成功'));
複製代碼
created() {
this.isToken()
}
methods:{
// 獲取token
getIMToken() {
getIMToken().then(res => {
var time = new Date().getTime()
res.time = time
// 將token保存下來
this.gobalToken = res
var tokenStr = JSON.stringify(res)
localStorage.setItem('token', tokenStr)
// 初始化融雲
this.linkToRongs(res.data)
})
},
// 判斷token是否過時
isToken() {
var now = new Date().getTime()
// 獲取上一次存儲的token
var oldToken = JSON.parse(localStorage.getItem('token'))
// 判斷以前獲取的token
if (oldToken) {
var tokenTime = oldToken.time
// 判斷時間是否過時了
if (now - tokenTime > 29 * 24 * 60 * 60 * 1000) {
this.getIMToken()
} else {
this.gobalToken = JSON.parse(localStorage.getItem('token'))
this.linkToRongs(this.gobalToken.data)
return
}
}
this.getIMToken()
},
}
複製代碼
通常測試服一個appkey
,正式服一個appkey
。這個appkey
須要本身去申請
// 連接融雲
linkToRongs(token) {
const that = this
let RongClientKey
if (process.env.VUE_APP_BASE_API2 === '') {//測試服
RongClientKey = '4215151sadasas'
} else {//正式服
RongClientKey = 'adsada12asda1a'
}
// 應用初始化以獲取 RongIMLib 實例對象,請務必保證此過程只被執行一次
// eslint-disable-next-line no-undef
that.rongyun = RongIMLib.init({ appkey: RongClientKey })
}
複製代碼
初始化完成後,應在創建鏈接以前對 im 對象添加事件監聽器,及時獲取相關事件通知。
// 連接融雲
linkToRongs(token) {
const that = this
let RongClientKey
if (process.env.VUE_APP_BASE_API2 === '') {//測試服
RongClientKey = '4215151sadasas'
} else {//正式服
RongClientKey = 'adsada12asda1a'
}
// 應用初始化以獲取 RongIMLib 實例對象,請務必保證此過程只被執行一次
// eslint-disable-next-line no-undef
that.rongyun = RongIMLib.init({ appkey: RongClientKey })
const im = that.rongyun
// 添加事件監聽
im.watch({
// 監聽會話列表變動事件
conversation(event) {
// 假定存在 getExistedConversationList 方法,以獲取當前已存在的會話列表數據
const conversationList = that.getExistedConversationList(im)
// 發生變動的會話列表
const updatedConversationList = event.updatedConversationList
// 經過 im.Conversation.merge 計算最新的會話列表
const latestConversationList = im.Conversation.merge({ conversationList, updatedConversationList })
console.log(latestConversationList)
},
// 監聽消息通知
message(event) {
//初始化消息都在這
// 新接收到的消息內容
const message = event.message
console.log(message)
},
// 監聽 IM 鏈接狀態變化
status(event) {
console.log('connection status:', event.status)
},
// 監聽聊天室 KV 數據變動
chatroom(event) {
const updatedEntries = event.updatedEntries
console.log('聊天室 KV 存儲數據更新', updatedEntries)
}
})
}
複製代碼
// 連接融雲
linkToRongs(token) {
const that = this
let RongClientKey
if (process.env.VUE_APP_BASE_API2 === '') {//測試服
RongClientKey = '4215151sadasas'
} else {//正式服
RongClientKey = 'adsada12asda1a'
}
// 應用初始化以獲取 RongIMLib 實例對象,請務必保證此過程只被執行一次
// eslint-disable-next-line no-undef
that.rongyun = RongIMLib.init({ appkey: RongClientKey })
const im = that.rongyun
// 添加事件監聽
im.watch({
// 監聽會話列表變動事件
conversation(event) {
// 假定存在 getExistedConversationList 方法,以獲取當前已存在的會話列表數據
const conversationList = that.getExistedConversationList(im)
// 發生變動的會話列表
const updatedConversationList = event.updatedConversationList
// 經過 im.Conversation.merge 計算最新的會話列表
const latestConversationList = im.Conversation.merge({ conversationList, updatedConversationList })
console.log(latestConversationList)
},
// 監聽消息通知
message(event) {
//初始化消息都在這
// 新接收到的消息內容
const message = event.message
console.log(message)
},
// 監聽 IM 鏈接狀態變化
status(event) {
console.log('connection status:', event.status)
},
// 監聽聊天室 KV 數據變動
chatroom(event) {
const updatedEntries = event.updatedEntries
console.log('聊天室 KV 存儲數據更新', updatedEntries)
}
})
// 創建 IM 鏈接
const chatRoomId = '627865222'
var count = 50 // 數量
im.connect({ token: token }).then(user => {
this.$message.success('加入聊天室成功')
console.log('連接成功, 連接用戶 id 爲: ', user.id)
var chatRoom = im.ChatRoom.get({
id: chatRoomId
})
chatRoom.join({
count: count // 進入後, 自動拉取 20 條聊天室最新消息
}).then(function() {
console.log('加入聊天室成功')
chatRoom.getInfo().then(function(result) {
var userCount = result.userCount
var user = that.uniq(that.messageList)
// 刷選用戶
user.map(item => {
that.list.push(item.user)
})
that.num = userCount
})
})
}).catch(error => {
this.$message.success('加入聊天室失敗')
console.log('連接失敗: ', error.code, error.msg)
})
}
複製代碼
切換頁面時,必定要退出聊天廳,否則下次加入聊天廳沒法獲取以前的消息。固然你也能夠獲取歷史消息,我嘗試獲取歷史消息一直報錯,因此才選擇打開頁面加入,結束就離開。(不退出的話會一直保持鏈接)
destroyed() {
var chatRoom = this.rongyun.ChatRoom.get({
id: '聊天室id'
})
chatRoom.quit().then(function() {
console.log('退出聊天室成功')
})
}
複製代碼
即時通信這一塊作起來仍是蠻有意思的,總有一些意料以外的事情發生。
生活中充滿各類驚喜,代碼世界亦是如此。
我是涼城a,一個前端,熱愛技術也熱愛生活。
與你相逢,我很開心。
文中若有錯誤,歡迎在評論區指正,若是這篇文章幫到了你,歡迎點贊和關注😊
本文首發於掘金,未經許可禁止轉載💌