由於有同窗問了我下融雲怎麼寫聊天的問題,我才瞭解到有融雲這麼個東西,嘗試着學了下。主要介紹了vue中使用vue-cli接入融雲實現即時通訊的相關資料,本文經過實例代碼給你們介紹的很是詳細,具備必定的參考借鑑價值,須要的朋友能夠參考下... 我的博客javascript
本文章 Demo 源碼 star 哦 拿下來能夠直接跑css
Flutter 項目 star 哦 這是本人打算長期更新的一個項目html
在寫代碼以前咱們首先要 註冊融雲,註冊融雲後拿到 appkey 和融雲提供的 tokenvue
拿到 appkey 和 token 後記得保存下來java
能夠使用下列任一命令安裝這個新的包:git
$ npm install -g @vue/cli
# OR
$ yarn global add @vue/cli
複製代碼
運行如下命令來建立一個新項目:github
$ vue create hello-world
# OR
$ vue ui // UI 界面建立項目
複製代碼
你會被提示選取一個 prese 由於咱們這個項目用到了 VUEX 因此咱們選擇手動選擇特性來選取須要的特性來避免後續的的麻煩web
除了默認選項 咱們須要選擇 Router
和 Vuex
vuex
等項目建立完畢後大概是這個樣子vue-cli
首先咱們進入根目錄的 public
目錄下的 index.html
這個位置引入融雲 SDK
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>im</title>
</head>
<body>
<noscript>
<strong>We're sorry but im doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script src="https://cdn.ronghub.com/RongIMLib-2.5.0.min.js"></script>
<!-- built files will be auto injected -->
</body>
</html>
複製代碼
src
下建立幾個文件 名字隨意你們能夠自行建立utils.js
scss
目錄 在此目錄建立一個 utils.scss
(這個文件並不重要只是爲了自適應)scr
目錄下建立 init.vue
src
目錄下建立 RongCloud.vue
src
目錄下建立 Message.vue
utils.js
此文件是對融雲的初始化操做
export const init = (params, addPromptInfo) => {
var appkey = params.appkey
var token = params.token
RongIMClient.init(appkey)
RongIMClient.setConnectionStatusListener({
onChanged: function (status) {
switch (status) {
case RongIMLib.ConnectionStatus['CONNECTED']:
case 0:
addPromptInfo('鏈接成功')
break
case RongIMLib.ConnectionStatus['CONNECTING']:
case 1:
addPromptInfo('正在鏈接中')
break
case RongIMLib.ConnectionStatus['DISCONNECTED']:
case 2:
addPromptInfo('當前用戶主動斷開連接')
break
case RongIMLib.ConnectionStatus['NETWORK_UNAVAILABLE']:
case 3:
addPromptInfo('網絡不可用')
break
case RongIMLib.ConnectionStatus['CONNECTION_CLOSED']:
case 4:
addPromptInfo('未知緣由,鏈接關閉')
break
case RongIMLib.ConnectionStatus['KICKED_OFFLINE_BY_OTHER_CLIENT']:
case 6:
addPromptInfo('用戶帳戶在其餘設備登陸,本機會被踢掉線')
break
case RongIMLib.ConnectionStatus['DOMAIN_INCORRECT']:
case 12:
addPromptInfo('當前運行域名錯誤,請檢查安全域名配置')
break
}
}
})
// 消息監聽器
RongIMClient.setOnReceiveMessageListener({
// 接收到的消息
onReceived: function (message) {
// 判斷消息類型
switch (message.messageType) {
case RongIMClient.MessageType.TextMessage:
// message.content.content => 文字內容
addPromptInfo('新消息 ' + message.targetId + ':' + JSON.stringify(message))
break
case RongIMClient.MessageType.VoiceMessage:
// message.content.content => 格式爲 AMR 的音頻 base64
break
case RongIMClient.MessageType.ImageMessage:
// message.content.content => 圖片縮略圖 base64
// message.content.imageUri => 原圖 URL
break
case RongIMClient.MessageType.LocationMessage:
// message.content.latiude => 緯度
// message.content.longitude => 經度
// message.content.content => 位置圖片 base64
break
case RongIMClient.MessageType.RichContentMessage:
// message.content.content => 文本消息內容
// message.content.imageUri => 圖片 base64
// message.content.url => 原圖 URL
break
case RongIMClient.MessageType.InformationNotificationMessage:
// do something
break
case RongIMClient.MessageType.ContactNotificationMessage:
// do something
break
case RongIMClient.MessageType.ProfileNotificationMessage:
// do something
break
case RongIMClient.MessageType.CommandNotificationMessage:
// do something
break
case RongIMClient.MessageType.CommandMessage:
// do something
break
case RongIMClient.MessageType.UnknownMessage:
// do something
break
default:
// do something
}
}
})
RongIMClient.connect(token, {
onSuccess: function (userId) {
addPromptInfo('鏈接成功,用戶id:' + userId, userId)
},
onTokenIncorrect: function () {
addPromptInfo('token無效')
},
onError: function (errorCode) {
switch (errorCode) {
case RongIMLib.ErrorCode.TIMEOUT:
addPromptInfo('超時')
//連接超時進行從新的連接start
var callback = {
onSuccess: function (userId) {
console.log("Reconnect successfully." + userId);
},
onTokenIncorrect: function () {
console.log('token無效');
},
onError: function (errorCode) {
console.log(errorcode);
}
};
var config = {
// 默認 false, true 啓用自動重連,啓用則爲必選參數
auto: true,
// 重試頻率 [100, 1000, 3000, 6000, 10000, 18000] 單位爲毫秒,可選
url: 'cdn.ronghub.com/RongIMLib-2.5.0.min.js',
rate: [100, 1000, 3000, 6000, 10000]
};
RongIMClient.reconnect(callback, config);
//連接超時進行從新連接end
break;
case RongIMLib.ErrorCode.UNKNOWN_ERROR:
addPromptInfo('未知錯誤')
break;
case RongIMLib.ErrorCode.UNACCEPTABLE_PaROTOCOL_VERSION:
addPromptInfo('不可接受的協議版本')
break;
case RongIMLib.ErrorCode.IDENTIFIER_REJECTED:
console.log('ddd')
addPromptInfo('appkey不正確')
break;
case RongIMLib.ErrorCode.SERVER_UNAVAILABLE:
addPromptInfo('服務器不可用')
break;
}
addPromptInfo(errorCode)
}
}, null)
}
複製代碼
utils.scss
這個文件很簡單
@function vw ($px) {
@return $px / 750px * 100vw;
}
複製代碼
init.vue
經過用戶輸入的信息來進行初始化鏈接
<template>
<div class="init">
<van-nav-bar title="鏈接融雲" />
<van-cell-group>
<van-field v-model="appkey" required label="appkey" placeholder="請輸入您的 appkey" />
<van-field v-model="token" label="token" placeholder="請輸入您的 token" required />
<van-field v-model="targetId" label="targetId" placeholder="請輸入 targetId" required />
</van-cell-group>
<van-button class="init-button" type="info" @click="initRongCloud">初始化鏈接</van-button>
<div class="rong-show-box">
<p v-for="data in showDatas" v-bind:key="data">
{{data}}
</p>
</div>
</div>
</template>
<script> import { init } from '@/utils.js' export default { data () { return { appkey: '', // 這是咱們以前保存的 appkey *重要 token: '', // token 能夠屢次生成 以前也有介紹過 targetId: '', // 你要給誰發送消息 目標ID showDatas: [], // 初始化信息 } }, methods: { addPromptInfo (prompt, userId = null) { const _this = this const avatarList = [ 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4100987808,2324741924&fm=26&gp=0.jpg', 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2988245209,2476612762&fm=26&gp=0.jpg', 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4259300811,497831842&fm=26&gp=0.jpg', 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3684587473,1286660191&fm=26&gp=0.jpg', 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2884107401,3797902000&fm=26&gp=0.jpg' ] // 真實環境是經過登陸 後臺接口返回的 token 拿到的用戶信息 我在這爲爲了模擬 因此給初始化後的用戶隨機生成一個頭像 const avatar = avatarList[Math.floor(Math.random() * (3 + 1))] _this.showDatas.push(prompt) const timer = setInterval(() => { if (userId) { clearInterval(timer) // 路由跳轉後銷燬定時器 _this.$store.commit('SET_MEMBER', { // 保存用戶信息 userId: userId, avatar: avatar }) _this.$store.commit('SET_TARGETID', _this.targetId) // 保存目標ID _this.$router.push({ name: 'RongCloud' }) } }, 500) }, initRongCloud () { var appkey = this.appkey var token = this.token if (!appkey || !token) { alert('appkey 和 token 不能爲空') } else { // 這個init 是咱們以前擼的 `utils.js` init({ appkey: appkey, token: token }, this.addPromptInfo) } } } } </script>
<style lang="scss" scoped> @import "~@/scss/utils"; .init-button { position: fixed !important; bottom: vw(30px); left: 50%; transform: translateX(-50%); } .rong-show-box { margin-top: vw(100px); text-align: center; } </style>
複製代碼
RongCloud.vue
發送消息
<template>
<div id='rongcloud'>
<van-nav-bar title="融雲聊天" fixed left-text="返回" left-arrow @click-left="onClickLeft" />
<div class="wrapper">
<Message v-for="(item, index) in answer" :key="index" :data='item' />
</div>
<div class="send-message">
<van-field v-model="say" class="message-textarea" type="textarea" placeholder="請輸入..." />
<van-button class="send-button" type="info" size="small" @click="sendMessage">發送</van-button>
</div>
</div>
</template>
<script> import { mapState } from 'vuex' import Message from './Message' export default { components: { Message }, data () { return { say: '' // 消息 } }, created () { this.$nextTick(() => { const list = document.getElementById('rongcloud') document.documentElement.scrollTop = list.scrollHeight //如不行,請嘗試-> list.scrollTop = list.scrollHeight }) }, watch: { answer () { this.$nextTick(() => { const list = document.getElementById('rongcloud') document.documentElement.scrollTop = list.scrollHeight //如不行,請嘗試-> list.scrollTop = list.scrollHeight }) } }, computed: { ...mapState({ answer: 'answer', // 消息列表 memberInfo: 'memberInfo', // 用戶信息 targetId: 'targetId' // 目標ID }) }, methods: { onClickLeft () { this.$router.go(-1) }, sendMessage () { const _this = this var msg = new RongIMLib.TextMessage({ content: _this.say, extra: _this.memberInfo.avatar }); var conversationType = RongIMLib.ConversationType.PRIVATE // 單聊, 其餘會話選擇相應的消息類型便可 var targetId = this.targetId // 目標 Id RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, { onSuccess: function (message) { // message 爲發送的消息對象而且包含服務器返回的消息惟一 Id 和發送消息時間戳 const say = { css: 'right', txt: message.content.content, headImg: _this.memberInfo.avatar } _this.answer.push(say) _this.say = '' }, onError: function (errorCode, message) { var info = '' switch (errorCode) { case RongIMLib.ErrorCode.TIMEOUT: info = '超時' break case RongIMLib.ErrorCode.UNKNOWN: info = '未知錯誤' break case RongIMLib.ErrorCode.REJECTED_BY_BLACKLIST: info = '在黑名單中,沒法向對方發送消息' break case RongIMLib.ErrorCode.NOT_IN_DISCUSSION: info = '不在討論組中' break case RongIMLib.ErrorCode.NOT_IN_GROUP: info = '不在羣組中' break case RongIMLib.ErrorCode.NOT_IN_CHATROOM: info = '不在聊天室中' break } console.log('發送失敗: ' + info + errorCode) } }) } } } </script>
<style lang="scss" scoped> @import "~@/scss/utils"; .wrapper { padding-top: vw(92px); padding-bottom: vw(200px); } .send-message { width: 100vw; height: vw(200px); position: fixed !important; bottom: 0; left: 0; .message-textarea { height: 100%; } .send-button { position: fixed; right: vw(30px); bottom: vw(30px); } } </style>
複製代碼
Message.vue
顯示消息 邏輯比較簡單就不講了
<template>
<div>
<div v-if="data.css === 'left'">
<div class="message left">
<van-image round fit="cover" width="2rem" height="2rem" :src="data.headImg" />
<span>{{data.txt}}</span>
</div>
</div>
<div v-if="data.css === 'right'">
<div class="message right">
<span>{{data.txt}}</span>
<van-image round fit="cover" width="2rem" height="2rem" :src="data.headImg" />
</div>
</div>
</div>
</template>
<script> export default { props: ['data'] } </script>
<style lang="scss" scoped> @import "~@/scss/utils"; .message { display: flex; align-items: center; padding: vw(10px); } .left { justify-content: flex-start; span { margin-left: vw(20px); } } .right { justify-content: flex-end; span { margin-right: vw(20px); } } </style>
複製代碼
store.js
此demo的一些狀態管理數據
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
memberInfo: undefined, // 用戶信息
targetId: undefined, // 目標ID
answer: [] // 消息列表
}
const mutations = {
SET_MEMBER (state, memberInfo) {
state.memberInfo = memberInfo
},
SET_TARGETID (state, targetId) {
state.targetId = targetId
},
SET_ANSWER (state, playload) {
let say = {
css: 'left', // css 樣式
txt: playload.content, // 文本內容
headImg: playload.extra // 頭像
}
state.answer.push(say)
},
};
export default new Vuex.Store({
state,
mutations,
actions
})
複製代碼
utils.js
文件中引入store 保存發送的消息到 answer
import store from './store'
export const init = (params, addPromptInfo) => {
...
// 消息監聽器
RongIMClient.setOnReceiveMessageListener({
// 接收到的消息
onReceived: function (message) {
// 判斷消息類型
switch (message.messageType) {
case RongIMClient.MessageType.TextMessage:
// message.content.content => 文字內容
store.commit('SET_ANSWER', message.content)
...
}
}
})
...
}
複製代碼
我的博客 本 demo 是給你們實現一個基本思路,只是實現了一個一對一聊天的功能。如需更多功能,請自行深刻了解,謝謝