Vue 集成环信 全局封装环信WebSDK


1 安装  vue

npm install easemob-websdk --save    官方安装 ,这种安装要在依赖包配置初始化连接,提交代码时并没把配置提交 

使用 hx-websdk 安装web

npm install --save hx-websdk  

 2 .使用 新建一个webim.js  放在聊天窗口组件同一层级,为了Emoji图片路径同步vuex

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-webrtcnpm

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 = /(?<=_).*(?=@)/
      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 = /(?<=_).*(?=@)/
      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 .组件使用或者全局使用api

// 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.发送消息,图片app

 // 发送消息与表情图同样是发送文本
    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所有变量 ,在组件内监听数据变化自行处理接收数据

相关文章
相关标签/搜索