如何实现IM表情、图片、文件之间的通讯?

背景

随着企业的发展,企业事务管理系统如OA、CRM、PM、KM等将会越来越多。企业员工每天需要花大量的时间去各个系统查看与操作相关事务。尽管如此,各项信息还是无法第一时间得到处理,各项工作的执行效率大打折扣。因此,睿信IM产品应运而生,它可以:

1、为企业提供私有的IM系统,防止商业信息泄露

2、整合企业办公生态,汇总多端消息通知,防止消息漏接漏审。

3、便捷企业办公,在IM中可完成多个办公系统的操作。简化办公流程操作。

而通讯作为睿信IM最基本的功能,怎么少得了表情、图片、文件之间的通讯呢?那么问题来了,它是如何实现IM表情、图片、文件之间的通讯呢?

 

睿信IM表情是如何实现的呢:

在使用IM产品时,我们接收到的表情不会是一张图片,而是类似:face[微笑] 、[微笑]、/微笑这样的字符串,那么如何将字符串转换为对应的表情就是问题的关键。毋庸置疑,通过对相应的字符串作匹配替换,从而将对应的表情显示出来是比较好的一个方法。

首先,本地要有一个表情图片库,类似 睿信IM表情库:

 

本地表情文件的不同,对应的处理方法也会不一样。 有了这样的一个表情库文件,接下来就是对相应的表情字符串进行匹配。

其次:针对不同的表情字符串,需要写不同的匹配规则。如需匹配[微笑]或者/微笑格式的表情,对应的规则如下:

A.循环遍历,用字符串赋予一个图片路径,最后用来发送的表情实际上是 face+下面的字符串标识,如 face[微笑]:

private insertFace(item: any) {
    this.sendMessageValue = this.sendMessageValue + "face" + item;
    this.showFace = false;
}

export let faceUtils = {
    alt: [
        "[微笑]", "[得意]", "[泪]", "[哈哈]", "[色]", "[伤心]",
        "[害羞]", "[疑问]", "[闭嘴]", "[怒]", "[偷笑]", "[困]",
        "[汗]", "[吐血]", "[拜拜]", "[笑哭]", "[晕]", "[嘘]",
        "[衰]", "[敲打]", "[可怜]", "[赞]", "[差]", "[握手]",
        "[耶]", "[抱拳]", "[OK]", "[抱抱]", "[玫瑰]", "[晚安]"
    ],
      faces: function () {
        let self = this;
        let arr: any = {};
        for (let i = 0; i < self.alt.length; i++) {
            arr[self.alt[i]] = "./static/newFace/" + i + ".png";
        }
        return arr;
    }
};

 

 

B.上一步的每一个字符串(如face[微笑])都有一个与之对应的图片路径(如 ”./static/newFace/0.png”),接下来把每个图片路径放到img表情里,实现表情的渲染(如下图):

<ul class="faces">
    <li v-for="(item, index) in faceList" :key="index">
        <img :src="faceMap[item]" :alt="item" :title="item" @click="insertFace(item)"/>
    </li>
</ul>

 

data() {
    return {
        faceList: faceUtils.alt,
        faceMap: faceUtils.faces()
    };
},
methods: {
    insertFace: function(item) {
        this.$emit("insertFace", item);
    }
}

 

 

C.当接收方收到表情字符串(如face[微笑])时,对应的要进行转译,以字符串标识face[]进行替换为对应的img标签(即表情):

let fa = faceUtils.faces();
content = content
    .replace(/face\[([^\s\\[\]]+?)]/g, function (face: any) {
    // 转义表情
    let alt = face.replace(/^face/g, "");
    return ('<img class="faceImg" width="28" alt="face' + alt + '" src="' + fa[alt] + '">');
})

 

 

睿信IM图片及文件是如何实现的呢:

图片及文件发送,通过input标签选择图片或文件

<input type="file" class="fileInput" ref="fileInput" title="发送图片"
       @change="imageChange" placeholder="上传文件" accept="image/*" />
<input type="file" class="fileUpload" ref="fileUpload" title="发送文件"
       @change="fileChange" placeholder="上传文件" accept />

 

 

接着调用文件发送接口,通过表单的数据格式向后台发送数据,回调函数接收图片或文件路径,

let formData = new FormData();
formData.append("channel_id", this.chatObj.channel_id);
formData.append("user_id", Common.getIMUserIDFromCookie());
formData.append("file", this.fileObj);
apiIMServices.filePost(formData, (progress) => {
    this.uploadProgress = progress;
}).then((res: any) => {
    Popup.closeAll();
    console.log(res);
    this.$store.commit('setFilePath',{
        id: res.metadata.files[0].id,
        filePath: this.fileObj.path,
        exist: true
    });
    this.ifImg = false;
}).catch(error => {
    Popup.closeAll();
    console.log(error);
    Popup.errorMsg(error.errorMsg);
});

 

 

 

对方接收到对应的图片或文件,会有如下websocket推送

 

接收方通过字段image和otherFile判断它是图片还是文件,然后把一整个文件信息数组(上图metadata里的files)传递给文件组件处理:

组件接收到文件files信息,通过id去获取文件链接路径,然后把链接FileLinkUrl传递到img标签,即可完成图片的渲染显示:

 

private async getFileLink() {
    this.FileLinkUrl =  await apiIMServices.getFileLink(this.file.id);
    let that: any = this;
    that.filelinkUrls[this.file.id] = this.FileLinkUrl;
    this.$store.commit('setFilelinkUrls',that.filelinkUrls);
}
<img class="image-item" :src="FileLinkUrl ? FileLinkUrl.link: ''" alt />

 

同理:把链接FileLinkUrl传递到a标签,即可完成文件的下载:

<a class="file-download" v-if="FileLinkUrl" :href="FileLinkUrl ? FileLinkUrl.link : 'javascript:;'" >下载</a>

 

总结

总体来说将字符串转换为对应的图片是表情实现的关键,而图片和文件的通讯则依赖于后台接口提供的文件链接,将文件链接嵌入对应的标签从而转变为对应的图片或文件,再通过点击文件的标签链接从而实现文件下载功能。以上是IM表情、图片、文件通讯实现基本思路,希望能给大家带来收获。

posted on 2020-11-16 17:41  睿江云  阅读(336)  评论(0编辑  收藏  举报