vue(版本2.xx) + 环信web sdk(版本1.8.3)
Posted 小白&小菜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue(版本2.xx) + 环信web sdk(版本1.8.3)相关的知识,希望对你有一定的参考价值。
实现方案:
环信没有临时聊天人员历史记录接口,所以实现的方案是:
1.监听消息接收;2.将受到的消息存到缓存中,同时判断此用户是否之前聊天过,如果没聊过的话,把他的用户信息也存到缓存中;3.展示的东西都是从缓存中获取;4.新消息提醒是在监听到消息后,给用户信息里设置一个状态值,当点击刚用户查看历史记录时,再改变这个状态值
实现效果:
1.准备工作
npm引入sdk及 strophe.js(坑:刚开始下载的最新版的sdk,但是下载下来总是少文件src,挣扎半天,换了1.8.3版本的sdk好了,可能跟我项目的哪些东西的版本有不兼容的吧)
(1)cnpm i easemob-websdk@1.8.3 --save
(2)cnpm i strophe.js@1.2.16 --save
(3)下载webim.config.js: https://gitee.com/weimingye/web-im/blob/master/demo/javascript/dist/webim.config.js#
2.修改sdk的connection.js文件(注意新增代码的位置,放在11行声明变量的后边)
代码:
//新增代码***********start var Strophe = require(\'../../strophe.js/dist/strophe.js\').Strophe; var meStrophe = require(\'../../strophe.js/dist/strophe.js\'); $iq = meStrophe.$iq; $build = meStrophe.$build; $msg = meStrophe.$msg; $pres = meStrophe.$pres; //新增代码***********end
3.修改strophe.js
代码:
//新增代码***********start setJid: function (jid) { this.jid = jid; this.authzid = Strophe.getBareJidFromJid(this.jid); this.authcid = Strophe.getNodeFromJid(this.jid); }, getJid: function () { return this.jid; }, //新增代码***********end
4.修改webim.config.js(首行、最后一行,把自己公司的appkey换上去)
5.main.js新增配置
//环信start require(\'./assets/webim.config.js\') let WebIM = require(\'easemob-websdk\') Vue.prototype.$webim = WebIM const conn = new WebIM.connection({ isMultiLoginSessions: WebIM.config.isMultiLoginSessions, https: typeof WebIM.config.https === \'boolean\' ? WebIM.config.https : location.protocol === \'https:\', url: WebIM.config.xmppURL, heartBeatWait: WebIM.config.heartBeatWait, autoReconnectNumMax: WebIM.config.autoReconnectNumMax, autoReconnectInterval: WebIM.config.autoReconnectInterval, apiUrl: WebIM.config.apiURL, isAutoLogin: true }) const options = { apiUrl: WebIM.config.apiURL, user: \'\',//用户名 pwd: \'\',//密码 appKey: WebIM.config.appkey, success:function (res) { console.log(\'链接服务器正常\') }, error:function (err) { alert(err) } } Vue.prototype.$imconn = conn Vue.prototype.$imoption = options //环信end
6.聊天中的表情编码对应文件
emoji.js
module.exports = { path: "../../static/faces", obj: { "[):]": "ee_1.png", "[:D]": "ee_2.png", "[;)]": "ee_3.png", "[:-o]": "ee_4.png", "[:p]": "ee_5.png", "[(H)]": "ee_6.png", "[:@]": "ee_7.png", "[:s]": "ee_8.png", "[:$]": "ee_9.png", "[:(]": "ee_10.png", "[:\'(]": "ee_11.png", "[:|]": "ee_18.png", "[(a)]": "ee_13.png", "[8o|]": "ee_14.png", "[8-|]": "ee_15.png", "[+o(]": "ee_16.png", "[<o)]": "ee_12.png", "[|-)]": "ee_17.png", "[*-)]": "ee_19.png", "[:-#]": "ee_20.png", "[:-*]": "ee_22.png", "[^o)]": "ee_21.png", "[8-)]": "ee_23.png", "[(|)]": "ee_24.png", "[(u)]": "ee_25.png", "[(S)]": "ee_26.png", "[(*)]": "ee_27.png", "[(#)]": "ee_28.png", "[(R)]": "ee_29.png", "[({)]": "ee_30.png", "[(})]": "ee_31.png", "[(k)]": "ee_32.png", "[(F)]": "ee_33.png", "[(W)]": "ee_34.png", "[(D)]": "ee_35.png" } };
index.js(暂时未用到)
const _WIDTH = window.screen.availWidth > 350 ? 350 : window.screen.availWidth; export default { // whether auto check media query and dispatch by redux or not ? reduxMatchMedia: true, // map of media query breakpoints dimensionMap: { xs: "480px", sm: "768px", md: "992px", lg: "1200px", xl: "1600px" }, name: "Web IM", logo: "", SIDER_COL_BREAK: "sm", // md SIDER_COL_WIDTH: 80, SIDER_WIDTH: 350, RIGHT_SIDER_WIDTH: _WIDTH, // imgType: { // gif: 1, // bmp: 1, // jpg: 1, // png: 1, // }, PAGE_NUM: 20 };
7.图片文件存放在static文件夹下,图片大致都差不多,网上应该可以查到
8.表情组件
<template> <span> <el-popover ref="popover5" placement="top-start" width="360" v-model="showModal"> <img v-for="(v,i) in emojiList" :src="require(`../../../static/faces/${v}`)" :key="i" @click="selectEmoji(i)" class="img-style" /> </el-popover> <i class="icon iconfont icon-face" @click="showModal = !showModal"></i> </span> </template> <script> import emoji from "../../config/emoji"; export default { data() { return { emojiList: emoji.obj, currentEmoji: "", showModal: false }; }, methods: { selectEmoji(e) { let value = (this.inpMessage || "") + e; this.$data.showModal = false; this.$emit("selectEmoji", value); } }, props: { inpMessage: String } }; </script> <style scoped> /deep/ .el-popover.el-popper { width: 360px; position: absolute; bottom: 20%; left: 260px; transform-origin: center bottom; z-index: 2001; } .img-style { width: 22px; margin: 5px; cursor: pointer; } .img-style:hover { background-color: aquamarine; } </style>
8.页面中使用
<template> <div> <div class="headerTitle">{{title}}</div> <div class="chatBox"> <!-- 临时聊天用户列表--> <div class="chatList" ref="chatList"> <div class="chatList_title">近期联系人</div> <div> <div v-if="chatList && chatList.length>0" v-for="(item,index) in chatList" :key="index" class="chatList_item" :class="{\'active\':index == currentIndex}" @click="selectFriend(item.userPhone,index)"> <img :src="item.userPic" :onerror="defaultImgs" style="min-width: 40px;"/> <div>{{item.userPhone}} {{item.userName}}</div> <span v-if="item.active"></span> </div> </div> </div> <!-- 聊天内容--> <div class="content" ref="chatContent"> <!-- 聊天历史记录--> <div class="historyList" id="historyList"> <div v-for="(item,index) in historyMessage" :key="index"> <div class="item_time">{{item.time}}</div> <div class="item_message" :class="{\'currentUser\':item.from == username_from}"> <!-- 展示图片--> <img v-if="item.type == \'img\'" :src="item.message" style="max-width: 30%"/> <!--解析文本或表情--> <p v-if="item.type ==\'txt\'" style="user-select: text" v-html="renderTxt(item.message)" /> </div> </div> </div> <!--发送聊天--> <div class="chatInput"> <div style="padding: 4px 10px;"> <!-- 表情组件 --> <ChatEmoji v-on:selectEmoji="selectEmoji" :inpMessage="message" /> <!-- 上传图片 --> <div class="upImgBox"> <i class="icon iconfont icon-tupian"></i> <input type="file" class="sendImg" ref="sendImg" @change="sendPrivateUrlImg"> </div> </div> <!-- 输入框--> <el-input ref="txtDom" type="textarea" :autosize="{ minRows: 4, maxRows: 8}" placeholder="请输入内容" resize="none" v-model="message" @keyup.enter.native="sendPrivateText"> </el-input> <el-button type="primary" size="small" @click="sendPrivateText" style="float: right;margin-right: 20px;">提交</el-button> </div> </div> </div> </div> </template> <script> import ChatEmoji from "../../components/chatEmoji/index.vue";//表情组件 import emoji from "../../config/emoji"; export default { name: "index", components: { ChatEmoji }, data(){ return { title: \'互动消息\', type: \'contact\', currentUserpwd: \'123456\', username_from: \'15263819410\',//当前登录的用户(发送人手机号) username_to: \'\',//当前聊天的用户名(接收人手机号) message:\'\',//当前发送的信息 historyMessage: [],//聊天历史记录 showEmoji: false,//是否展示表情组件 chatList:[],//临时聊天用户列表 currentIndex: undefined,//左侧当前激活index defaultImgs: \'this.src = "\' + require(\'../../assets/img/userLogo.png\') + \'"\', } }, created() { this.login(); this.updateChatList();//获取临时聊天用户列表 }, mounted(){ this.$refs.chatContent.style.height = this.getClientHeight() - 50 + \'px\'; this.$refs.chatList.style.height = this.getClientHeight() - 50 + \'px\'; }, methods: { //登录环信账户 login(){ var _this = this; this.$imoption.user = this.username_from; this.$imoption.pwd = this.currentUserpwd; this.$imoption.success = (res)=>{ // console.log(\'登录成功回调\',res); } this.$imconn.open(this.$imoption); this.$imconn.listen({ onOpened: function (message) { // console.log(\'用户已上线\'); }, onClosed: function (message) { this.$message.info(\'用户已下线\') }, //收到表情消息 onEmojiMessage: function (message) { // //把聊天对象名message.from存储到storage中 _this.updateChatList(message); //把新接收的信息更新存储到storage中 _this.updateStorage(message); //_this.selectFriend(message.from); }, //收到图片消息 onPictureMessage: (message) => { //把聊天对象名message.from存储到storage中 _this.updateChatList(message); //把新接收的信息更新存储到storage中 _this.updateStorage(message); //_this.selectFriend(message.from); }, //收到文本消息 onTextMessage: function (message) { //把聊天对象名message.from存储到storage中 _this.updateChatList(message); //把新接收的信息更新存储到storage中 _this.updateStorage(message); // 更新历史记录到页面 // _this.selectFriend(message.from); }, //收到音频消息 onAudioMessage: function ( message ) { var options = { url: message.url }; options.onFileDownloadComplete = function ( response ) { //音频下载成功,需要将response转换成blob,使用objectURL作为audio标签的src即可播放。 var objectURL = WebIM.utils.parseDownloadResponse.call(Demo.conn, response); // console.log(\'音频\',objectURL) }; options.onFileDownloadError = function () { //音频下载失败 }; //通知服务器将音频转为mp3 options.headers = { \'Accept\': \'audio/mp3\' }; WebIM.utils.download.call(conn, options); }, //收到视频消息 onVideoMessage: function (message) { var node = document.getElementById(\'privateVideo\'); var option = { url: message.url, headers: { \'Accept\': \'audio/mp4\' }, onFileDownloadComplete: function (response) { var objectURL = WebIM.utils.parseDownloadResponse.call(conn, response); // console.log(\'视频消息\',objectURL); node.src = objectURL; }, onFileDownloadError: function () { // console.log(\'File down load error.\') } }; WebIM.utils.download.call(conn, option); }, }) }, // 获取好友列表(项目没用到) // getFriends(){ // var newarry = []; // this.friends = newarry; // this.$imconn.getRoster({ // success: function (roster) { // console.log(\'获取好友列表1\',roster) // roster.forEach((item,index)=>{ // if(item.subscription === \'both\' || item.subscription === \'to\'){ // newarry.push(item); // console.log(\'好友列表\',newarry, item.name); // } // }); // }, // error: function (error) { // console.log(\'error\',error) // } // }) // }, //发送文本消息 环信 flutter sdk集成IM离线推送及点击推送获取推送信息(iOS版)环信 flutter sdk集成IM离线推送及点击推送获取推送信息(iOS版)
RTC月度小报5月 |教育aPaaS灵动课堂升级抢先体验VUE版 Agora Web SDK声网Agora与HTC达成合作