基于环信SDK的IM即时通讯填坑之路(vue)

公司最近使用第三方环信SDK的进行通信聊天,基本已完成。记录下填坑之路

1、可以通过以下方式引用 WebSDK

1.安装

npm install easemob-websdk --save

2. 先 require ,再访问 Web IM 。

require('easemob-websdk'); 

注:该方式只引用了 Web SDK ,仍需在项目里配置 WebIMConfig 文件内的参数,用于实例化 websdk。
配置在 webim.config.js 文件内进行以下配置:

xmppURL: 'im-api.easemob.com',            // xmpp Server地址,对于在console.easemob.com创建的appKey,固定为该值
 
apiURL: 'http://a1.easemob.com',          // rest Server地址,对于在console.easemob.com创建的appkey,固定为该值
 
appkey: 'easemob-demo#chatdemoui',        // App key
 
https : false,                            // 是否使用https
 
isHttpDNS: true,                         //防止DNS劫持从服务端获取XMPPUrl、restUrl
 
isMultiLoginSessions: false,              // 是否开启多页面同步收消息,注意,需要先联系商务开通此功能
 
isAutoLogin: true,                        // 自动出席,(如设置为false,则表示离线,无法收消息,需要在登录成功后手动调用conn.setPresence()才可以收消息)
 
isDebug: false,                           // 打开调试,会自动打印log,在控制台的console中查看log
 
autoReconnectNumMax: 2,                   // 断线重连最大次数
 
autoReconnectInterval: 2,                 // 断线重连时间间隔
 
heartBeatWait: 4500,                       // 使用webrtc(视频聊天)时发送心跳包的时间间隔,单位ms
 
delivery: true,                           // 是否发送已读回执

2、组件中使用(群聊)

这里以群聊为例子

注册

regeister(id,name) {        
     var options = {
          username: id,//用户名
          password: md5(id),//密码
          nickname: name,//昵称
          appKey: WebIM.config.appkey,//appkey
          success: e => {
            console.log('注册成功', e);
            if (e) {
              localStorage.setItem("liveUser", id);//注册成功将id保存
              this.login()//去登录
            }
          },
          error: e => {
            console.log("注册异常",e);
            if(e.type == 17){//如果已注册 则登录
              console.log("注册异常去登陆",e);
              localStorage.setItem("liveUser", id);
              this.login();
            }
          },
          apiUrl: WebIM.config.apiURL
        };
        WebIM.conn.registerUser(options);
},

1、这里如果注册异常的type==17则代表已注册,那就直接去登录

2、这里id是依据是否在应用内已登录(自己应用,非环信),

如果是未登录(游客状态)则随机一个

Math.ceil(Math.random() * 100000);

如果登录,则用登录后返回的user_id

登录

//环信登录
login() {
        var userName = localStorage.getItem("liveUser");
        var options = {
          apiUrl: WebIM.config.apiURL,
          user: userName,
          pwd: md5(userName),
          appKey: WebIM.config.appkey,
          success: e => {
            console.log('登录成功', e);
            if (e) {
              this.addGroup()
            }
          },
          fail: e => {
            console.error('登录失败', e);
          }
        };
        WebIM.conn.open(options);
},

登录成功后就可以加入群组

 

加入群组

//加入群组
addGroup() {
        var options = {
          groupId: "xxxx",   // 群组ID
          success: function (resp) {
            console.log("Response: ", resp);
          },
          error: function (e) {
            console.error("加入群聊异常", e, JSON.parse(e.data));
            if (e.type == 17) {
              console.error("您已经在这个群组里了");
            }
          }
        };
        WebIM.conn.joinGroup(options);
 },

这里群id是你购买环信后创建应用分配的群id

加群成功,就可以获取群历史消息了

获取历史消息

getMessList() {
        var options = {
          queue: "xxxx",//群组id
          isGroup: true,//是否是群聊
          count: 20,//返回多少条
          success: data => {
            this.$store.dispatch('receive_livemsglist',data)//这里把消息加到vuex中存储
 
            this.messList = this.$store.state.liveMsgList
 
            console.log("获取历史消息", data)
          },
          fail: e => {
            console.log("获取群聊异常", e)
          }
        };
 
        WebIM.conn.fetchHistoryMessages(options);
      },

1、不能依据页码获取数据

这里环信有个bug(也不能说bug,一个不足吧),就是获取历史消息竟然不是依据页码去拉取,也就是我拉取哪一页就获取哪一页。没办法,环信没有提供这个参数。

给环信提供了工单,他那边反馈

解决

先说下,上面这个问题,就是用本地vuex存储了.

vuex的state中

export default {
  liveMsgList:[],//消息记录
}

mutations.js中

//消息记录
  [RECEIVE_LIVEMSGLIST](state,{liveMsgList}){
    if(state.liveMsgList.length){
      state.liveMsgList.unshift(...liveMsgList)
    }else{
      state.liveMsgList = liveMsgList
    }
  },

actions.js中

receive_livemsglist({commit},liveMsgList){
    commit(RECEIVE_LIVEMSGLIST,{liveMsgList})
  },

2、获取历史消息时,会触发监听接收消息事件

解决

这个是3.0.7 版本 SDK 的已知bug,建议您更新下SDK

监听消息

//环信接收消息
      _IMListen() {
        WebIM.conn.listen({
          onOpened: () => {          //连接成功回调
            console.log("连接成功!")
          },
          //文本消息
          onTextMessage: text => {
            console.log("接收到了文本消息", text);
            if (!text.error && text.type != "chat") {
              this.messList.push(text);
            }
          },
          //连接关闭回调
          onClosed: function ( message ) {
            console.log("连接关闭!",message)
          },         
          //收到表情消息
          onEmojiMessage: emj => {
            console.log("接收到了表情消息", emj)
            if (!emj.error && emj.type != "chat") {
              this.messList.push(emj);
            }
          },
          //cmd消息
          onCmdMessage:  ( message ) => {
            console.log(message,"cmd")
          },
          //收到自定义消息
          onCustomMessage: ( message ) => {
            console.log(message,"Custom")
          },
          onError: e => {
            console.log("接收消息错误", JSON.stringify(e));
          },
          onRecallMessage:(e)=>{
            console.log("消息撤回",e)
          },
        });
      },

发送消息

sendMess() {
        var id = WebIM.conn.getUniqueId(); // 生成本地消息id
        var msg = new WebIM.message("txt", id); // 创建文本消息
        var option = {
          msg: this.message, // 消息内容
          to: "xxx", // 接收消息对象(聊天室id)
          roomType: false, // 群聊类型,true时为聊天室,false时为群组
          ext: {}, // 扩展消息
          success: (id, serverMsgId) => {
            console.log("发送消息成功",serverMsgId)
          },
          fail: e => {
            console.error("发送消息异常", e)
          }
        };
        msg.set(option);
        msg.setGroup("groupchat"); // 群聊类型
        WebIM.conn.send(msg.body);
      }
    },

大致流程就这样,不懂的可以评论能解决就会回答。

 

 

posted @ 2020-05-12 17:53  蓝胖子1096  阅读(1110)  评论(0编辑  收藏  举报