Vue集成融雲實現即時通信聊天室

前言

最近把Vue+Element二次封裝持續完善了,而後開始着手處理即時通信這一塊了。html

以前的老代碼用的是融雲2.x版本,如今4.x了,天然要更新下,融雲4.x變化仍是挺大的,不少API都換掉了,可是相對來說仍是比較簡單上手的。前端

因爲沒有原型圖,我直接邊設計辦coding,對於這種本身發揮的需求,我仍然保持微笑。(這應該是對我審美的確定吧!)先整了個樣圖出來以下git

融雲2.png

高處不勝寒,起舞弄清影。github

接下來我們步入正題npm

分析需求

項目是一個社交APP的後臺管理項目,項目中有個模塊是關於聊天室的,連接APP內的聊天大廳,若是有用戶發佈不良信息,能夠禁言用戶,同時也能夠發佈公告消息。後端

任務

  1. 獲取token,連接融雲
  2. 獲取歷史消息並模擬聊天展現出來
  3. 發送消息,這個是由後端完成,我發送消息就請求接口
  4. 能夠禁言用戶,這個也是由後端來統一完成

關於融雲

融雲提供的即時通信服務,不須要在 App 以外創建並行的用戶體系,不用同步 App 下用戶信息到融雲,不影響 App 現有的系統架構與賬號體系,與現有業務體系可以實現完美融合。瀏覽器

兼容說明

Chrome Firefox Safari IE Edge QQ 瀏覽器 微信 瀏覽器 Android
9+

導入 SDK

融雲 4.x 底層使用 Typescript 進行了重構,對 Typescript 的使用者提供了友好的類型化支持,推薦開發者使用 Typescript 進行業務開發以提高代碼健壯性及可維護性。服務器

NPM 引入(推薦)

  1. 依賴安裝
npm install @rongcloud/imlib-v4
複製代碼
  1. 代碼集成
// 非 ESModule
const RongIMLib = require('@rongcloud/imlib-v4')
// ESModule
import * as RongIMLib from '@rongcloud/imlib-v4'
複製代碼

CDN 引入

  • index.html
<script src="https://cdn.ronghub.com/RongIMLib-4.3.latest.js"></script>
複製代碼

App Key

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

複製代碼

創建 IM 鏈接

App Key 是應用的惟一性標識,Token 則是用戶的惟一性標識,是用戶鏈接融雲 IM 服務所必需的身份憑證。Token 通常由開發者的應用服務器調用融雲 Server API 獲取 Token 接口獲取以後,由應用服務器下發到應用客戶端。

個人這個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 經過會話數據中的 conversationTypetargetId 兩個屬性值來標識會話的惟一性,對於兩個屬性的定義以下:

  1. conversationType 用來標識會話類型(如:單聊、羣聊...),其值爲 RongIMLib.CONVERSATION_TYPE 中的常量定義
  2. targetId 用來標識與本端進行對話的人員或羣組 Id:
  • conversationType 值爲 RongIMLib.CONVERSATION_TYPE.PRIVATE,targetId 爲對方用戶 Id
  • conversationType 值爲 RongIMLib.CONVERSATION_TYPE.GROUP,targetId 爲當前羣組 Id
  • conversationType 值爲 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('斷開連接成功'));
複製代碼

實戰運用

token拿到手,往前走一走

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()
    },
}
複製代碼

init初始化,話話道心好好聽

通常測試服一個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)
        }
      })
}
複製代碼

連接融雲先用key,長驅直入無人攔

// 連接融雲
 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('退出聊天室成功')
    })
  }
複製代碼

結尾

即時通信這一塊作起來仍是蠻有意思的,總有一些意料以外的事情發生。

生活中充滿各類驚喜,代碼世界亦是如此。

最後把源碼放在了github

融雲官方文檔

寫在最後

我是涼城a,一個前端,熱愛技術也熱愛生活。

與你相逢,我很開心。

若是你想了解更多,請點這裏,期待你的小⭐⭐

  • 文中若有錯誤,歡迎在評論區指正,若是這篇文章幫到了你,歡迎點贊和關注😊

  • 本文首發於掘金,未經許可禁止轉載💌

相關文章
相關標籤/搜索