一、前言
IM即时通讯(Instant Messaging),实时通信系统,允许二人或多人使用网络实时的传递文字消息、文件、语音或视频交流。美家技术团队在项目早期中应用到了环信IM,其中踩了不少坑。
-
早期技术选型中,通信两端采用不同的前端技术体系,面向B端的采用了 mpvue
,面向C端用户使用了原生微信小程序开发,因此当时遇到了大坑,环信的小程序版(原生)sdk 不适合mpvue
(vue),改造sdk根本不现实,文件依赖引用太多了,改不动[旺柴]。最后的改造方案是聊天IM页面依然使用原生微信小程序,混合mpvue使用,实现了B、C端的通信。 -
引入该 sdk 极易导致微信小程序主包过大(小程序主包2M限制),只能将该sdk单独分包 -
每次修改了涉及IM的部分,必须重新运行编译,热刷新不生效
2019.7 C端逛逛美家使用uniapp
重构,又遇到了一大问题,环信IM小程序sdk,在uniapp中的并非完全适用,经历再次改造。原生小程序的页面不能用,此处改成了vue,通信websocket建立起来了,B端能发消息,C端能收到;C端发的消息,然而B端却收不到。最后还是把C端的聊天界面全部推到,重新编写才能收发消息。此处只支持文本发送,像视频,图片,语音,定位等的功能都屏蔽了,因为需要改造对应的环信sdk小程序组件。最后变成了阉割版的文字聊天。
后面随着业务的扩展已经产品的迭代,该IM聊天咨询功能已不能满足需求,至少在该基础上仅有的文字聊天
满足不了。需求还涉及到自定义消息,系统消息,未读消息等等。在此基础上,简单对比了两款产品的优劣。
二、腾讯云IM和环信IM应用比较
IM平台 | 厂家 | 通信方式 | 易用性 | 扩展性 | 客服 | 引用方式 | 在线文档手册 |
---|---|---|---|---|---|---|---|
腾讯云IM | 腾讯 | polling 轮询 | 易,文档详实,包含相应的短视频介绍,实例丰富 | 丰富,自定义消息,系统消息,未读消息 | 在线工单 | npm 包模块 | 产品手册 (https://main.qcloudimg.com/raw/document/product/pdf/269_1497_cn.pdf) 在线文档(https://cloud.tencent.com/document/product/269/37413) |
环信IM | 北京易掌云峰科技有限公司 | websocket | 较难,文档及案例较简单,建立链接后需要手动处理的逻辑复杂 | 较少 | 在线客服 | 手动copy脚步到项目下,import |
在线文档
(http://docs-im.easemob.com/im/applet/intro) |
三、腾讯云IM使用文档
本文略,详情请查看 即时通信 IM 集成 SDK(Web & 小程序)(https://cloud.tencent.com/document/product/269/37413)
四、TIM 在 uni-app 中应用
tim
初始化应用Example
// #ifdef MP-WEIXIN || APP-PLUS
// 小程序、App端使用该sdk
import TIMWX from 'tim-wx-sdk';
// #endif
// #ifdef H5
// uniapp h5版本的微信小程序SDK上传图片出现问题,不能兼容,需要单独修改
import TIMH5 from '@/static/h5/tim-wx-sdk/tim-js';
// #endif
let TIM = null;
// #ifdef MP-WEIXIN || APP-PLUS
TIM = TIMWX;
// #endif
// #ifdef H5
TIM = TIMH5;
// #endif
import COS from 'cos-wx-sdk-v5';
// 创建 SDK 实例,TIM.create() 方法对于同一个 SDKAppID 只会返回同一份实例
let options = {
SDKAppID: 0 // 接入时需要将0替换为您的即时通信应用的 SDKAppID
};
let tim = TIM.create(options); // SDK 实例通常用 tim 表示
// 设置 SDK 日志输出级别,详细分级请参见 setLogLevel 接口的说明
tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
// tim.setLogLevel(1); // release级别,SDK 输出关键信息,生产环境时建议使用
// 将腾讯云对象存储服务 SDK (以下简称 COS SDK)注册为插件,IM SDK 发送文件、图片等消息时,需要用到腾讯云的 COS 服务
// HTML5 环境,注册 COS SDK
tim.registerPlugin({'cos-js-sdk': COS});
// 微信小程序环境,注册 COS SDK
//tim.registerPlugin({'cos-wx-sdk': COS}); // 微信小程序环境请取消本行注释,并注释掉 tim.registerPlugin({'cos-js-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) {
// 收到推送的单聊、群聊、群提示、群系统通知的新消息,可通过遍历 event.data 获取消息列表数据并渲染到页面
// event.name - TIM.EVENT.MESSAGE_RECEIVED
// event.data - 存储 Message 对象的数组 - [Message]
});
tim.on(TIM.EVENT.MESSAGE_REVOKED, function(event) {
// 收到消息被撤回的通知。使用前需要将SDK版本升级至v2.4.0或以上。
// 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 会自动同步消息
});
wx.TIM = TIM; // 绑定TIM到全局对象wx下
wx.$app = tim; // 绑定tim到全局对象wx.$app下
// 开始登录
tim.login({userID: 'your userID', userSig: 'your userSig'});
uni-app支持将小程序、H5、Andorid/iOS编译打包到各平台,其中各平台均使用了IM通信功能,使用了腾讯云IM中的集成SDK(web&小程序), App 端和微信小程序均可使用小程序版 SDK
-
uni-app支持微信小程序版本,使用一般不存在问题。 -
App 中使用的问题正常,除了发送视频外,由于App中的视频使用的是原生组件,不能覆盖,滚动聊天面板的时候出现视频覆盖在内容上,影响体验效果。暂时也没有很好的解决方法,nvue的改造工作量大,先将IM聊天中的发送视频屏蔽。 -
h5 版本,小程序与h5的sdk还是有很大的区别,这里不使用小程序版,通过uni-app的条件编译使用h5版本 tim-js
-
编写条件编译,区别小程序与h5中引用的 sdk
// #ifdef MP-WEIXIN || APP-PLUS
// 小程序、App端使用该sdk
import TIMWX from 'tim-wx-sdk';
// #endif
// #ifdef H5
// uniapp h5版本的微信小程序SDK上传图片出现问题,不能兼容,需要单独修改
import TIMH5 from '@/static/h5/tim-wx-sdk/tim-js';
// #endif
-
编译运行到h5, tim
初始化成功

-
登陆 tim
账号
tim.login({userID: 'your userID', userSig: 'your userSig'});
tim
登录成功,并认证成功

-
SDK is ready
,此监听事件,回调函数中后面可以调用 sendMessage(发送消息) 等需要鉴权的接口
// 监听ready事件
tim.on(TIM.EVENT.SDK_READY, function(event) {
// 收到离线消息和会话列表同步完毕通知,接入侧可以调用 sendMessage 等需要鉴权的接口
// event.name - TIM.EVENT.SDK_READY
});

-
通过轮询收发实时信息

-
进入聊天界面,发送文字,表情正常

-
选取图片,发送报错,如何解决h5发送图片报错问题,也就解决了tim在uniapp中的兼容性

uni-app的app端其实是一个强化版的小程序引擎,所以支持小程序sdk在app端使用。但这些sdk在h5端、支付宝百度等小程序平台无法使用
解决 uni-app 在h5中使用 TIM 发送图片失败的问题
正常来说,腾讯云IM提供了小程序版以及h5版本的SDK,同时 uni-app
使用了条件编译区分了该两个不同环境下所使用的SDK,那么为什么h5还出现发送图片失败? 原因是由于TIM的全局对象wx
被 uni-app
全局对象uni
所代理,是同一个对象,即有
// 以下两个对象uni和wx比较,返回true,即为同一个对象
uni === wx

因此当 tim
的sdk判断当前运行环境(小程序还是h5环境)会出现问题(下文会贴代码),wx
已经不再是原来的单纯的那个对象,而是注入了 uni
对象的各种方法


由于该SDK不开源,找不到源码,只有压缩过后的js文件,h5 TIM SDK 地址(https://github.com/tencentyun/TIMSDK/blob/master/H5/sdk/tim-js.js)。格式化该文件,(格式化后的文件行数及变量名可能不同)
下文提到的代码行数,均指格式化后的源代码行数
分析如下:

由该格式可得,此为 umd
通用模块定义, 即为多种模块组合
!(function (window, factory) {
if ('object' == typeof exports && 'undefined' != typeof module) {
// CommonJS 模式
module.exports = factory()
} else if ('function' == typeof define && define.amd) {
// RequireJS 模式
define(factory)
} else {
// IIFE
window.TIM = factory()
}
}(this, (function (){
// *** 省略逻辑代码
// 返回Object
return {
...
}
}))
继续往下阅读,基本就是一些函数定义,暂时识别不出有意义部分。回到 TIM 的警告和报错提示

格式化源码文档中搜索 createImageMessage payload.file 的类型必须是 HTMLInputElement 或 File
,大概 6115
行,找到信息,结合报错提示 TIM [createImageMessage] Invalid params: custom validator check failed for params.

以下为点击图片上传,调用TIM的创建图片消息逻辑代码
wx.chooseImage({
sourceType: [name],
count: 1,
success: function (res) {
message = wx.$app.createImageMessage({ // 创建图片消息
to: self.$store.getters.toAccount,
conversationType: self.$store.getters.currentConversationType,
payload: {
file: res
},
onProgress: percent => {
self.percent = percent
}
})
self.$store.commit('sendMessage', message)
wx.$app.sendMessage(message).then(() => {
self.percent = 0
}).catch((err) => {
console.log(err)
})
}
})
综上, tim
创建图文消息的 payload.file
参数类型错误,该图片的文件类型是从 wx.chooseImage
中返回,一般不能更改。回到源码分析,第 6113
行,此处变量 ws
的布尔类型为 true
,才会执行报错提示代码,因此需要搜索变量 ws
所定义的位置,(小技巧,搜索的时候添加一个后面的空格,即“ws
”)

搜索得到8个结果,找到变量定义地方

var ws = "undefined" != typeof window
, Ns = "undefined" != typeof wx && "function" == typeof wx.getSystemInfoSync
, Ls = ws && window.navigator && window.navigator.userAgent || ""
// 上面使用关键字var同时定义多个变量,使用逗号分隔, 关键字 typeof 变量类型判断
// "undefined" != typeof window 判断是否为浏览器环境,window是浏览器宿主对象,true为浏览器环境,false为非浏览器环境,此处ws为true
// "undefined" != typeof wx && "function" == typeof wx.getSystemInfoSync,此处判断wx对象是否有定义,且wx.getSystemInfoSync是否为函数类型,true为小程序环境,false为非小程序环境,此处Ns变量为true
如上面所提到的,由于 wx
和 uni
为同一个对象,导致 Ns
变量为true,即此处既是浏览器环境(ws
),又是微信小程序环境(Ns
),因此使用 Ns
判断的地方有可能会出现问题
回到上面截图,源码分析,第6113
行,变量 ws
为浏览器环境,正确,结合error log信息,
TIM [createImageMessage] Invalid params: custom validator check failed for params.
,
结合 6113
行附近代码判断,此处代码为 tim
定义方法 createImageMessage
的函数参数校验器,推测错误原因应该是环境判断错误,可能是调用了小程序 wx
的专用方法(h5不支持), 因此需要继续查找真正定义方法 createImageMessage
的逻辑代码,继续搜索关键字 createImageMessage
,得到关键信息

第 13950
行,此处使用了变量 Ns
,该变量表示微信小程序环境,由于开始的环境判断异常,导致h5中的某些程序代码走了小程序的逻辑,因此此处封装的小程序环境的参数payload.file
与h5环境存在差异,不能通过 createImageMessage
方法参数校验。那么,直接修改变量 Ns
为 false
,是否就可以高枕无忧了?修改2555
行变量 Ns
为 false

重新点击发送图片[惊]

依然是之前的错误,文件参数校验失败问题,原因分析:调用 tim
方法 createImageMesssage
发送图片消息, 上面关键代码wx.chooseImage
,wx.$app.createImageMessage
先选择图片,再创建 tim
图片消息,
wx.chooseImage({
sourceType: [name],
count: 1,
success: function (res) {
// 此处选取的文件格式res可能就已经不是单纯的h5环境的文件图片格式
message = wx.$app.createImageMessage({ // 创建图片消息
to: self.$store.getters.toAccount,
conversationType: self.$store.getters.currentConversationType,
payload: {
file: res // wx.chooseImage 获取图片的格式传入 createImageMessage 并非h5的文件格式
}
})
self.$store.commit('sendMessage', message)
wx.$app.sendMessage(message).then(() => {
self.percent = 0
}).catch((err) => {
console.log(err)
})
}
})
整个项目使用uni-app
构建,那么就不是只有 tim
中的 h5 sdk
使用到了 wx
,可以说,整个项目中的 wx
全局都被 uni
劫持代理,上面的 wx.chooseImage
将选择的图片格式包装了一层,不是原生的h5文件对象。打印 wx.chooseImage
选项的图片对象,

h5文件对象的格式

窘,虽说 tim sdk
内部已修改了逻辑,但是调用 tim.createImageMessasge
的时候并不能保证传入的参数(wx.chooseImage
所得,回调中的参数并不是完全的h5文件对象(HTMLInputElement或File))能通过校验。到此,有两个修改方向
-
调用 wx.chooseImage
时,处理回调的参数response
符合h5
文件对象,类型是 HTMLInputElement 或 File -
依旧走小程序逻辑,实际调用时才统一处理 payload.file
格式
看第一种解决方向,所有h5代码处,发送图文消息 createImageMessage
时,都需要去处理 payload.file
为原生h5文件格式,尤其是多端情况下, 兼容小程序以及App,代码量大,分散,易遗漏,暂不考虑。
第二种情况,只修改 tim
的 h5 sdk
,并不涉及页面的逻辑处理。先按此思路实现。
回到代码处,变量 Ns
就不理解成微信小程序环境了,在此应该理解成统一封装了API的超集。
撤销源码第 2555
行变量 Ns
的修改
, Ns = "undefined" != typeof wx && "function" == typeof wx.getSystemInfoSync
变量 ws
确实为浏览器环境,为让 createImageMessage
的参数校验器通过,因此将 ws
条件判断注释掉,如下代码所示,因为 wx.chooseImage
方法的传参不能满足该校验器。
{
...,
createImageMessage: {
to: {
type: "String",
required: !0
},
conversationType: {
type: "String",
required: !0
},
payload: {
type: "Object",
required: !0,
validator: function(e) {
if (va(e.file))
return console.warn("createImageMessage payload.file 不能为 undefined。请参考 https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html#createImageMessage"),
!1;
// if (ws) {
// if (!(e.file instanceof HTMLInputElement || pa(e.file)))
// return console.warn("createImageMessage payload.file 的类型必须是 HTMLInputElement 或 File。请参考 https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html#createImageMessage"),
// !1;
// if (e.file instanceof HTMLInputElement && 0 === e.file.files.length)
// return console.warn("createImageMessage 您没有选择文件,无法发送。请参考 https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html#createImageMessage"),
// !1
// }
return !0
},
onProgress: {
type: "Function",
required: !1,
validator: function(e) {
return va(e) && console.warn("createImageMessage 没有 onProgress 回调,您将无法获取图片上传进度。请参考 https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html#createImageMessage"),
!0
}
}
}
},
...
}
重新点击图片上传,提示如下:

Blob 对象表示一个不可变、原始数据的类文件对象。图中的报错提示
n: 只允许上传 jpg png jpeg gif 格式的图片
该格式的判断有可能是根据文件的扩展名称而来。因此,回归到代码 tim.createImageMessage
方法的调用,关键代码
{
key: "createImageMessage",
value: function(e) {
e.currentUser = this.tim.context.identifier;
var t = new Uf(e);
if (Ns) {
var n = e.payload.file;
if (pa(n))
return void la.warn("微信小程序环境下调用 createImageMessage 接口时,payload.file 不支持传入 File 对象");
var r = n.tempFilePaths[0]
, o = {
url: r,
name: r.slice(r.lastIndexOf("/") + 1),
size: n.tempFiles[0].size,
type: r.slice(r.lastIndexOf(".") + 1).toLowerCase()
};
e.payload.file = o
} else if (ws && pa(e.payload.file)) {
var i = e.payload.file;
e.payload.file = {
files: [i]
}
}
}
}
根据上面分析,Ns
布尔值为 true
,并且需要处理传入参数,显而易见,上面 var n = e.payload.file
中的变量 n
即为 tim.createImageMessasge
入参,变量 n
的值其实就是点击图片选取时调用的 wx.chooseImage
的返回值

比较分析
// 代入上面的变量n, 变量 r 的值为字符串 blob:http://172.18.10.159/2e507f2d-b2a8-4d7c-930a-81eddcbd97ce
// 对象 o 的属性 type 的值为 r.slice(r.lastIndexOf(".") + 1).toLowerCase(),代入处理得 '159/2e507f2d-b2a8-4d7c-930a-81eddcbd97ce'
var r = n.tempFilePaths[0];
, o = {
url: r,
name: r.slice(r.lastIndexOf("/") + 1),
size: n.tempFiles[0].size,
type: r.slice(r.lastIndexOf(".") + 1).toLowerCase()
};
此处type的值为 '159/2e507f2d-b2a8-4d7c-930a-81eddcbd97ce'
,显然不是正常图片的格式
因此 o.type
修改为 n.tempFiles[0].type
,调整后运行结合提示 n: 只允许上传 jpg png jpeg gif 格式的图片
最终修改为 n.tempFiles[0].type.split('/')[1]
代码如下:
var r = n.tempFilePaths[0]
, o = {
url: r,
name: r.slice(r.lastIndexOf("/") + 1),
size: n.tempFiles[0].size,
// type: r.slice(r.lastIndexOf(".") + 1).toLowerCase()
// 修改此处 wx.chooseImage的 file blob对象路径没有后缀名,所以用了对应n.tempFiles[0]的type类型,截取获得后缀
type: n.tempFiles[0].type.split('/')[1]
};
重新点击选取图片,报错依然

点击报错连接

或者根据提示直接打开源代码第 18983
行
{
{
key: "uploadImage", // 定义上传图片方法
value: function(e) {
if (!e.file) // 判断入参
return id(new Sp({
code: Ep.MESSAGE_IMAGE_SELECT_FILE_FIRST,
message: qp
}));
var t = this._checkImageType(e.file); // 检查图片类型
if (!0 !== t)
return t;
var n = this._checkImageMime(e.file); // 检查图片Mine类型
if (!0 !== n)
return n;
var r = this._checkImageSize(e.file); // 检查图片大小
return !0 !== r ? r : this.upload(e) // 上传
}
},
{
key: "_checkImageType", // 定义图片类型检查方法
value: function(e) {
var t = "";
// 变量 Ns 为 true
// e.url 值为 blob:http://172.18.10.159/2e507f2d-b2a8-4d7c-930a-81eddcbd97ce,因此该处逻辑判段出了问题
// t 为 159/2e507f2d-b2a8-4d7c-930a-81eddcbd97ce
// Of 从源码搜索出为 Of = ["jpg", "jpeg", "gif", "png"]
// 最后 return false
return t = Ns ? e.url.slice(e.url.lastIndexOf(".") + 1) : e.files[0].name.slice(e.files[0].name.lastIndexOf(".") + 1),
Of.indexOf(t.toLowerCase()) >= 0 || id(new Sp({
coe: Ep.MESSAGE_IMAGE_TYPES_LIMIT,
message: Fp
}))
}
}
}

此处依然是上传图片类型问题错误导致,上面提到上传对象 e
的 url
为 blob
类型字符串,因此不能通过该 url
值获取图片类型, 需要修改为 e.type
, 即源码 18996
行代码修改为:
return t = Ns ? e.url.slice(e.url.lastIndexOf(“.”) + 1) : e.files[0].name.slice(e.files[0].name.lastIndexOf(“.”) + 1),
return t = Ns ? e.type
: e.files[0].name.slice(e.files[0].name.lastIndexOf(“.”) + 1),
上传图片成功!!

总结 tim
修改的三处地方
-
源码 6113
附近, 放弃tim.createImageMessage
对原生h5文件的类型校验,已注释掉
// ************************* BEGIN 第一处修改 BEGIN***********************************
// if (ws) {
// if (!(e.file instanceof HTMLInputElement || pa(e.file)))
// return console.warn("createImageMessage payload.file 的类型必须是 HTMLInputElement 或 File。请参考 https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html#createImageMessage"),
// !1;
// if (e.file instanceof HTMLInputElement && 0 === e.file.files.length)
// return console.warn("createImageMessage 您没有选择文件,无法发送。请参考 https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html#createImageMessage"),
// !1
// }
// ************************* BEGIN 第一处修改 BEGIN***********************************
-
修改并重新获取 tim.createImageMessage
上传图片类型,源码13964
行附近
// ************************* BEGIN 第二处修改 BEGIN***********************************
// type: r.slice(r.lastIndexOf(".") + 1).toLowerCase()
// 修改此处 wx.chooseImage的 file blob对象路径没有后缀名,所以用了对应n.tempFiles[0]的type类型,截取获得后缀
type: n.tempFiles[0].type.split('/')[1]
// ************************* BEGIN 第二处修改 BEGIN***********************************
-
修改上传图片前的图片文件类型校验,源码 19002
行附近
// ************************* BEGIN 第三处修改 BEGIN***********************************
// return t = Ns ? e.url.slice(e.url.lastIndexOf(".") + 1) : e.files[0].name.slice(e.files[0].name.lastIndexOf(".") + 1),
return t = Ns ? e.type : e.files[0].name.slice(e.files[0].name.lastIndexOf(".") + 1),
// ************************* END 第三处修改 END***************************************
适用于 uni-app
的h5腾讯云IM tim sdk
,解决对话中的图片发送问题,去下载(http://3vj-vda.3vjia.com/meijia_oss_pro/static/wangpu/h5/tim-js.js)
总结
此为项目中真实遇到的问题,使用 uni-app
开发多端项目H5,微信小程序,App(iOS/Android)应用,使用腾讯云IM作为聊天工具。使用腾讯云IM的(Web&小程序)sdk,其中h5版本不兼容。原因 uni-app
为兼容微信小程序开发,微信小程序专用全局对象 wx
被 uni
代理劫持,开发者能直接使用 wx
而不报错, h5版本的 sdk
代码中仍有 wx
对象,某些逻辑h5和小程序环境混用。
-
遇到问题,结合项目,具体分析 -
根据 warn
、error
提示,定位目标代码,分析关键代码,推测原因 -
文档资料查阅,对比结果(意料或意外),分析其中的差异性 -
验证,整理结果
当然,实际工作过程中,遇到的问题肯定比本文所列举的还要多,本文有点啰嗦,希望在遇到问题时能抛砖引玉。
参考资料
腾讯云IM(https://cloud.tencent.com/document/product/269/37413)
uni-app(https://uniapp.dcloud.io/README)
MDN web docs(https://developer.mozilla.org/zh-CN/docs/Web/API/Blob)
原文始发于微信公众号(三维家技术实践):uni-app多端兼容IM掏心实战
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/30686.html