微信小程序 -- 原生JS集成腾讯IM实时聊天功能(持续更新 更新时间2020-11-12)

   日期:2020-11-13     浏览:197    评论:0    
核心提示:最近公司微信小程序需要集成腾讯IM实现实时聊天功能,这篇文章就记录我在集成过程中所踩得坑和心得首先第一步: 当然是进官网读文档文档地址 : https://cloud.tencent.com/document/product/269/36838第一个看到的就是这个一分钟跑通demo(实际上我感觉看了跟没看一样,没啥太大帮助)也就清楚了一下前期准备工作:首先你要有一个可用的腾讯云账号然后你需要登录 及时 通信IM控制台在控制台中添加新应用创建应用后点进去可以拿到应用的 SDKAppId 以及

最近公司微信小程序需要集成腾讯IM实现实时聊天功能,这篇文章就记录我在集成过程中所踩得坑和心得

首先第一步: 当然是进官网读文档
文档地址 : https://cloud.tencent.com/document/product/269/36838
第一个看到的就是这个一分钟跑通demo(实际上我感觉看了跟没看一样,没啥太大帮助)也就清楚了一下前期准备工作:

  1. 首先你要有一个可用的腾讯云账号
  2. 然后你需要登录 即时通信IM控制台
  3. 在控制台中添加新应用
  4. 创建应用后点进去可以拿到应用的 SDKAppId 以及 密钥
  5. 注意:大哥些这里可以把demo源文件下载下来,一会儿有大用处

接下来继续翻,真正符合我需求的还是文档 常规集成 这一块


根据文档要求先将依赖搞好(其实也可以直接在源文件里面把 tim-wx.js 直接拷过来放你项目里也行)

// IM 小程序 SDK
npm install tim-wx-sdk --save
// 发送图片、文件等消息需要的 COS SDK
npm install cos-wx-sdk-v5 --save

依赖安好,引用,搞到这里我就出现了第一个问题,搞得我头痛,我引用依赖后报了个错误

import TIM from '../../tim-wx-sdk/tim-wx';


一开始把我搞蒙了,然后就当然网上查,然后得到的信息是小程序开启ES6转码后async函数无法使用,说到底就是这依赖语法用得有点高呗,然后网上给的解决办法最为直接有效的有两种(都是在小程序项目详情的本地设置里处理):

  1. 关了ES6 转 ES5 (我当时就否决了,他娘的这个一关我小程序其它地方不得崩死?谁还不用点es6啊)
  2. 开启增强编译( 这就好办了,立刻我就把增强编译打开了 注意:如果你没有这个选项,你就更新你的开发者工具,别用老古董版本了)

然后我满怀希望的再次编译得到的还是它(当时我就急了,网友这不骗人吗!!!)

然后又是慢慢网搜路,还是不知道哪儿出问题了 就是不行…最后的最后,被我找到了,还是本地设置里

我他娘的用了老古董调试基础库= =(怪我,不该质疑无私的码友们)我火速改到最新的!!!

然后就不报错了!!!泪目啊泪目,我算是把第一个坑踩过了

