1 安装
npm install easemob-websdk --save 官方安装 ,这种安装要在依赖包配置初始化链接,提交代码时并没把配置提交
使用 hx-websdk 安装
npm install --save hx-websdk
2 .使用 新建一个webim.js 放在聊天窗口组件同一层级,为了Emoji图片路径同步
import store from ‘@/store/store‘ // window.Strophe = require(‘strophe.js‘).Strophe // let WebIM = require(‘easemob-websdk‘) import WebIM from "hx-websdk"; // let WebIM = require(‘hx-websdk‘) // require(‘hx-emedia‘) // WebIM.WebRTC = require(‘hx-webrtc‘) WebIM.config = { /* * XMPP server */ xmppURL: ‘im-api.easemob.com‘, /* * Backend REST API URL */ apiURL: (location.protocol === ‘https:‘ ? ‘https:‘ : ‘http:‘) + ‘//a1.easemob.com‘, /* * Application AppKey */ appkey: ‘1106190328208422#liangzi‘, /* * Whether to use wss * @parameter {Boolean} true or false */ https: false, /* * isMultiLoginSessions * true: A visitor can sign in to multiple webpages and receive messages at all the webpages. * false: A visitor can sign in to only one webpage and receive messages at the webpage. */ isMultiLoginSessions: false, /* * set presence after login */ isAutoLogin: true, /** * Whether to use window.doQuery() * @parameter {Boolean} true or false */ isWindowSDK: false, /** * isSandBox=true: xmppURL: ‘im-api-sandbox.easemob.com‘, apiURL: ‘//a1-sdb.easemob.com‘, * isSandBox=false: xmppURL: ‘im-api.easemob.com‘, apiURL: ‘//a1.easemob.com‘, * @parameter {Boolean} true or false */ isSandBox: false, /** * Whether to console.log in strophe.log() * @parameter {Boolean} true or false */ isDebug: true, /** * will auto connect the xmpp server autoReconnectNumMax times in background when client is offline. * won‘t auto connect if autoReconnectNumMax=0. */ autoReconnectNumMax: 2, /** * the interval seconds between each auto reconnectting. * works only if autoReconnectMaxNum >= 2. */ autoReconnectInterval: 2, /** * webrtc supports WebKit and https only */ isWebRTC: (/Firefox/.test(navigator.userAgent) || /WebKit/.test(navigator.userAgent)) && /^https:$/.test(window.location.protocol), /** * after login, send empty message to xmpp server like heartBeat every 45s, to keep the ws connection alive. */ heartBeatWait: 4500, /** * while http access,use ip directly,instead of ServerName,avoiding DNS problem. */ isHttpDNS: false, /** * Will show the status of messages in single chat * msgStatus: true show * msgStatus: true hide */ msgStatus: true, /** * When a message arrived, the receiver send an ack message to the * sender, in order to tell the sender the message has delivered. * See call back function onReceivedMessage */ delivery: true, /** * When a message read, the receiver send an ack message to the * sender, in order to tell the sender the message has been read. * See call back function onReadMessage */ read: false, /** * Will encrypt text message and emoji message * {type:‘none‘} no encrypt * {type:‘base64‘} encrypt with base64 * {type:‘aes‘,mode: ‘ebc‘,key: ‘123456789easemob‘,iv: ‘0000000000000000‘} encrypt with aes(ebc) * {type:‘aes‘,mode: ‘cbc‘,key: ‘123456789easemob‘,iv: ‘0000000000000000‘} encrypt with aes(cbc) */ encrypt: { type: ‘none‘ } } WebIM.Emoji = { path: ‘./../../../../../assets/images/faces/‘, map: { ‘[微笑]‘: ‘ee_1.gif‘, ‘[撇嘴]‘: ‘ee_2.gif‘, ‘[色]‘: ‘ee_3.gif‘, ‘[发呆]‘: ‘ee_4.gif‘, ‘[流泪]‘: ‘ee_5.gif‘, ‘[害羞]‘: ‘ee_6.gif‘, ‘[闭嘴]‘: ‘ee_7.gif‘, ‘[睡]‘: ‘ee_8.gif‘, ‘[大哭]‘: ‘ee_9.gif‘, ‘[尴尬]‘: ‘ee_10.gif‘, ‘[发怒]‘: ‘ee_11.gif‘, ‘[调皮]‘: ‘ee_12.gif‘, ‘[呲牙]‘: ‘ee_13.gif‘, ‘[惊讶]‘: ‘ee_14.gif‘, ‘[难过]‘: ‘ee_15.gif‘, ‘[囧]‘: ‘ee_16.gif‘, ‘[抓狂]‘: ‘ee_17.gif‘, ‘[吐]‘: ‘ee_18.gif‘, ‘[偷笑]‘: ‘ee_19.gif‘, ‘[愉快]‘: ‘ee_20.gif‘, ‘[白眼]‘: ‘ee_21.gif‘, ‘[傲慢]‘: ‘ee_22.gif‘, ‘[饥饿]‘: ‘ee_23.gif‘, ‘[困]‘: ‘ee_24.gif‘, ‘[惊恐]‘: ‘ee_25.gif‘, ‘[流汗]‘: ‘ee_26.gif‘, ‘[憨笑]‘: ‘ee_27.gif‘, ‘[悠闲]‘: ‘ee_28.gif‘, ‘[奋斗]‘: ‘ee_29.gif‘, ‘[咒骂]‘: ‘ee_30.gif‘, ‘[疑问]‘: ‘ee_31.gif‘, ‘[嘘]‘: ‘ee_32.gif‘, ‘[晕]‘: ‘ee_33.gif‘, ‘[疯了]‘: ‘ee_34.gif‘, ‘[衰]‘: ‘ee_35.gif‘, ‘[敲打]‘: ‘ee_36.gif‘, ‘[再见]‘: ‘ee_37.gif‘, ‘[擦汗]‘: ‘ee_38.gif‘, ‘[抠鼻]‘: ‘ee_39.gif‘, ‘[糗大了]‘: ‘ee_40.gif‘, ‘[坏笑]‘: ‘ee_41.gif‘, ‘[左哼哼]‘: ‘ee_42.gif‘, ‘[右哼哼]‘: ‘ee_43.gif‘, ‘[哈欠]‘: ‘ee_44.gif‘, ‘[鄙视]‘: ‘ee_45.gif‘, ‘[委屈]‘: ‘ee_46.gif‘, ‘[快哭]‘: ‘ee_47.gif‘, ‘[阴险]‘: ‘ee_48.gif‘, ‘[亲亲]‘: ‘ee_49.gif‘, ‘[吓]‘: ‘ee_50.gif‘, ‘[可怜]‘: ‘ee_51.gif‘, ‘[拥抱]‘: ‘ee_52.gif‘, ‘[月亮]‘: ‘ee_53.gif‘, ‘[太阳]‘: ‘ee_54.gif‘, ‘[炸弹]‘: ‘ee_55.gif‘, ‘[骷髅]‘: ‘ee_56.gif‘, ‘[菜刀]‘: ‘ee_57.gif‘, ‘[猪头]‘: ‘ee_58.gif‘, ‘[西瓜]‘: ‘ee_59.gif‘, ‘[咖啡]‘: ‘ee_60.gif‘, ‘[饭]‘: ‘ee_61.gif‘, ‘[爱心]‘: ‘ee_62.gif‘, ‘[强]‘: ‘ee_63.gif‘, ‘[弱]‘: ‘ee_64.gif‘, ‘[握手]‘: ‘ee_65.gif‘, ‘[胜利]‘: ‘ee_66.gif‘, ‘[抱拳]‘: ‘ee_67.gif‘, ‘[勾引]‘: ‘ee_68.gif‘, ‘[OK]‘: ‘ee_69.gif‘, ‘[No]‘: ‘ee_70.gif‘, ‘[玫瑰]‘: ‘ee_71.gif‘, ‘[凋谢]‘: ‘ee_72.gif‘, ‘[嘴唇]‘: ‘ee_73.gif‘, ‘[爱情]‘: ‘ee_74.gif‘, ‘[飞吻]‘: ‘ee_75.gif‘ } } // WebIM.NewEmoji = { // map: [‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘??‘, ‘??♂?‘, ‘??♀?‘, ‘??Det‘, ‘???♂?‘, ‘???♀?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??????‘, ‘??????‘, ‘????????‘, ‘????????‘, ‘????????‘, ‘??????‘, ‘??????‘, ‘????????‘, ‘????????‘, ‘????????‘, ‘??????‘, ‘??????‘, ‘????????‘, ‘????????‘, ‘????????‘, ‘????‘, ‘??????‘, ‘????‘, ‘??????‘, ‘??????‘, ‘????‘, ‘??????‘, ‘????‘, ‘??????‘, ‘??????‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘] // } /* eslint new-cap: ["error", { "newIsCap": false }] */ 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 }) conn.listen({ // 连接成功回调 onOpened: function (message) { conn.getRoster({ success: function (roster) { // console.log(roster,‘链接‘); let rosData = [] for (var i = 0, l = roster.length; i < l; i++) { if (roster[i].subscription === ‘both‘) { rosData.push(roster[i]) // console.log(rosData,‘链接成功‘) // store.dispatch(‘getFriendsData‘, rosData) } else { return } } } }) }, // 收到文本消息 onTextMessage: function (message) { console.log(message,‘接收新的消息‘); let textMessage = { from: message.from, content:message.data, type: ‘txt‘ } store.dispatch(‘setIMtextMessage‘, JSON.stringify(textMessage) ); // console.log(store,‘全局变量‘); }, // 接收图片 onPictureMessage: (message) => { let textMessage = { from: message.from, url: message.url, type: ‘img‘ } store.dispatch(‘setIMtextMessage‘, JSON.stringify(textMessage)); console.log(message,‘接收图片‘); }, // 收到表情信息 onEmojiMessage: function (message) { console.log(message, ‘接收表情‘); // 接收到的是数组,循环编译图片 let content = ‘‘; message.data.forEach((item, index) => { if (item.type==‘emoji‘) { //require不能转动态参,先截取图片名称再拼接转 let eeIndex = item.data.indexOf(‘ee_‘); let img = item.data.substring(eeIndex, item.data.length); let path = require(`./../../../../../assets/images/faces/${img}`); content += `<img src="${path}" />` } else { content += item.data } }) let textMessage = { from: message.from, content: content, type: ‘txt‘ } store.dispatch(‘setIMtextMessage‘, JSON.stringify(textMessage)); }, // 收到联系人订阅请求、处理群组、聊天室被踢解散等消息 onPresence: function (message) { }, // 处理好友申请 onRoster: function () { conn.getRoster({ success: function (roster) { let rosData = [] for (var i = 0, l = roster.length; i < l; i++) { if (roster[i].subscription === ‘both‘) { rosData.push(roster[i]) console.log(‘处理好友申请‘) console.log(rosData) // store.dispatch(‘getFriendsData‘, rosData) } else { return } } } }) }, onAudioMessage: function (message) { console.log(‘当前关闭‘) }, // 收到音频消息 onLocationMessage: function (message) { console.log(‘当前关闭‘) }, // 收到位置消息 onFileMessage: function (message) { console.log(‘当前关闭‘) }, // 收到文件消息 onVideoMessage: function (message) { console.log(‘当前关闭‘) }, // 收到视频消息 onInviteMessage: function (message) { console.log(‘当前关闭‘) }, // 处理群组邀请 onOnline: function () { console.log(‘当前关闭‘) }, // 本机网络连接成功 onOffline: function () { console.log(‘当前关闭‘) }, // 本机网络掉线 // 失败回调 onError: function (message) { console.log(message) } }) // 需要注册一个全局的WebIM 在hx-sdk中有需要用到 不然发送接收表情时会抛出异常 window.WebIM = WebIM export default { install: function (Vue, options) { // console.log(WebIM) Object.defineProperty(Vue.prototype, ‘$imConn‘, { value: conn }) } }
3.如果需要视频聊天 安装 hx-webrtc
npm install --save hx-webrtc // 代码部分 WebIM.WebRTC = require(‘hx-webrtc‘) // 集成 const rtcCall = new WebIM.WebRTC.Call({ connection: conn, mediaStreamConstaints: { audio: true, video: true }, listener: { onAcceptCall: function (from, options) { // console.log(‘onAcceptCall::‘, ‘from: ‘, from, ‘options: ‘, options); }, onGotRemoteStream: function (stream, streamType) { // console.log(‘onGotRemoteStream::‘, ‘stream: ‘, stream, ‘streamType: ‘, streamType); }, onGotLocalStream: function (stream, streamType) { // console.log(‘onGotLocalStream::‘, ‘stream:‘, stream, ‘streamType: ‘, streamType); }, onRinging: function (caller) { let reg = /(?<=_).*([email protected])/ let callerId = (reg.exec(caller))[0] let curUser = [] let friends = store.state.data.friends for (let i in friends) { if (friends[i].username === callerId) { curUser = friends[i] } } console.log(curUser) // router.push({ path: ‘/calling‘, query: { user: curUser, curBtn: true } }) }, onTermCall: function (reason) { console.log(‘onTermCall::‘) console.log(‘reason:‘, reason) }, onIceConnectionStateChange: function (iceState) { if (iceState === ‘closed‘) { // router.push({ path: ‘/friends‘ }) } }, onError: function (e) { console.log(e) } } }) Object.defineProperty(Vue.prototype, ‘$rtcCall‘, { value: rtcCall })
4 .最终代码结合
import store from ‘@/store/store‘ // window.Strophe = require(‘strophe.js‘).Strophe // let WebIM = require(‘easemob-websdk‘) import WebIM from "hx-websdk"; // let WebIM = require(‘hx-websdk‘) // require(‘hx-emedia‘) // WebIM.WebRTC = require(‘hx-webrtc‘) WebIM.config = { /* * XMPP服务器 对于在console.easemob.com创建的appKey,固定为该值 */ xmppURL: ‘im-api.easemob.com‘, /* *环信后端REST API URL,固定不变 */ apiURL: (location.protocol === ‘https:‘ ? ‘https:‘ : ‘http:‘) + ‘//a1.easemob.com‘, /* *rest Server地址 对于在console.easemob.com创建的appkey,固定为该值 */ appkey: ‘1106190328208422#liangzi‘, /* * 是否使用https * @parameter {Boolean} true or false */ https: false, /* * isMultiLoginSessions * true: 访问者可以登录多个网页,并在所有网页上接收消息。. * false: 访客只能登入一个网页,并在该网页接收讯息 */ isMultiLoginSessions: false, /* * set presence after login */ isAutoLogin: true, /** * Whether to use window.doQuery() * @parameter {Boolean} true or false */ isWindowSDK: false, /** * isSandBox=true: xmppURL: ‘im-api-sandbox.easemob.com‘, apiURL: ‘//a1-sdb.easemob.com‘, * isSandBox=false: xmppURL: ‘im-api.easemob.com‘, apiURL: ‘//a1.easemob.com‘, * @parameter {Boolean} true or false */ isSandBox: false, /** * Whether to console.log in strophe.log() * @parameter {Boolean} true or false */ isDebug: true, /** * 将自动连接xmpp服务器,当客户端离线时,在后台自动重连次数. *如果autoReconnectNumMax=0,则不会自动连接. */ autoReconnectNumMax: 2, /** * 每次自动重新连接之间的间隔秒. * 仅当autoReconnectMaxNum >= 2时才有效。 */ autoReconnectInterval: 2, /** * webrtc只支持WebKit和https */ isWebRTC: (/Firefox/.test(navigator.userAgent) || /WebKit/.test(navigator.userAgent)) && /^https:$/.test(window.location.protocol), /** * 登录后,每隔45秒向xmpp服务器发送一条空消息(比如heartBeat),以保持ws连接处于活动状态 */ heartBeatWait: 4500, /** * 当http访问时,直接使用ip而不是ServerName,避免了DNS问题 */ isHttpDNS: false, /** * 会显示消息的状态在单一聊天 * msgStatus: true show * msgStatus: true hide */ msgStatus: true, /** * 当消息到达时,接收方将ack消息发送到 * 发送方,以便告诉发送方消息已发送。 * 参见回调函数onReceivedMessage */ delivery: true, /** * 当消息读取时,接收方将ack消息发送到 * 发送方,以便告诉发送方消息已被读取。 * 参见回调函数onReadMessage */ read: false, /** *将加密短信和表情信息 * {type:‘none‘} no encrypt * {type:‘base64‘} encrypt with base64 * {type:‘aes‘,mode: ‘ebc‘,key: ‘123456789easemob‘,iv: ‘0000000000000000‘} encrypt with aes(ebc) * {type:‘aes‘,mode: ‘cbc‘,key: ‘123456789easemob‘,iv: ‘0000000000000000‘} encrypt with aes(cbc) */ encrypt: { type: ‘none‘ } } WebIM.Emoji = { path: ‘./../../../../../assets/images/faces/‘, map: { ‘[微笑]‘: ‘ee_1.gif‘, ‘[撇嘴]‘: ‘ee_2.gif‘, ‘[色]‘: ‘ee_3.gif‘, ‘[发呆]‘: ‘ee_4.gif‘, ‘[流泪]‘: ‘ee_5.gif‘, ‘[害羞]‘: ‘ee_6.gif‘, ‘[闭嘴]‘: ‘ee_7.gif‘, ‘[睡]‘: ‘ee_8.gif‘, ‘[大哭]‘: ‘ee_9.gif‘, ‘[尴尬]‘: ‘ee_10.gif‘, ‘[发怒]‘: ‘ee_11.gif‘, ‘[调皮]‘: ‘ee_12.gif‘, ‘[呲牙]‘: ‘ee_13.gif‘, ‘[惊讶]‘: ‘ee_14.gif‘, ‘[难过]‘: ‘ee_15.gif‘, ‘[囧]‘: ‘ee_16.gif‘, ‘[抓狂]‘: ‘ee_17.gif‘, ‘[吐]‘: ‘ee_18.gif‘, ‘[偷笑]‘: ‘ee_19.gif‘, ‘[愉快]‘: ‘ee_20.gif‘, ‘[白眼]‘: ‘ee_21.gif‘, ‘[傲慢]‘: ‘ee_22.gif‘, ‘[饥饿]‘: ‘ee_23.gif‘, ‘[困]‘: ‘ee_24.gif‘, ‘[惊恐]‘: ‘ee_25.gif‘, ‘[流汗]‘: ‘ee_26.gif‘, ‘[憨笑]‘: ‘ee_27.gif‘, ‘[悠闲]‘: ‘ee_28.gif‘, ‘[奋斗]‘: ‘ee_29.gif‘, ‘[咒骂]‘: ‘ee_30.gif‘, ‘[疑问]‘: ‘ee_31.gif‘, ‘[嘘]‘: ‘ee_32.gif‘, ‘[晕]‘: ‘ee_33.gif‘, ‘[疯了]‘: ‘ee_34.gif‘, ‘[衰]‘: ‘ee_35.gif‘, ‘[敲打]‘: ‘ee_36.gif‘, ‘[再见]‘: ‘ee_37.gif‘, ‘[擦汗]‘: ‘ee_38.gif‘, ‘[抠鼻]‘: ‘ee_39.gif‘, ‘[糗大了]‘: ‘ee_40.gif‘, ‘[坏笑]‘: ‘ee_41.gif‘, ‘[左哼哼]‘: ‘ee_42.gif‘, ‘[右哼哼]‘: ‘ee_43.gif‘, ‘[哈欠]‘: ‘ee_44.gif‘, ‘[鄙视]‘: ‘ee_45.gif‘, ‘[委屈]‘: ‘ee_46.gif‘, ‘[快哭]‘: ‘ee_47.gif‘, ‘[阴险]‘: ‘ee_48.gif‘, ‘[亲亲]‘: ‘ee_49.gif‘, ‘[吓]‘: ‘ee_50.gif‘, ‘[可怜]‘: ‘ee_51.gif‘, ‘[拥抱]‘: ‘ee_52.gif‘, ‘[月亮]‘: ‘ee_53.gif‘, ‘[太阳]‘: ‘ee_54.gif‘, ‘[炸弹]‘: ‘ee_55.gif‘, ‘[骷髅]‘: ‘ee_56.gif‘, ‘[菜刀]‘: ‘ee_57.gif‘, ‘[猪头]‘: ‘ee_58.gif‘, ‘[西瓜]‘: ‘ee_59.gif‘, ‘[咖啡]‘: ‘ee_60.gif‘, ‘[饭]‘: ‘ee_61.gif‘, ‘[爱心]‘: ‘ee_62.gif‘, ‘[强]‘: ‘ee_63.gif‘, ‘[弱]‘: ‘ee_64.gif‘, ‘[握手]‘: ‘ee_65.gif‘, ‘[胜利]‘: ‘ee_66.gif‘, ‘[抱拳]‘: ‘ee_67.gif‘, ‘[勾引]‘: ‘ee_68.gif‘, ‘[OK]‘: ‘ee_69.gif‘, ‘[No]‘: ‘ee_70.gif‘, ‘[玫瑰]‘: ‘ee_71.gif‘, ‘[凋谢]‘: ‘ee_72.gif‘, ‘[嘴唇]‘: ‘ee_73.gif‘, ‘[爱情]‘: ‘ee_74.gif‘, ‘[飞吻]‘: ‘ee_75.gif‘ } } // WebIM.NewEmoji = { // map: [‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘????‘, ‘??‘, ‘??♂?‘, ‘??♀?‘, ‘??Det‘, ‘???♂?‘, ‘???♀?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??????‘, ‘??????‘, ‘????????‘, ‘????????‘, ‘????????‘, ‘??????‘, ‘??????‘, ‘????????‘, ‘????????‘, ‘????????‘, ‘??????‘, ‘??????‘, ‘????????‘, ‘????????‘, ‘????????‘, ‘????‘, ‘??????‘, ‘????‘, ‘??????‘, ‘??????‘, ‘????‘, ‘??????‘, ‘????‘, ‘??????‘, ‘??????‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘??‘, ‘?‘, ‘??‘, ‘??‘, ‘??‘] // } /* eslint new-cap: ["error", { "newIsCap": false }] */ 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 }) conn.listen({ // 连接成功回调 onOpened: function (message) { conn.getRoster({ success: function (roster) { // console.log(roster,‘链接‘); let rosData = [] for (var i = 0, l = roster.length; i < l; i++) { if (roster[i].subscription === ‘both‘) { rosData.push(roster[i]) // console.log(rosData,‘链接成功‘) // store.dispatch(‘getFriendsData‘, rosData) } else { return } } } }) }, // 收到文本消息 onTextMessage: function (message) { console.log(message,‘接收新的消息‘); let textMessage = { from: message.from, content:message.data, type: ‘txt‘ } store.dispatch(‘setIMtextMessage‘, JSON.stringify(textMessage) ); // console.log(store,‘全局变量‘); }, // 接收图片 onPictureMessage: (message) => { let textMessage = { from: message.from, url: message.url, type: ‘img‘ } store.dispatch(‘setIMtextMessage‘, JSON.stringify(textMessage)); console.log(message,‘接收图片‘); }, // 收到表情信息 onEmojiMessage: function (message) { console.log(message, ‘接收表情‘); // 接收到的是数组 let content = ‘‘; message.data.forEach((item, index) => { if (item.type==‘emoji‘) { //require不能转动态参,先截取图片名称再拼接转 let eeIndex = item.data.indexOf(‘ee_‘); let img = item.data.substring(eeIndex, item.data.length); let path = require(`./../../../../../assets/images/faces/${img}`); content += `<img src="${path}" />` } else { content += item.data } }) let textMessage = { from: message.from, content: content, type: ‘txt‘ } store.dispatch(‘setIMtextMessage‘, JSON.stringify(textMessage)); }, // 收到联系人订阅请求、处理群组、聊天室被踢解散等消息 onPresence: function (message) { }, // 处理好友申请 onRoster: function () { conn.getRoster({ success: function (roster) { let rosData = [] for (var i = 0, l = roster.length; i < l; i++) { if (roster[i].subscription === ‘both‘) { rosData.push(roster[i]) console.log(‘处理好友申请‘) console.log(rosData) // store.dispatch(‘getFriendsData‘, rosData) } else { return } } } }) }, onAudioMessage: function (message) { console.log(‘当前关闭‘) }, // 收到音频消息 onLocationMessage: function (message) { console.log(‘当前关闭‘) }, // 收到位置消息 onFileMessage: function (message) { console.log(‘当前关闭‘) }, // 收到文件消息 onVideoMessage: function (message) { console.log(‘当前关闭‘) }, // 收到视频消息 onInviteMessage: function (message) { console.log(‘当前关闭‘) }, // 处理群组邀请 onOnline: function () { console.log(‘当前关闭‘) }, // 本机网络连接成功 onOffline: function () { console.log(‘当前关闭‘) }, // 本机网络掉线 // 失败回调 onError: function (message) { console.log(message) } }) /* const rtcCall = new WebIM.WebRTC.Call({ connection: conn, mediaStreamConstaints: { audio: true, video: true }, listener: { onAcceptCall: function (from, options) { // console.log(‘onAcceptCall::‘, ‘from: ‘, from, ‘options: ‘, options); }, onGotRemoteStream: function (stream, streamType) { // console.log(‘onGotRemoteStream::‘, ‘stream: ‘, stream, ‘streamType: ‘, streamType); }, onGotLocalStream: function (stream, streamType) { // console.log(‘onGotLocalStream::‘, ‘stream:‘, stream, ‘streamType: ‘, streamType); }, onRinging: function (caller) { let reg = /(?<=_).*([email protected])/ let callerId = (reg.exec(caller))[0] let curUser = [] let friends = store.state.data.friends for (let i in friends) { if (friends[i].username === callerId) { curUser = friends[i] } } console.log(curUser) // router.push({ path: ‘/calling‘, query: { user: curUser, curBtn: true } }) }, onTermCall: function (reason) { console.log(‘onTermCall::‘) console.log(‘reason:‘, reason) }, onIceConnectionStateChange: function (iceState) { if (iceState === ‘closed‘) { // router.push({ path: ‘/friends‘ }) } }, onError: function (e) { console.log(e) } } }) */ // 需要注册一个全局的WebIM 在hx-sdk中有需要用到 不然发送接收表情时会抛出异常 window.WebIM = WebIM export default { install: function (Vue, options) { // console.log(WebIM) Object.defineProperty(Vue.prototype, ‘$imConn‘, { value: conn }) Object.defineProperty(Vue.prototype, ‘$rtcCall‘, { value: rtcCall }) } }
5 .组件使用或者全局使用
// main.js import IM from ‘./utils/plugin/webim‘ Vue.use(IM)
6. 注册
根据用户名/密码/昵称注册环信 Web IM :
webIMregister() { this.$imConn.open({ username: ‘username‘, password: ‘password‘, nickname: ‘nickname‘, appKey: WebIM.config.appkey, apiUrl: WebIM.config.apiURL, success: function () { }, error: function () { }, }) },
7 .登录
// 登录环信 webIMlogin () { this.$imConn.open({ apiUrl: WebIM.config.apiURL, user: this.userInfo.uuid, pwd: ‘123456‘, appKey: WebIM.config.appkey, success: function (token) { console.log(‘环信登录成功‘); }, error: function(){ } }) },
8.发送消息,图片
// 发送消息与表情图一样是发送文本 onSend () { this.ishowEmoji = false; let self = this; let id = this.$imConn.getUniqueId(); // 生成本地消息id let msg = new WebIM.message(‘txt‘, id); // 创建文本消息 msg.set({ msg: this.messageValue, // 消息内容 to: this.forumUserData.phone, // 接收消息对象(用户id) roomType: false, success: function (id, serverMsgId) { self.chatContent.push({ // userLogo: self.userInfo.logoPath, msg: self.messageValue, from: self.userInfo.phoneMobile, msg_type: ‘txt‘, timestamp:new Date().getTime(), isShowTime:self.timestampStatus() }); //处理表情已图片展示 self.replace_em() //清空发送输入框内容 self.messageValue = ‘‘; }, // 对成功的相关定义,sdk会将消息id登记到日志进行备份处理 fail: function(e){ console.log("Send private text error"); } // 对失败的相关定义,sdk会将消息id登记到日志进行备份处理 }); this.$imConn.send(msg.body); }, //发送图片 sendImg (e) { this.ishowEmoji = false; let file = e.target.files[0]; let self = this; if(file) { let type = ‘image/gif image/png image/jpeg image/jpg‘; if(type.indexOf(file.type) != -1) { let id = this.$imConn.getUniqueId();// 生成本地消息id let msg = new WebIM.message(‘img‘, id);// 创建图片消息 let imgFile = WebIM.utils.getFileUrl(this.$refs.imgFile); // 将图片转化为二进制文件 let imgMsg = {}; let option = { apiUrl: WebIM.config.apiURL, file: imgFile, to: self.forumUserData.phone,// 接收消息对象 roomType: false, timestamp:new Date().getTime(), onFileUploadError: (error) => { // 消息上传失败 // console.log(error,‘失败‘); }, onFileUploadComplete: img => { // 消息上传成功 // console.log(‘onFileUploadComplete‘, img); imgMsg = { // userLogo: self.userInfo.logoPath, url: `${img.uri}/${img.entities[0].uuid}`, from: self.userInfo.phoneMobile, msg_type: ‘img‘, timestamp:new Date().getTime(), isShowTime:self.timestampStatus() }; }, success: res => { // 消息发送成功 self.chatContent.push(imgMsg); //滚动条置底部 setTimeout(() => { document.getElementById(‘refresh-box‘).scrollTop = document.getElementById(‘refresh-box‘).scrollHeight + 50;//加50是因为还有发送输入框 }, 100); // console.log(‘Success‘,res); }, flashUpload: WebIM.flashUpload }; msg.set(option); this.$imConn.send(msg.body); }else { alert(‘图片上传仅支持jpg、jpeg、png、gif格式‘); return; } } }, //处理表情图片展示, replace_em () { this.chatContent.forEach(item => { if(item.msg_type == ‘txt‘) { let reg = new RegExp(‘\\[(.*?)\\]‘,"g"); item.msg = item.msg.replace(reg, (word) => { let emoji = WebIM.Emoji.map[word]; let img = word // let imgPath = `${WebIM.Emoji.path}${emoji}`; // require if(emoji) { let path = require(‘./../../../../../assets/images/faces/‘+emoji); img = `<img src="${path}" />` } return img }); setTimeout(() => { document.getElementById(‘refresh-box‘).scrollTop = document.getElementById(‘refresh-box‘).scrollHeight + 50;//加50是因为还有发送输入框 }, 100); } }) }, //处理是否要显示时间状态,返回true,false timestampStatus () { let data = this.chatContent[this.chatContent.length - 1]; //聊天列表的最后的一次数据 let isShowTime = false; if (data) { //判断是否有上一次的聊天记录, let startTime = new Date(data.timestamp); //上一次的记录时间 let endTime = new Date().getTime(); //当前发送的时间 if (endTime-startTime>=180000) { //当前的时间大于上一次的时间3分钟则显示时间,否则不显示 isShowTime = true; }else{ isShowTime = false } }else{ //没有聊天记录则是第一条聊天记录显示时间 isShowTime = true; } return isShowTime; }
接收消息存储在vuex全部变量 ,在组件内监听数据变化自行处理接收数据
原文地址:https://www.cnblogs.com/yuwenyan/p/11364141.html
时间: 2024-11-05 13:34:23