最近在作一款有语音直播功能的小程序,用到了环信IM集成功能,因为我搜了下目前用环信作小程序的的确是少之又少,并且环信官方说从2月份再也不更新代码(具体缘由我也没问,可能自己微信就是一款聊天工具因此用处不大)ajax
咱们产品须要用到聊天室功能,以前作H5端登陆完成以后加入聊天室便可:小程序
WebIM.conn.open(options); WebIM.conn.joinChatRoom(option1);
一样方法在小程序上不行,一直报错:api
Cannot read property 'sendIQ' of undefined
百度了一下,说加入聊天室要放在登陆成功后的回调里,因而查看它的源码connection.js发现:微信
connection.prototype.open = function (options) { var pass = _validCheck(options, this); if (!pass) { return; } var conn = this; if (conn.isOpening() || conn.isOpened()) { return; } if (options.accessToken) { options.access_token = options.accessToken; _login(options, conn); } else { //登陆成功的回调函数 var suc = function (data, xhr, myName) { conn.context.status = _code.STATUS_DOLOGIN_IM; conn.context.restTokenData = data; if (data.statusCode != '404' && data.statusCode != '400') { wx.showToast({ title: '登陆成功', icon: 'none', duration: 4000 }); } //回调成功后执行这个方法 _login(data.data, conn); }; var options = { url: apiUrl + '/' + orgName + '/' + appName + '/token', data: loginfo, success: suc || _utils.emptyfn, error: error || _utils.emptyfn }; _utils.ajax(options); }
登陆成功有一个内部回调,回调里面调用了一个 _login(data.data, conn)的方法:app
//具体里面执行什么去源代码查看,我就不贴代码了 var _login = function (options, conn) { var callback = function (status, msg) { _loginCallback(status, msg, conn); }; };
执行完login方法有一个_loginCallback回调:函数
var _loginCallback = function (status, msg, conn) { var conflict, error; //console.log('_loginCallback 1', Strophe.Status, status, msg) if (msg === 'conflict') { conflict = true; } console.log(status) if (status == Strophe.Status.CONNFAIL) { } else if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED) { //登陆成功 } else if (status == Strophe.Status.DISCONNECTING) { } else if (status == Strophe.Status.DISCONNECTED) { } else if (status == Strophe.Status.AUTHFAIL) { } else if (status == Strophe.Status.ERROR) { } conn.context.status_now = status; };
经过断点发现当执行到 else if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED)时,登陆成功.因此须要把加入聊天室的回调须要放在这个判断里面,个人具体作法以下:工具
//项目中封装一个加入聊天室函数 joinRoom: function () { var option1 = {}; var option2 = {}; //加入聊天室 WebIM.conn.joinChatRoom(option1); WebIM.conn.joinChatRoom(option2); }; //在环信登陆函数中添加一个本身的回调: var options = { apiUrl: WebIM.config.apiURL, user: userId + '', pwd: userId + '', grant_type: "password", appKey: WebIM.config.appkey, //本身添加的回调函数 callBack:function(){ //调用加入聊天室 that.joinRoom(); } }; WebIM.conn.open(options);
修改环信connection.js代码:this
//登陆代码 connection.prototype.open = function (options) { var suc = function (data, xhr, myName) { //callBack传入加入聊天室回调 _login(data.data, conn, options.callBack); }; var options = { url: apiUrl + '/' + orgName + '/' + appName + '/token', data: loginfo, success: suc || _utils.emptyfn, //添加加入聊天室的回调函数 callBack: options.callBack, error: error || _utils.emptyfn }; } }; //_login代码 var _login = function (options, conn, callBack) { var callback = function (status, msg) { //把加入聊天室函数传给_login回调函数 _loginCallback(status, msg, conn, callBack); }; }; //_loginCallback代码 var _loginCallback = function (status, msg, conn,callBack) { var conflict, error; //console.log('_loginCallback 1', Strophe.Status, status, msg) if (msg === 'conflict') { conflict = true; } console.log(status) if (status == Strophe.Status.CONNFAIL) { } else if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED) { //登陆成功执行加入聊天室 callBack(); } else if (status == Strophe.Status.DISCONNECTING) { } else if (status == Strophe.Status.DISCONNECTED) { } else if (status == Strophe.Status.AUTHFAIL) { } else if (status == Strophe.Status.ERROR) { } conn.context.status_now = status; };
具体思路就是这样,因为环信小程序代码有不少坑,因此遇到问题多看看源码,有些功能就须要本身去修改代码,这是环信工单回答个人问题:url