IM 聊天教程:发送图片/视频/语音/表情

2020-05-19 09:46:49 +08:00
 jonychen1

IM 聊天教程:发送图片 /视频 /语音 /表情

经常有朋友问起,如何在 IM 即时通讯中实现发送图片、视频、语音和表情?

为此,小编特意写了一个 vue 版本的 Demo,实现了图片视频文件和表情的的发送,参考这个 Demo 源代码,相信你就可以轻松的用 Uniapp 和小程序完成类似的功能。

本文的 Demo 全套的源码已经开源在码云上,供大家 clone 或者下载:https://gitee.com/goeasy-io/GoEasyDemo-vue-AudioPictureVideo

一、图片 /视频 /语音发送

对于语音、视频和图片的发送,您如果有注意的话,在使用 QQ 或者微信的时候,当有朋友发送图片和视频给您时,收到后,需要等一会儿才能显示出来。就是因为在发送的时候,只发送了文件的路径,您收到后,需要加载才能显示出来。因为当前主流的 IM 包括微信,QQ 等对于图片和视频的发送,通常的做法都是:

  1. 上传文件到文件服务器
  2. 推送文件路径
  3. 收到文件路径
  4. 加载文件

并不会通过网络直接传送源文件,因为对于大文件的传输,会影响消息的即时性。

对于文件的上传,您可以选择直接上传到您自己的服务器,也可以选择上传到各种云服务的对象存储服务,也就是 OSS 上。

参考源码:

DemoService.prototype.sendFileMessage = function (type,content) {
    let uploadResult = restapi.uploadFile(content);
    let message = new Message(type, uploadResult.url);
    uploadResult.promise.then(() => {
        this.publish(message);
    },() =>  {
        var error = new Message(MessageType.TEXT, "文件上传失败.");
        this.messages.unshift(error)
    });
    return uploadResult.promise;
};

云服务的 OSS 具有更好的稳定性和高可用性,上传的速度也有保证,另外也可以和 CDN 配合,所以我们建议用 GoEasy 配合 OSS 服务来实现图片和视频的发送。

在本文的源码里,选择了使用阿里云的 OSS 作为文件上传服务器,您也可以切换为您自己实现的文件上传服务器,或者选择其他云服务的 OSS,原理都是一样的。

二、发送表情

表情的发送也是非常简单的,只是对于一些第一次实现表情发送的同学来说,需要一个思路而已。

细心点的朋友,肯定有发现,当我们在 QQ 上聊天的时候,我们输入一个反斜杠+“cy”, 就像这样:/cy,QQ 就会立即显示为一个呲牙的表情,就像下图一样:

哈哈哈,相信你已经心里已经明白了十之八九了,对吧?

没错,表情在发送的过程中其实就是发一个像“/cy”这样定义好的的字符串,在对方收到后“翻译”成表情而已。

那为什么不直接发图片,而要进行这么复杂的“翻译”呢?

因为字符串比图片更小,发送的速度更快,用户体验更好。一个系统中的用户成千上万,用字符串可以节约大量的带宽,节约系统资源。

原理讲明白了,我们就开始干活儿吧:

第一步、定义表情

定义一个 key value 的对象,key 作为表情标签,value 则为每个表情标签对应的图片:

let expressions = {
    "[risus]": './images/risus.png',
    "[kiss]": './images/kiss.png',
    "[cry]": './images/cry.png',
    "[die]": './images/die.png',
    "[anger]": './images/anger.png',
}

然后画一个表情选择的界面:

第二步、选择表情

为每个图片的 onclick 事件中传入这个表情的字符串标签,当用户点击的时候,将表情的标签写入输入框,就成为了一个普通的字符串。在发送的时候,发送的其实就是这个表情的标签,也就是一个字符串。

<div class="goeasy-expression">
            <div :class="[appearanceClass, 'goeasy-appearance']" @click="show = true">{{text}}</div>
            <div class="expression-container" v-show="show">
                <div class="expression-icon-content">
                    <div class="expression-icon__item"
                         v-for="expression in list"
                         :key="expression.id"
                         @click="selectExpression(expression)">
                        <img :src="expressions[expression.tag]">
                    </div>

                </div>
                <div class="close-expression" @click="show = false"></div>
            </div>
        </div>

第三步、收到表情和展示表情

当对方收到一个字符串后,跟第一步定义的 key-value 列表去匹配,如果能找到对应的表情,就在页面上展示对应的表情图片,如果找不到,就是一个普通的文本信息。

原理讲清楚了后,具体实现是不是很简单了?

参考我们提供的 Demo 源代码,相信你很快就能掌握实现方法。

Demo 源码:https://gitee.com/goeasy-io/GoEasyDemo-vue-AudioPictureVideo

1304 次点击
所在节点    问与答
1 条回复
iFlicker
2020-05-19 09:55:48 +08:00
长文本呢? 图文混编的富文本呢?👀

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/673114

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX