uniapp对接腾讯即时通讯TIM 发图片消息问题

最近在用uniapp做app,中间涉及到了聊天功能,我在uni插件市场找到了集成tim腾讯即时通讯的模板:https://ext.dcloud.net.cn/plugin?id=1421

但作者没有实现上传图片消息的功能,自己搞了下,坑真多

首先,uniapp中选择图片用uni.chooseImage,返回:

返回一些blob的url,但是tim要求发图片必须使用dom对象或者File对象

 

这就只能把blob变成file对象了。

关于file对象的探索看这个:https://blog.csdn.net/lianzhang861/article/details/80283120

关于创建File对象,可以这样:

var file1=new File([blob], "aa.png",{type:"image/jpg"}); //第一个参数是Blob对象或者dataUrl,第二个参数是文件名,三个参数可选,规定文件类型

注意:第一个参数必须是对象,不能是转换成的字符串,比如uniapp或者微信小程序的chooseImage方法返回的blob的url,他是一个字符串,这样生成的File对象只是将url字符串变成文件了,不是文件本身!!!

想把blob字符串变成Blob对象,可以用es6的:const blob = await fetch(image.path).then(r => r.blob())

或者用传统的XHR或者ajax也行,就是把blob对象根据url给获取出来就行。

实例:

getImage(type){
	this.hideDrawer();
	uni.chooseImage({
		sourceType:[type],
		sizeType: ['original'/* , 'compressed' */], //可以指定是原图还是压缩图,默认二者都有
		success: (res)=>{
			console.log("!!!!!!!!!!!!!!!!!!!!")
			console.log(res)
			for(let i=0;i<res.tempFilePaths.length;i++){
				//res.name="aa.png"
				uni.getImageInfo({
					src: res.tempFilePaths[i],
					success: async  (image)=>{
						const blob = await fetch(image.path).then(r => r.blob())
						var file1=new File([blob], res.tempFiles[i].name,{type:blob.type});
						//file1.type="image/jpeg";
						let msg = {url:res.tempFilePaths[i],file:file1,w:image.width,h:image.height};
						this.sendMsg(msg,'img');
					}
				});
			}
		}
	});
},
// 发送消息
sendMsg(content,type){
	console.log(content)
	let message
	if(type=="text"){
		message= this.tim.createTextMessage({
		  to: this.toUserId,
		  conversationType: 'C2C',
		  payload: {
			text: content.text
		  }
		});	
	}else if(type=="img"){
		message = this.tim.createImageMessage({
		  to: this.toUserId,
		  conversationType: '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: {
			file: content.file
		  },
		  onProgress: function(event) { console.log('file uploading:', event) }
		});
	} 
	
	this.$store.commit('pushCurrentMessageList', message)
	let pomise = this.tim.sendMessage(message)
	pomise.then(res=>{
		console.log(res)
		this.$nextTick(()=> {
			// 滚动到底
			this.scrollToView = res.data.message.ID
		});
	})	
},

其实就是简单的blob转file而已,只不过从毫无头绪开始搞起,又看jdk源码都找资料的,一点点东西花了近两天的时间!!!
 

ps:

问题描述:

在uniapp h5版里面使用腾讯的即时通讯IM时,发现图片发送不了;

IM文档地址:TIM

查看 tim-js.js 源码发现,是由于uniapp内部封装有微信小程序的 wx 对象,导致 tim-js.js 即使在浏览器环境下也错误的判断成了小程序环境,导致上传插件 cos-js-sdk-v5 出现加载失败问题;

tim-js.js翻车地点:

上图红框内的判断导致变量 Oa(不一定是Oa,因为每次代码压缩混淆都会不一样) 在h5环境下始终未true;可以通过搜索canIUse字符定位到这里;

解决办法:

将上图红框代码更改为下面代码即可:

Oa = "undefined" == typeof window && "undefined" != typeof wx && "function" == typeof wx.getSystemInfoSync && "function" == typeof wx.canIUse,

 

ps:

上次闹得只能用于h5端,因为uniapp用的是js的sdk,tim要求你上传file对象,但是在app中,无法将path转行成js中的file对象传给tim,这样的话只能换一个方式了。

解决办法:

使用自定义消息,官方文档:https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html?_ga=1.122530763.1188066772.1554011923#createCustomMessage

思路:将要发送的图片上传到自己的服务器或者oss啥的就行了,返回一个url,将url拼到自定义消息中即可

上传图片的步骤我就省略了,这里说的是上传后返回一个url,再创建:

message = this.tim.createCustomMessage({
  to: this.toUserId,
  conversationType: '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_HIGH,
  payload: {
	data: 'chatFile', // 用于标识该消息类型
	description: content, // 用于装载url
	extension: ''
  }
});

这样返回message中就有了payload信息:

在消息队列中判断消息类型,把description赋值给img就完事

<view v-if="item.type=='TIMCustomElem'" class="bubble img" @tap="showPic(item.payload.description)">
									<image :src="item.payload.description" :style="{'width': 100+'px','height': 100+'px'}"></image>
								</view>

至于其他类型的比如视频音频啥的,都可以使用这种方法,可以判断data的标识,也可以判断url的文件类型,区分不同的消息展示方式 

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆趣编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值