接下来就是按部就班初始化im了(直接把文档的扒下来就行)

  init_TIM() { //初始化im实时聊天
    let options = { 
      SDKAppID: 0// 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
    };
  
    let that = this
    // 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
    this.tim = TIM.create(options);// SDK 实例通常用 tim 表示
    // 设置 SDK 日志输出级别,详细分级请参见 setLogLevel 接口的说明
    this.tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
    // tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用
    // 注册 COS SDK 插件
    // tim.registerPlugin({'cos-wx-sdk': COS})
  
    // 监听事件,例如:
    this.tim.on(TIM.EVENT.SDK_READY, function(event) { 
      // 收到离线消息和会话列表同步完毕通知,接入侧可以调用 sendMessage 等需要鉴权的接口
      // event.name - TIM.EVENT.SDK_READY
    });
  
    this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, function(event) { 
      // 收到推送的单聊、群聊、群提示、群系统通知的新消息,可通过遍历 event.data 获取消息列表数据并渲染到页面
      // event.name - TIM.EVENT.MESSAGE_RECEIVED
      // event.data - 存储 Message 对象的数组 - [Message]
    });
  
    this.tim.on(TIM.EVENT.MESSAGE_REVOKED, function(event) { 
      // 收到消息被撤回的通知
      // event.name - TIM.EVENT.MESSAGE_REVOKED
      // event.data - 存储 Message 对象的数组 - [Message] - 每个 Message 对象的 isRevoked 属性值为 true
    });
  
    this.tim.on(TIM.EVENT.MESSAGE_READ_BY_PEER, function(event) { 
      // SDK 收到对端已读消息的通知,即已读回执。使用前需要将 SDK 版本升级至 v2.7.0 或以上。仅支持单聊会话。
      // event.name - TIM.EVENT.MESSAGE_READ_BY_PEER
      // event.data - event.data - 存储 Message 对象的数组 - [Message] - 每个 Message 对象的 isPeerRead 属性值为 true
    });
  
    this.tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATeD, function(event) { 
      // 收到会话列表更新通知,可通过遍历 event.data 获取会话列表数据并渲染到页面
      // event.name - TIM.EVENT.CONVERSATION_LIST_UPDATED
      // event.data - 存储 Conversation 对象的数组 - [Conversation]
    });
  
    this.tim.on(TIM.EVENT.GROUP_LIST_UPDATED, function(event) { 
      // 收到群组列表更新通知,可通过遍历 event.data 获取群组列表数据并渲染到页面
      // event.name - TIM.EVENT.GROUP_LIST_UPDATED
      // event.data - 存储 Group 对象的数组 - [Group]
    });
  
    this.tim.on(TIM.EVENT.PROFILE_UPDATED, function(event) { 
      // 收到自己或好友的资料变更通知
      // event.name - TIM.EVENT.PROFILE_UPDATED
      // event.data - 存储 Profile 对象的数组 - [Profile]
    });
  
    this.tim.on(TIM.EVENT.BLACKLIST_UPDATED, function(event) { 
      // 收到黑名单列表更新通知
      // event.name - TIM.EVENT.BLACKLIST_UPDATED
      // event.data - 存储 userID 的数组 - [userID]
    });
  
    this.tim.on(TIM.EVENT.ERROR, function(event) { 
      // 收到 SDK 发生错误通知,可以获取错误码和错误信息
      // event.name - TIM.EVENT.ERROR
      // event.data.code - 错误码
      // event.data.message - 错误信息
    });
  
    this.tim.on(TIM.EVENT.SDK_NOT_READY, function(event) { 
      // 收到 SDK 进入 not ready 状态通知,此时 SDK 无法正常工作
      // event.name - TIM.EVENT.SDK_NOT_READY
    });
  
    this.tim.on(TIM.EVENT.KICKED_OUT, function(event) { 
      // 收到被踢下线通知
      // event.name - TIM.EVENT.KICKED_OUT
      // event.data.type - 被踢下线的原因,例如:
      // - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多实例登录被踢
      // - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多终端登录被踢
      // - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 签名过期被踢 (v2.4.0起支持)。 
    });
  
    this.tim.on(TIM.EVENT.NET_STATE_CHANGE, function(event) {  
      // 网络状态发生改变(v2.5.0 起支持)。 
      // event.name - TIM.EVENT.NET_STATE_CHANGE 
      // event.data.state 当前网络状态,枚举值及说明如下: 
      // \- TIM.TYPES.NET_STATE_CONNECTED - 已接入网络 
      // \- TIM.TYPES.NET_STATE_CONNECTING - 连接中。很可能遇到网络抖动,SDK 在重试。接入侧可根据此状态提示“当前网络不稳定”或“连接中” 
      // \- TIM.TYPES.NET_STATE_DISCONNECTED - 未接入网络。接入侧可根据此状态提示“当前网络不可用”。SDK 仍会继续重试,若用户网络恢复,SDK 会自动同步消息 
    });
  
    console.log('执行了init');
    // this.login_TIM();
  },

调用 , 执行


看到这一串大宝贝儿,我就舒了口气,成功了嘛,那接下来我就登陆嘛!

login_TIM() { //登录im实时聊天
    let promise = this.tim.login({ userID: '', userSig: ''});
    promise.then(function(imResponse) { 
      console.log(imResponse.data); // 登录成功
      if (imResponse.data.repeatLogin === true) { 
        // 标识账号已登录,本次登录操作为重复登录。v2.5.1 起支持
        console.log(imResponse.data.errorInfo);
      }
    }).catch(function(imError) { 
      console.warn('login error:', imError); // 登录失败的相关信息
    });
  },

到这里userID随便填一个测试的就行,那userSig不行啊,要计算啊,那我就看文档 : https://cloud.tencent.com/document/product/269/32688
他倒是给了客户端计算的方法和源码


下载下来一看源码

global.webpackJsonpMpvue([18],{ 
 "dutN":
 (function(module, __webpack_exports__, __webpack_require__) { 

"use strict";
 __webpack_require__.d(__webpack_exports__, "a", function() {  return _SDKAPPID; });
 __webpack_require__.d(__webpack_exports__, "b", function() {  return genTestUserSig; });
 var __WEBPACK_IMPORTED_MODULE_0__lib_generate_test_usersig_es_min_js__ = __webpack_require__("n7IX");



const _SDKAPPID = 0;
const _SECRETKEY = '';

function genTestUserSig(userID) { 
  
  var SDKAPPID = _SDKAPPID;

  
  var EXPIRETIME = 604800;


  
  var SECRETKEY = _SECRETKEY;
  
  var generator = new __WEBPACK_IMPORTED_MODULE_0__lib_generate_test_usersig_es_min_js__["a" ](SDKAPPID, SECRETKEY, EXPIRETIME);
  var userSig = generator.genTestUserSig(userID);
  return { 
    sdkappid: SDKAPPID,
    userSig: userSig
  };
}
 })
});

好家伙你倒是用了Vue模板去搞,我要是不用Vue,你让我原生js怎么去引,怎么去用,他娘的,这算是第二个坑了嘛,又开始网搜,最后的最后,我们下在的demo源文件发挥大作用了


这个文件路径下面有两个js文件


把这两个甩到项目里去再去引用这个 GenerateTestUserSig.js 文件,他是好孩子,是原生的

引用

import {  genTestUserSig } from '../../utils/GenerateTestUserSig'

输出

  onLoad:function(){ 
    console.log(genTestUserSig('TEST-1'));
  },

打印


乖乖 , 总算是有了,至此第二个坑踩完了(这里我要吐槽一下开发文档,你他娘的有原生的就不能告知一下?非要人自己去找)

接下来登录(注意:userID必须是字符串类型)

  login_TIM() { //登录im实时聊天
    let promise = this.tim.login({ userID: 'TEST-1', userSig: genTestUserSig('TEST-1').userSig});
    promise.then(function(imResponse) { 
      console.log(imResponse.data); // 登录成功
      if (imResponse.data.repeatLogin === true) { 
        // 标识账号已登录,本次登录操作为重复登录。v2.5.1 起支持
        console.log(imResponse.data.errorInfo);
      }
    }).catch(function(imError) { 
      console.warn('login error:', imError); // 登录失败的相关信息
    });
  },

OJBK ! 成了,总算了给他登进去了

--------更新割----------

接下来就是收发消息了,看了下文档,这就比较简单跑通了直接调接口,官方文档还是写得很通俗易懂了

// 发送文本消息,Web 端与小程序端相同
// 1. 创建消息实例,接口返回的实例可以上屏
let message = tim.createTextMessage({ 
  to: 'user1',
  conversationType: TIM.TYPES.CONV_C2C,
  // 消息优先级,用于群聊(v2.4.2起支持)。如果某个群的消息超过了频率限制,后台会优先下发高优先级的消息,详细请参考:https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
  // 支持的枚举值:TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL(默认), TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
  // priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
  payload: { 
    text: 'Hello world!'
  }
});
// 2. 发送消息
let promise = tim.sendMessage(message);
promise.then(function(imResponse) { 
  // 发送成功
  console.log(imResponse);
}).catch(function(imError) { 
  // 发送失败
  console.warn('sendMessage error:', imError);
});

执行后打印如下


