微信小程序实现聊天功能?导入sdk(软件开发工具包)
首先使用npm进行下载腾讯云的即时聊天sdk;然后在项目中进行引用并进行sdk初始化;再根据后台接口返回userID,userSig这两个参数判断当前登录人是谁;最后根据文档实现基础功能即可。
示例代码
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>
<!-- 头像与内容文本 -->
<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?'松开 结束':'按住说话'}}
</view>
</view>
<view class="{{sendBtn==true?'send':'sendActive'}}" bindtap="sendMsg">发送</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">结束</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 应用的 SDKAppID
};
// 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
let tim = TIM.create(options); // SDK 实例通常用 tim 表示
// 设置 SDK 日志输出级别,详细分级请参见 setLogLevel 接口的说明
tim.setLogLevel(1); // 普通级别,日志量较多,接入时建议使用
// tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用
// 注册 COS SDK 插件
tim.registerPlugin({
'cos-wx-sdk': COS
});
const app = getApp()
let recorderManager = wx.getRecorderManager();
// 录音部分参数 小程序文档
const recordOptions = {
duration: 60000, // 录音的时长,单位 ms,最大值 600000(10 分钟)
sampleRate: 44100, // 采样率
numberOfChannels: 1, // 录音通道数
encodeBitRate: 192000, // 编码码率
format: 'aac' // 音频格式,选择此格式创建的音频消息,可以在即时通信 IM 全平台(Android、iOS、微信小程序和Web)互通
};
Page({
data: {
friendId: '',
friendName: '',
friendAvatarUrl: '',
messages: [], // 消息集合
complete: 0, // 是否还有历史消息可以拉取,1 - 表示没有,0 - 表示有
content: '', // 输入框的文本值
lock: false, // 发送消息锁 true - 加锁状态 false - 解锁状态
scroll_height: wx.getSystemInfoSync().windowHeight - 54,
reply_height: 0,
moreShow: true,
userData: [],
audioPng:"../image/audio-play.png",
audioGif:"../image/audio-play.gif",
audioState:true,
/**
* 历史消息消息集合(结构如下):
* nextReqMessageID 用于续拉,分页续拉时需传入该字段。
* isCompleted 表示是否已经拉完所有消息。
*/
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;
// 获取当前聊天的历史列表
that.getMessageList();
that.scrollToBottom();
// 获取收到的单聊信息
let onMessageReceived = function (event) {
// event.data - 存储 Message 对象的数组 - [Message]
let msgList = that.data.messages
handlerHistoryMsgs(event.data, that)
that.scrollToBottom();
};
tim.on(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived)
// 监听录音结束
recorderManager.onStop(function (res) {
if (that.data.recording) {
if (that.data.cancelRecord) {
wx.hideToast()
that.setData({
cancelRecord: false
})
} else {
// 创建消息实例,接口返回的实例可以上屏
const message = tim.createAudioMessage({
to: that.data.friendId,
conversationType: TIM.TYPES.CONV_C2C,
payload: {
file: res
},
onProgress: function (event) { }
});
// 发送消息
let promise = tim.sendMessage(message);
promise.then(function (imResponse) {
// 发送成功
that.addMessage(imResponse.data.message, that)
}).catch(function (imError) {
// 发送失败
});
that.setData({
recording: false
})
}
} else {
wx.showToast({
title: '说话时间太短',
duration: 1000,
image: '../image/err.png'