您好,登錄后才能下訂單哦!
這篇文章主要介紹小程序如何導(dǎo)入sdk實現(xiàn)聊天功能,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!
小程序怎么導(dǎo)入sdk實現(xiàn)聊天功能
首先使用npm進行下載騰訊云的即時聊天sdk;然后在項目中進行引用并進行sdk初始化;再根據(jù)后臺接口返回userID,userSig這兩個參數(shù)判斷當(dāng)前登錄人是誰;最后根據(jù)文檔實現(xiàn)基礎(chǔ)功能即可。
示例代碼
wxml:
<scroll-view bindscroll="refresh" scroll-into-view="{{toView}}" style="height: {{scroll_height}}px;" upper-threshold="100" scroll-y="true" enable-back-to-top="true" class="message-list"> <!-- 每一行 --> <view class="row" wx:for="{{messages}}" wx:key="{{index}}" id="row_{{index}}"> <!-- 日期 --> <view class="datetime" wx:if="{{item.msgTime != ''}}">{{item.msgTime}}</view> <!-- 頭像與內(nèi)容文本 --> <view class="body" style="flex-flow: {{item.flow == 'in' ? 'row' : 'row-reverse'}}"> <view class="avatar-container"> <image wx:if="{{item.flow=='in'}}" class="avatar" src="{{friendAvatarUrl}}" /> <image wx:else class="avatar" src="{{userData.avatarUrl}}" /> </view> <!-- 畫對話框 --> <view class="triangle" style="{{item.flow == 'out' ? 'right: 140rpx; background: #7ECB4B' : 'left: 140rpx;'}}"></view> <view class="content" style="{{item.flow == 'out' ? 'background: #7ECB4B' : ''}}"> <view wx:if="{{item.type === 'TIMTextElem'}}">{{item.payload.text}}</view> <image class="image-message" wx:elif="{{item.type === 'TIMImageElem'}}" src="{{item.payload.imageInfoArray[1].url}}" bindtap="previewImage" data-src="{{item.payload.imageInfoArray[1].url}}"></image> <view wx:elif="{{item.type === 'TIMSoundElem'}}" url="{{item.payload.url}}"> <view class="box" bindtap="openAudio" data-eventid="{{'13_'+index}}" data-time="{{item.payload.second}}" data-comkey="{{item.payload.url}}"> <image src="{{'13_'+index==audioIndex?audioGif:audioPng}}" style="height:22px;width:22px" class="_image"></image> <view style="padding-left: 4px;" class="_div data-v-afeb3abc"> {{item.payload.second<1?1:item.payload.second}}s </view> </view> </view> </view> </view> </view> </scroll-view> <view class="reply" style="bottom:{{reply_height}}px;"> <view class="Audio"> <image wx:if="{{opration==true}}" bindtap="Audio" src="../image/Audio.png"></image> <image wx:else bindtap="keyboard" src="../image/keyboard.png"></image> </view> <view class="opration-area"> <input bindfocus="bindfocus" wx:if="{{opration==true}}" type="text" bindinput="getContent" value="{{content}}" /> <view wx:else class="voice-button {{touchBtn?'hoverBtn':''}}" bind:touchstart="startAudio" bind:touchend="onTouchEnd" bind:longpress="onLongpress" bind:touchmove="onTouchMove"> {{touchBtn?'松開 結(jié)束':'按住說話'}} </view> </view> <view class="{{sendBtn==true?'send':'sendActive'}}" bindtap="sendMsg">發(fā)送</view> <view class="add" bind:tap="moreClick"> <image class="more" src="../image/more.png"></image> </view> <!-- <view class="send" bindtap="sendImg">相冊</view> <view class="send" bindtap="startAudio">開始</view> <view class="send" bindtap="endAudio">結(jié)束</view> --> </view> <view class="more_box" hidden="{{moreShow}}"> <view class="more_item" bindtap="sendImg"> <view class="img_box"> <image src="../image/picture.png"></image> </view> <view style="margin-top:10rpx;"> <text>相冊</text> </view> </view> </view>
js:
import TIM from 'tim-wx-sdk'; import COS from "cos-wx-sdk-v5"; let options = { SDKAppID: 0 // 接入時需要將0替換為您的即時通信 IM 應(yīng)用的 SDKAppID }; // 創(chuàng)建 SDK 實例,`TIM.create()`方法對于同一個 `SDKAppID` 只會返回同一份實例 let tim = TIM.create(options); // SDK 實例通常用 tim 表示 // 設(shè)置 SDK 日志輸出級別,詳細(xì)分級請參見 setLogLevel 接口的說明 tim.setLogLevel(1); // 普通級別,日志量較多,接入時建議使用 // tim.setLogLevel(1); // release 級別,SDK 輸出關(guān)鍵信息,生產(chǎn)環(huán)境時建議使用 // 注冊 COS SDK 插件 tim.registerPlugin({ 'cos-wx-sdk': COS }); const app = getApp() let recorderManager = wx.getRecorderManager(); // 錄音部分參數(shù) 小程序文檔 const recordOptions = { duration: 60000, // 錄音的時長,單位 ms,最大值 600000(10 分鐘) sampleRate: 44100, // 采樣率 numberOfChannels: 1, // 錄音通道數(shù) encodeBitRate: 192000, // 編碼碼率 format: 'aac' // 音頻格式,選擇此格式創(chuàng)建的音頻消息,可以在即時通信 IM 全平臺(Android、iOS、微信小程序和Web)互通 }; Page({ data: { friendId: '', friendName: '', friendAvatarUrl: '', messages: [], // 消息集合 complete: 0, // 是否還有歷史消息可以拉取,1 - 表示沒有,0 - 表示有 content: '', // 輸入框的文本值 lock: false, // 發(fā)送消息鎖 true - 加鎖狀態(tài) false - 解鎖狀態(tài) scroll_height: wx.getSystemInfoSync().windowHeight - 54, reply_height: 0, moreShow: true, userData: [], audioPng:"../image/audio-play.png", audioGif:"../image/audio-play.gif", audioState:true, /** * 歷史消息消息集合(結(jié)構(gòu)如下): * nextReqMessageID 用于續(xù)拉,分頁續(xù)拉時需傳入該字段。 * isCompleted 表示是否已經(jīng)拉完所有消息。 */ nextReqMessageID: "", isCompleted: "", isFirstGetList: true, audioContext: null, opration: true, touchBtn: false, recording: false, stopflag: false, cancelRecord: false, refreshTime: '', ScrollLoading: 0, audioIndex:null, sendBtn:true }, onLoad: function (options) { // this.setData({ friendId: options.friendId, friendName: options.friendName, friendAvatarUrl: options.friendAvatarUrl, conversationID: options.conversationID }) wx.setNavigationBarTitle({ title: options.friendName }) var that = this var userData = JSON.parse(wx.getStorageSync('userData')) that.data.messages = [] // 清空歷史消息 let audioContext = wx.createInnerAudioContext() this.setData({ userData, audioContext }) // 將某會話下所有未讀消息已讀上報 let promise = tim.setMessageRead({ conversationID: options.conversationID }); promise.then(function (imResponse) { // 已讀上報成功 }).catch(function (imError) { // 已讀上報失敗 }); }, onShow: function () { let that = this; // 獲取當(dāng)前聊天的歷史列表 that.getMessageList(); that.scrollToBottom(); // 獲取收到的單聊信息 let onMessageReceived = function (event) { // event.data - 存儲 Message 對象的數(shù)組 - [Message] let msgList = that.data.messages handlerHistoryMsgs(event.data, that) that.scrollToBottom(); }; tim.on(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived) // 監(jiān)聽錄音結(jié)束 recorderManager.onStop(function (res) { if (that.data.recording) { if (that.data.cancelRecord) { wx.hideToast() that.setData({ cancelRecord: false }) } else { // 創(chuàng)建消息實例,接口返回的實例可以上屏 const message = tim.createAudioMessage({ to: that.data.friendId, conversationType: TIM.TYPES.CONV_C2C, payload: { file: res }, onProgress: function (event) { } }); // 發(fā)送消息 let promise = tim.sendMessage(message); promise.then(function (imResponse) { // 發(fā)送成功 that.addMessage(imResponse.data.message, that) }).catch(function (imError) { // 發(fā)送失敗 }); that.setData({ recording: false }) } } else { wx.showToast({ title: '說話時間太短', duration: 1000, image: '../image/err.png' }) } }); }, onUnload: function () { }, /** * 獲取消息列表 */ getMessageList() { let that = this; let cb = tim.getMessageList({ conversationID: conversationID,//會話列表傳遞過來的參數(shù) count: 15 }) cb.then(function (imResponse) { const messageList = imResponse.data.messageList; // 消息列表。 const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于續(xù)拉,分頁續(xù)拉時需傳入該字段。 const isCompleted = imResponse.data.isCompleted; // 表示是否已經(jīng)拉完所有消息。 that.setData({ nextReqMessageID: nextReqMessageID, isCompleted: isCompleted }) handlerHistoryMsgs(messageList, that); that.scrollToBottom(); }); }, /** * 獲取文本的消息 */ getContent: function (e) { if(e.detail.value ==""){ this.setData({sendBtn:true}) }else{ this.setData({sendBtn:false}) } console.log(e) var that = this; that.setData({ content: e.detail.value }) }, /** * 發(fā)送消息 */ sendMsg: function (e) { if(this.data.content ==""){ wx.showToast({ title: '請輸入內(nèi)容', duration: 1000, icon:'none' }) return } var that = this // 發(fā)送文本消息,Web 端與小程序端相同 // 1. 創(chuàng)建消息實例,接口返回的實例可以上屏 let message = tim.createTextMessage({ to: this.data.friendId, conversationType: TIM.TYPES.CONV_C2C, payload: { text: this.data.content } }); // 2. 發(fā)送消息 let promise = tim.sendMessage(message); promise.then(function (imResponse) { // 發(fā)送成功 that.addMessage(imResponse.data.message, that) that.setData({sendBtn:true}) }).catch(function (imError) { // 發(fā)送失敗 }); }, /** * 刷新文本消息 */ addMessage: function (msg, that) { var messages = that.data.messages; messages.push(msg); that.setData({ messages: messages, content: '' // 清空輸入框文本 }) that.scrollToBottom(); }, /** * 發(fā)送圖片消息 */ sendImg() { let that = this; wx.chooseImage({ sourceType: ['album'], // 從相冊選擇 count: 1, // 只選一張,目前 SDK 不支持一次發(fā)送多張圖片 success: function (res) { // 2. 創(chuàng)建消息實例,接口返回的實例可以上屏 let message = tim.createImageMessage({ to: that.data.friendId, conversationType: TIM.TYPES.CONV_C2C, payload: { file: res }, onProgress: function (event) { } }); // 3. 發(fā)送圖片 let promise = tim.sendMessage(message); promise.then(function (imResponse) { // 發(fā)送成功 that.addMessage(imResponse.data.message, that) }).catch(function (imError) { // 發(fā)送失敗 }); } }) }, scrollToBottom: function () { this.setData({ toView: 'row_' + (this.data.messages.length - 1) }); }, previewImage(e) { let src = ''; wx.previewImage({ current: e.currentTarget.dataset.src, // 當(dāng)前顯示圖片的http鏈接 urls: [e.currentTarget.dataset.src] }) }, // 錄制語音 startAudio: function () { wx.showToast({ title: '上滑取消發(fā)送', duration: 10000, image: '../image/cancel.png' }) this.setData({ touchBtn: true }) if (this.data.stopFlag) { return; } recorderManager.start(recordOptions); recorderManager.onError(function (errMsg) { }); }, // # 利用長按判斷錄音是否太短 onLongpress() { this.setData({ recording: true }) }, // 發(fā)送錄音 onTouchEnd: function () { wx.hideToast() let that = this; that.setData({ touchBtn: false }) if (that.data.stopFlag) { return; } if (that.data.recording) { recorderManager.stop(); } else { that.setData({ stopFlag: true }) setTimeout(() => { recorderManager.stop(); that.setData({ stopFlag: false }) }, 400); } }, // 播放語音 openAudio(audio) { console.log(audio) let index = audio.currentTarget.dataset.eventid this.setData({ audioIndex:index // audioState:false }) this.data.audioContext.src = audio.currentTarget.dataset.comkey this.data.audioContext.autoplay = true; this.data.audioContext.play() this.data.audioContext.onPlay((res) => { }) this.data.audioContext.onEnded(() => { wx.hideToast() this.setData({ audioIndex:null }) console.log("語音結(jié)束了") }) this.data.audioContext.onError((res) => { }) }, // 上滑取消 onTouchMove(e) { if (e.touches[0].clientY < 520) { // # 取消發(fā)送 this.setData({ cancelRecord: true }); wx.showToast({ title: '松開,取消發(fā)送', duration: 10000, image: '../image/cancel.png' }) } else { // # 不取消 wx.hideToast() wx.showToast({ title: '上滑取消發(fā)送', duration: 10000, image: '../image/cancel.png' }) this.setData({ cancelRecord: false }) } }, // 下拉加載聊天記錄 refresh: function (e) { let that = this if (that.data.ScrollLoading == 1) { //防止多次觸發(fā) return false } if (e.detail.scrollTop < 1) { that.setData({ ScrollLoading: 1 }) wx.showLoading({ title: '加載中', }) setTimeout(() => { let promise = tim.getMessageList({ conversationID: that.data.conversationID, nextReqMessageID: that.data.nextReqMessageID, count: 15 }); promise.then(function (imResponse) { const newMessageList = imResponse.data.messageList; // 消息列表。 const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于續(xù)拉,分頁續(xù)拉時需傳入該字段。 const isCompleted = imResponse.data.isCompleted; // 表示是否已經(jīng)拉完所有消息。 that.setData({ nextReqMessageID: nextReqMessageID, isCompleted: isCompleted, messages: newMessageList.concat(that.data.messages) }) wx.hideLoading() that.setData({ ScrollLoading: 0 }) // handlerHistoryMsgs(messageList, that); }); }, 800); } // setTimeout(function(){ // var date = new Date(); // },300); }, // 切換 Audio() { this.setData({ opration: false }) }, keyboard() { this.setData({ opration: true }) }, moreClick() { if (this.data.moreShow) { this.setData({ moreShow: false, reply_height: 92, scroll_height: this.data.scroll_height - 92 }) } }, bindfocus() { this.setData({ moreShow: true, reply_height: 0, scroll_height: wx.getSystemInfoSync().windowHeight - 54 }) } }) /** * 處理歷史消息 */ function handlerHistoryMsgs(result, that) { var historyMsgs = that.data.messages; result.forEach(item => { historyMsgs.push(item) }) // historyMsgs.push(result[0]) that.setData({ messages: historyMsgs, }) // 將某會話下所有未讀消息已讀上報 let promise = tim.setMessageRead({ conversationID: that.data.conversationID }); promise.then(function (imResponse) { // 已讀上報成功 }).catch(function (imError) { // 已讀上報失敗 }); }
wxss:
/** 聊天窗口樣式 * 54px為回復(fù)框高度,js同 */ /*聊天記錄*/ page{ background: rgb(245, 245, 245); } .message-list { /*margin-bottom: 54px;*/ background: rgb(235, 235, 235); } /*單元行*/ .row { display: flex; flex-direction: column; margin: 0 30rpx; } /*日期*/ .datetime { font-size: 10px; padding: 10px 0; color: #999; text-align: center; } .send { font-size: 15px; /* padding-right: 10px; */ color: #999; text-align: center; height: 70%; border: 1px solid #e4dfdf; display: flex; align-items: center; justify-content: center; width: 90rpx; border-radius: 10rpx; } .sendActive { font-size: 15px; /* padding-right: 10px; */ color: #fff; text-align: center; height: 70%; border: 1px solid #05c15f; display: flex; align-items: center; justify-content: center; width: 90rpx; border-radius: 10rpx; background-color: #05c15f; } .Audio { font-size: 15px; color: #999; text-align: center; padding-left: 10rpx; } .Audio image { width: 50rpx; height: 50rpx; } .add { height: 70%; display: flex; align-items: center; justify-content: center; width: 90rpx; } .more { width: 50rpx; height: 50rpx; } /*主體*/ .body { display: flex; flex-direction: row; align-items: flex-start; justify-content: flex-start; width: 100%; margin-top: 10px; } /*頭像容器*/ .body.avatar-container { width: 20%; } /*頭像*/ .body .avatar { width: 80rpx; height: 80rpx; border-radius: 50%; margin: 0 20rpx; } /*文本消息*/ .body .content { font-size: 16px; background: #fff; border-radius: 5px; padding: 10px; line-height: 22px; margin-bottom: 10px; word-wrap: break-word; max-width: 300rpx; } /* 三角箭頭 */ .body .triangle { background: white; width: 20rpx; height: 20rpx; margin-top: 26rpx; transform: rotate(45deg); position: absolute; } /*圖片消息*/ .picture { width: 160px; } /*回復(fù)框*/ .reply { display: flex; flex-direction: row; justify-content: flex-start; align-items: center; position: fixed; /* bottom: 0; */ width: 100%; height: 54px; border-top: 1px solid rgb(215, 215, 215); background: rgb(245, 245, 245); } .reply .voice-image { width: 25px; height: 25px; margin-left: 3%; } /*文本輸入或語音錄入*/ .reply .opration-area { flex: 1; padding: 8px; } /*回復(fù)文本框*/ .reply input { background: rgb(252, 252, 252); height: 36px; border: 1px solid rgb(221, 221, 221); border-radius: 6px; padding-left: 3px; } /*選取圖片*/ .reply .choose-image { width: 25px; height: 25px; margin-right: 3%; } /*按住說話button*/ .voice-button { height: 36px; color: #818181; font-size: 14px; line-height: 36px; text-align: center; border: 1px solid #e4dfdf; border-radius: 10rpx; } /*懸浮提示框*/ .hud-container { position: fixed; width: 150px; height: 150px; left: 50%; top: 50%; margin-left: -75px; margin-top: -75px; } /*背景層*/ .hud-background { position: absolute; width: 100%; height: 100%; background: #999; opacity: 0.8; z-index: 11; border-radius: 10px; } /*懸浮框主體*/ .hud-body { position: relative; width: 100%; height: 100%; z-index: 19; display: flex; flex-direction: column; justify-content: space-between; align-items: center; } /*圖標(biāo)*/ .hud-body image { margin-top: 20px; width: 80px; height: 80px; } /*文字*/ .hud-body .tip { color: #fff; text-align: center; width: 90%; line-height: 34px; margin: 0 auto; margin-bottom: 10px; width: 90%; } .hud-body .warning { background: #c33; border-radius: 5px; } .image-message { max-width: 100%; border-radius: 4rpx; } .box { display: flex; height: 40rpx; line-height: 40rpx; } .hoverBtn { background-color: rgb(226, 220, 220); color: #fff; border-radius: 10rpx; } .more_box { height: 138rpx; width: 100%; padding: 15rpx; display: flex; background: rgb(245, 245, 245); position: fixed; bottom: 0; } .more_item { text-align: center; height: 150rpx; font-size: 24rpx; margin-left: 26rpx } .img_box { width: 80rpx; height: 84rpx; background-color: #fff; display: flex; justify-content: center; align-items: center; border-radius: 10rpx; } .img_box image { width: 40rpx; height: 40rpx; }
以上是“小程序如何導(dǎo)入sdk實現(xiàn)聊天功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。