然后看看我在收消息的那方获取到的信息(这里是通过最开始 tim.on(TIM.EVENT.MESSAGE_RECEIVED, function(event) {}所监听到的事件)


当然还有发送图片消息,音频消息,文件消息等等,官方文档还是写得很清楚,也没碰到什么坑,所以我就不一一列出了.至此腾讯im主要的功能算是完全跑通了,接下来就是按照自己的项目需求继续开发了.然后我将整个腾讯IM的初始化/登录/发送消息等都放到了一个js文件中,这里就贴上来供大家参考下:

  const app = getApp() //获取APP.js便于设置操作全局变量
  
  import TIM from '../tim-wx-sdk/tim-wx';
  import {  genTestUserSig } from '../tim-wx-sdk/GenerateTestUserSig'

  var tim = '';

  function init_TIM() { //初始化im实时聊天
    if(app.globalData_TIM.isInit){ 
      //这里设置了一个全局变量isLogin来标记是否已登录,避免重复创建im实例
      return false
    }
    let options = { 
      SDKAppID: 0// 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
    };
    
    let that = this
    // 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
    tim = TIM.create(options);// SDK 实例通常用 tim 表示
    // 设置 SDK 日志输出级别,详细分级请参见 setLogLevel 接口的说明
    tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
    // tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用
    // 注册 COS SDK 插件 此处暂时隐藏有需求要传图片,文件等的请放开进行配置,记住头部引入
    // tim.registerPlugin({'cos-wx-sdk': COS})
  
    // 监听事件,例如:
    tim.on(TIM.EVENT.SDK_READY, function(event) { 
      // 收到离线消息和会话列表同步完毕通知,接入侧可以调用 sendMessage 等需要鉴权的接口
      // event.name - TIM.EVENT.SDK_READY
    });
  
    tim.on(TIM.EVENT.MESSAGE_RECEIVED, function(event) { 
      console.log('收到消息');
      // 收到推送的单聊、群聊、群提示、群系统通知的新消息,可通过遍历 event.data 获取消息列表数据并渲染到页面
      // event.name - TIM.EVENT.MESSAGE_RECEIVED
      // event.data - 存储 Message 对象的数组 - [Message]
    });
  
    tim.on(TIM.EVENT.MESSAGE_REVOKED, function(event) { 
      // 收到消息被撤回的通知
      // event.name - TIM.EVENT.MESSAGE_REVOKED
      // event.data - 存储 Message 对象的数组 - [Message] - 每个 Message 对象的 isRevoked 属性值为 true
    });
  
    tim.on(TIM.EVENT.MESSAGE_READ_BY_PEER, function(event) { 
      // SDK 收到对端已读消息的通知,即已读回执。使用前需要将 SDK 版本升级至 v2.7.0 或以上。仅支持单聊会话。
      // event.name - TIM.EVENT.MESSAGE_READ_BY_PEER
      // event.data - event.data - 存储 Message 对象的数组 - [Message] - 每个 Message 对象的 isPeerRead 属性值为 true
    });
  
    tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATeD, function(event) { 
      // 收到会话列表更新通知,可通过遍历 event.data 获取会话列表数据并渲染到页面
      // event.name - TIM.EVENT.CONVERSATION_LIST_UPDATED
      // event.data - 存储 Conversation 对象的数组 - [Conversation]
    });
  
    tim.on(TIM.EVENT.GROUP_LIST_UPDATED, function(event) { 
      // 收到群组列表更新通知,可通过遍历 event.data 获取群组列表数据并渲染到页面
      // event.name - TIM.EVENT.GROUP_LIST_UPDATED
      // event.data - 存储 Group 对象的数组 - [Group]
    });
  
    tim.on(TIM.EVENT.PROFILE_UPDATED, function(event) { 
      // 收到自己或好友的资料变更通知
      // event.name - TIM.EVENT.PROFILE_UPDATED
      // event.data - 存储 Profile 对象的数组 - [Profile]
    });
  
    tim.on(TIM.EVENT.BLACKLIST_UPDATED, function(event) { 
      // 收到黑名单列表更新通知
      // event.name - TIM.EVENT.BLACKLIST_UPDATED
      // event.data - 存储 userID 的数组 - [userID]
    });
  
    tim.on(TIM.EVENT.ERROR, function(event) { 
      // 收到 SDK 发生错误通知,可以获取错误码和错误信息
      // event.name - TIM.EVENT.ERROR
      // event.data.code - 错误码
      // event.data.message - 错误信息
    });
  
    tim.on(TIM.EVENT.SDK_NOT_READY, function(event) { 
      // 收到 SDK 进入 not ready 状态通知,此时 SDK 无法正常工作
      // event.name - TIM.EVENT.SDK_NOT_READY
    });
  
    tim.on(TIM.EVENT.KICKED_OUT, function(event) { 
      // 收到被踢下线通知
      // event.name - TIM.EVENT.KICKED_OUT
      // event.data.type - 被踢下线的原因,例如:
      // - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多实例登录被踢
      // - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多终端登录被踢
      // - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 签名过期被踢 (v2.4.0起支持)。 
    });
  
    tim.on(TIM.EVENT.NET_STATE_CHANGE, function(event) {  
      // 网络状态发生改变(v2.5.0 起支持)。 
      // event.name - TIM.EVENT.NET_STATE_CHANGE 
      // event.data.state 当前网络状态,枚举值及说明如下: 
      // \- TIM.TYPES.NET_STATE_CONNECTED - 已接入网络 
      // \- TIM.TYPES.NET_STATE_CONNECTING - 连接中。很可能遇到网络抖动,SDK 在重试。接入侧可根据此状态提示“当前网络不稳定”或“连接中” 
      // \- TIM.TYPES.NET_STATE_DISCONNECTED - 未接入网络。接入侧可根据此状态提示“当前网络不可用”。SDK 仍会继续重试,若用户网络恢复,SDK 会自动同步消息 
    });
    app.globalData_TIM.isInit = true;  //完成im实例创建后设置标志为true
  }

  function login_TIM(userID) { //登录im实时聊天 
    let promise = tim.login({ userID: userID, userSig: genTestUserSig(userID).userSig});
    promise.then(function(imResponse) { 
      console.log('登录成功')
      console.log(imResponse.data); // 登录成功
      if (imResponse.data.repeatLogin === true) { 
        // 标识账号已登录,本次登录操作为重复登录。v2.5.1 起支持
        console.log('当前重复登录')
        console.log(imResponse.data.errorInfo);
      }
    }).catch(function(imError) { 
      console.warn('login error:', imError); // 登录失败的相关信息
    });
  }

  function sendMessage_TIM( sendTo , msg ) { 
  	//这里是文字消息的发送,有需求可以增加个type参数控制发送方式,文字/图片/音视频/文件 调用不同的tim接口
    let message = tim.createTextMessage({ 
      to: sendTo,
      conversationType: TIM.TYPES.CONV_C2C,
      payload: { 
        text: msg
      }
    });
    let promise = tim.sendMessage(message);
    promise.then(function(imResponse) { 
      // 发送成功
      console.log('发送成功')
      console.log(imResponse);
    }).catch(function(imError) { 
      // 发送失败
      console.log('发送失败')
      console.warn('sendMessage error:', imError);
    });
  }
  
  function logout_TIM() { 
    let promise = tim.logout();
    promise.then(function(imResponse) { 
      console.log(imResponse.data); // 登出成功
    }).catch(function(imError) { 
      console.warn('logout error:', imError);
    });
  }

//导出初始化,登录,消息发送接口供外部使用
module.exports = { 
  init_TIM,
  login_TIM,
  logout_TIM,
  sendMessage_TIM
}

在需要使用的页面通过以下方式使用

const app = getApp()

//头部引用
import {  init_TIM,login_TIM,sendMessage_TIM,logout_TIM } from '../../../js/tim-init';  

Page({ 
  data: { 
   userID: ''
  },
  onLoad() { 
    init_TIM();//在需要的页面初始化
  },
  loginTim() { 
    login_TIM(this.data.userID);//根据页面需求登录并传入登录userID
  },
  logoutTim() { 
    logout_TIM();//根据页面需求登出
  },
  sendMessage() { 
    sendMessage_TIM(sendTo ,msg) //sendTo为信息接受者的userID , msg为消息数据
  }
})
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服