七、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天消息项的实现
会话好友列表的实现
1、项目引言
2、腾讯云后台配置TXIM
3、配置项目并实现IM登录
4、会话好友列表的实现
5、聊天输入框的实现
6、聊天界面容器的实现
7、聊天消息项的实现
8、聊天输入框扩展面板的实现
9、聊天会话管理的实现
10、聊天记录的加载与消息收发
11、定位SD配置与收发定位消息
12、贴图表情的定制化开发
13、腾讯云后台配置TRTC功能
14、集成音视频通话功能
15、集成仿微信的拍照,相册选择插件
16、集成美颜功能
17、集成TPNS消息推送(暂未接入)
@
文章概述
整个IM项目的关键点来了,本文将讨论一下聊天消息的实现,如何收发消息并且实现聊天消息的UI显示。
聊天消息项的实现
1.收发聊天消息
1.1 接收聊天消息
接收聊天消息显得很简单,在之前的会话列表实现中已经做过一次,这次我们代码其实差不多,唯一不一样的是接受后我们需要做筛选确定需要回显到聊天消息界面的项目。
绑定消息事件部分的代码如下:
// 这里选择在onLoad绑定,确定不会漏接数据
async onLoad (params) {
// 做好一个变量确定我现在在和谁聊天
this.receiver = params.receiver
// 监听新的消息
this.$txim.$on('onRecvC2CTextMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvC2CCustomMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvGroupTextMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvGroupCustomMessage', this.onRecvMessageHanlder)
this.$txim.$on('onRecvNewMessage', this.onRecvMessageHanlder)
}
接收到消息的回调事件处理如下
// 获取消息
async onRecvMessageHanlder ({ data }) {
let V2TIMMessageManager = this.$txim.getMessageManager()
let senderId = data?.sender?.userID || data?.sender
if (senderId == this.receiver) {
this.HistoryMessageToChatLog([data])
this.$txim.markC2CMessageAsRead(senderId)
await this.$nextTick()
this.$refs.chatLayout.scrollToBottom()
}
},
1.2 发送聊天消息
发送聊天消息实际上demo已经有所封装了,对于文本消息而言发送的代码如下:
// 发送文字 这里需要防抖处理,反正多次点击发送按钮从而出现问题
sendText: _.debounce(async function (text) {
let V2TIMMessageManager = this.$txim.getMessageManager()
// 创建消息结构体
let v2TIMMessage = V2TIMMessageManager.createTextMessage(text)
try {
// 发送消息
let ret = await V2TIMMessageManager.sendMessage(v2TIMMessage, this.receiver)
// 更新聊天消息
this.HistoryMessageToChatLog([ret.data])
} catch (e) {
this.$utils.toast('发送失败')
}
await this.$nextTick()
// 保持滚动到底部
this.$refs.chatLayout.scrollToBottom()
}, 500, { leading: true, trailing: false }),
上面演示的是文本消息,而对于其他消息而言,只是创建的消息结构体不一样,各种消息的结构体如下
// 文本
let v2TIMMessage = V2TIMMessageManager.createTextMessage(text)
// 大表情
let v2TIMMessage = V2TIMMessageManager.createFaceMessage(0, { faceUrl: url })
// 图片
let v2TIMMessage = V2TIMMessageManager.createImageMessage(filePath)
// 视频
let v2TIMMessage = V2TIMMessageManager.createVideoMessage(filePath, 'mp4', timeLen, snapshotPath)
// 语音
let v2TIMMessage = V2TIMMessageManager.createSoundMessage(filePath, timeLen)
// 定位
let v2TIMMessage = V2TIMMessageManager.createLocationMessage(address, longitude, latitude)
2.聊天消息格式化
为了做好组件之间的解耦合,我们需要将腾讯消息的结构体进行格式化,映射为我们消息组件中能识别的结构体,映射部分的代码实际上utils/imUtils文件中已经有所提供了,具体的操作如下(这里需要注意,里面根据了消息记录的elemType做了判断,elemType腾讯TXIM的官方文档对应这里https://im.sdk.qcloud.com/doc/zh-cn/classcom_1_1tencent_1_1imsdk_1_1v2_1_1V2TIMMessageManager.html)
async HistoryMessageToChatLog (msgLogs, unshift) {
for (let item of msgLogs) {
let msgType = [
null,
this.$imUtils.MSG_TEXT,
null,
this.$imUtils.MSG_IMAGE,
this.$imUtils.MSG_AUDIO,
this.$imUtils.MSG_VIDEO,
null,
this.$imUtils.MSG_LOCATION,
this.$imUtils.MSG_TIP_FACE,
][item.elemType]
let dataJson = {
id: item.msgID,
head: '../static/icon_u_head.jpg',
self: item.isSelf,
type: msgType,
data: null
}
switch (msgType) {
case this.$imUtils.MSG_TEXT:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item.elem.text, item)
break
case this.$imUtils.MSG_LOCATION:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item, item.elem.latitude, item.elem.longitude, item.elem.desc, item)
break
case this.$imUtils.MSG_IMAGE:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item.elem.imageList[0].url, item)
break
case this.$imUtils.MSG_AUDIO:
dataJson.data = this.$imUtils.buildMessageItem(msgType, '', item.elem.duration * 1000, item)
break
case this.$imUtils.MSG_VIDEO:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item, item)
break
case this.$imUtils.MSG_TIP_FACE:
dataJson.data = this.$imUtils.buildMessageItem(msgType, item, item)
break
default:
// console.log(item)
}
if (msgType) {
this.chatLogs[unshift ? 'unshift' : 'push'](dataJson)
}
}
}
3.聊天消息回显
聊天消息部分demo已经内置了一个聊天组件,我们可以实现开箱即用,只需要引入组件定义好list即可
首先我们需要引入组件,并且在template对应的位置写好即可
<chat-message-item
v-for="item in chatLogs"
:ref="item.id"
:self="item.self"
:head="item.head"
:type="item.type"
:data="item.data"
:prevent="currentPopItem && currentPopItem.item.id == item.id"
@longpressContent="currentPopItem = { ref: $refs[item.id][0], item }"
>
</chat-message-item>
<script>
import ChatMessageItem from '../components/ChatMessageItem'
export default {
components: { ChatMessageItem },
}
</script>
4.聊天消息弹出菜单
一般而言我们聊天消息还需要有一些操作,比如删除,转发之类的,那么我们也需要为聊天消息增加弹出菜单,这需要我们去做浮动位置的计算,然而demo中已经提供了一个弹出菜单,使得我们可以很简单的实现这个功能。
聊天消息的弹出菜单组件在componetns/ChatMsgItemProp下,开发者需要自己修改成为自己需要的功能,这里我们先引入组件然后加入到template中对应位置
<chat-layout
class="page"
ref="chatLayout"
:end="end"
@upperLoading="loadMoreLog"
@scroll="onChatLayoutScroll"
@clickRoot="onRootClick"
>
<chat-message-item
v-for="item in chatLogs"
:ref="item.id"
:self="item.self"
:head="item.head"
:type="item.type"
:data="item.data"
:prevent="currentPopItem && currentPopItem.item.id == item.id"
@longpressContent="currentPopItem = { ref: $refs[item.id][0], item }"
>
</chat-message-item>
<!-- 这里要明显注意,弹出不是在ChatMessageItem里面的! -->
<chat-msg-item-pop
:show="currentPopItem"
@clickFn="onPopClickFn($event)"
></chat-msg-item-pop>
</chat-layout>
这里我们主要是从chatMessageItem中获取到了长按事件的坐标信息,然后交给chatMsgItemPop,弹出组件会根据坐标计算确定显示位置和方向,计算部分的算法如下:
calcPopPosition () {
let { ref } = this.show
let el = ref.$el
let pop = this.$refs.pop
let content = el.children[2]
dom.getComponentRect(pop, ({ size }) => {
let popSize = size
dom.getComponentRect(content, ({ size }) => {
let contentSize = size
this.popPoint.reverse = (contentSize.top - popSize.height) < 0
this.popPoint.popHeight = popSize.height
this.popPoint.itemHeight = contentSize.height
this.popPoint.touchX = contentSize.left + contentSize.width / 2
this.popPoint.touchY = contentSize.top
})
})
}
通过计算确定了显示位置之后就会显示功能菜单列表,在组件中内置了以下的按钮图标,功能暂未实现,开发者可以自己根据实际需要定制化处理哦。
{ type: 'copy', label: '复制', icon: '/static/icon_copy.png' },
{ type: 'share', label: '转发', icon: '/static/icon_share.png' },
{ type: 'collect', label: '收藏', icon: '/static/icon_collect.png' },
{ type: 'delete', label: '删除', icon: '/static/icon_delete.png' },
{ type: 'ref', label: '引用', icon: '/static/icon_ref_msg.png' },
{ type: 'translate', label: '翻译', icon: '/static/icon_fanyi.png' },
{ type: 'search', label: '搜一搜', icon: '/static/icon_search_fun.png' },
项目开源地址及交流群
项目成品效果查看:请点击项目引言
项目开源地址:https://gitee.com/ckong/Zhimi.OpenSource.UniApp.TXIM.Vue
Uniapp开发交流群:755910061
七、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天消息项的实现的更多相关文章
- 一、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-项目引言
项目文章索引 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展面板的 ...
- 五、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天输入框的实现
会话好友列表的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展 ...
- 二、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-腾讯云后台配置TXIM
项目文章索引 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展面板的 ...
- 三、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-配置项目并实现IM登录
项目文章索引 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展面板的 ...
- 四、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-会话好友列表的实现
会话好友列表的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入框扩展 ...
- 八、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天输入框扩展面板的实现
聊天输入框扩展面板的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入 ...
- Android IOS WebRTC 音视频开发总结(七十)-- 移动端音视频技术优化的七个方向
最近直播很火,很多朋友对背后的技术比较感兴趣,所以今天我们整理一篇关于移动端视频优化的文章,这篇文章是我朋友在一个技术大会上分享过的,更多内容请关注我们的微信公众号:rtcblacker 视频直播为什 ...
- Android IOS WebRTC 音视频开发总结(六七)-- 在线教育虽火要做好其实不容易
本文主要介绍在线教育这个行业,文章最早发表在我们的微信公众号上,支持原创,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.rtc.help 最近很多朋友在咨询在线教育的事(其实之 ...
- Android IOS WebRTC 音视频开发总结(四七)-- 深度解读国内首届WebRTC大会背后的真相
本文主要解读国内首届WebRTC大会背后的真相,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,更多详见www.rtc.help -------------------------- ...
随机推荐
- C#gridview颜色提示
OnRowCreated="gridStatistic_RowCreated private void FillUI() { gridStatistic.DataSource = dtSta ...
- 【STM32】晶振,主时钟,外设频率介绍
首先,我用的是STM32F407,下方所有图片都是出自这芯片的文档,如果型号和我不同,需要找到对应的芯片说明文档,也许会有出入 先看一张时钟图 这里会着重说明高速的部分,低速(不管内部还是外部)只给R ...
- 转Android service 启动篇之 startForegroundService
本文转自:https://blog.csdn.net/shift_wwx/article/details/82496447 前言: 在官方文档 Android 8.0 行为变更 中有这样一段话: An ...
- jenkins之代码部署回滚脚本
#!/bin/bash DATE=`date +%Y-%m-%d_%H-%M-%S` METHOD=$1 BRANCH=$2 GROUP_LIST=$3 function IP_list(){ if ...
- Linux学习 - 压缩解压命令
一." .gz "压缩文件 1 压缩语法 gzip [文件] 2 解压语法 gunzip [压缩文件] 3 注 gzip只能压缩文件 gzip不保留原文件 二." . ...
- 使用 ACE 库框架在 UNIX 中开发高性能并发应用
使用 ACE 库框架在 UNIX 中开发高性能并发应用来源:developerWorks 中国 作者:Arpan Sen ACE 开放源码工具包可以帮助开发人员创建健壮的可移植多线程应用程序.本文讨论 ...
- poi做一个简单的EXCAL
//创建一个实体类 package text; import java.util.Date; public class Student { private int id; private String ...
- C++ friend详解
私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. C++ 是 ...
- 【Python】【Algorithm】排序
冒泡排序 dic = [12, 45, 22, 6551, 74, 155, 6522, 1, 386, 15, 369, 15, 128, 123, ] for j in range(1, len( ...
- linux基础-TCP/IP协议篇
一.网络TCP/IP层次模型 1.网络层次模型概念介绍:TCP/IP协议就是用于简化OSI层次,以及相关的标准.传输控制协议(tcp/ip)族是相关国防部(DoD)所创建的,主要用来确保数据的完整性及 ...