uni-app 鸿蒙系统WebSocket.send不支持ArrayBuffer问题
uni-app 鸿蒙系统WebSocket.send不支持ArrayBuffer问题
操作步骤:
- WebSocket.send({data:ArrayBuffer})
预期结果:
- 发送成功
实际结果:
- {“name”:“UniError”,“errSubject”:"",“errCode”:0,“errMsg”:“Parameter error”}
bug描述:
- 鸿蒙系统里的WebSocket.send({data:xx}),只能发string, 不支持ArrayBuffer?
HBuilderX 4.33.2024111702-alpha 已修复。
更多关于uni-app 鸿蒙系统WebSocket.send不支持ArrayBuffer问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这个问题应该是存在的,请官方核实,下面是一个进行修正的例子:
在鸿蒙里,直接传ArrayBuffer,会导致参数错误,这里直接传数组
//#ifdef APP-HARMONY
let buffer = Array.from(allArr)
//#endif
let toSend = {
data: buffer,
fail: function (e) {
console.log("send fail", JSON.stringify(e))
}
}
ws.send(toSend);
在uni.api.ets中,对SocketTask1.send里重新构造ArrayBuffer, 这种方式可以成功发送ArrayBuffer
send(options: SendSocketMessageOptions) {
let data : string | ArrayBuffer
if(typeof(options.data)===‘string’){
data = options.data as string
}else{
data = new Uint8Array(options.data as ArrayBufferLike).buffer;
}
this._ws.send(data).then((success: boolean)=>{
if (success) {
tryExec(options.success, {} as GeneralCallbackResult);
} else {
tryExec(options.fail, new UniError(‘send message failed’));
}
}, (err: Error)=>{
tryExec(options.fail, new UniError(err.message));
});
}
感谢反馈,已确认bug
谢谢回复,修复的话预计是什么时候呢?
回复 d***@qq.com: 待定,下个alpha或者下下个alpha,鸿蒙的ohpm需要审核有点耽误发版进度
回复 DCloud_uniCloud_WYQ: 了解了,耐心等待,谢谢。
回复 d***@qq.com: 有可复现问题的项目吗?有的话附件发一下
回复 DCloud_uniCloud_WYQ: 抱歉,项目的代码比较多。打日志跟踪了一下,应该是在执行uni.connectSocket的时候会崩溃。
回复 d***@qq.com: 我这用我的测试项目试了下connectSocket不会崩溃,还是尽可能提供一个demo吧
回复 DCloud_uniCloud_WYQ: connectSocket大概的逻辑如下 let wssURL = “wss://xxx?param1=v1¶m2=v2” let protocols = [] let token = “xxxxx” ws = uni.connectSocket({ url: wssURL, header: { ‘content-type’: ‘application/json’, ‘X-Token’: token, }, protocols: protocols, method: ‘GET’, tcpNoDelay: true, fail: function (e) { console.log(e) uni.showToast({ title: ‘创建连接失败:’ + e.errMsg, duration: 2000, icon: ‘none’, }) }, })
回复 DCloud_uniCloud_WYQ: 如果在connectSocket传入了header参数,即使是空的会崩溃
回复 d***@qq.com: 了解了,runtime版本2.3.15会修复这个问题,下个版本的alpha带的也是这个版本。目前这个版本还在ohpm审核
回复 d***@qq.com: 2.3.15还遗留了一个问题,传header控制台会打印一行警告,这个不影响实际效果,下下个alpha再去除
回复 DCloud_uniCloud_WYQ: 好的,谢谢,有了新版本我们再测试
针对uni-app在鸿蒙系统上WebSocket.send不支持ArrayBuffer的问题,确实可能遇到兼容性问题。虽然官方文档可能表明支持ArrayBuffer,但在某些特定平台(如鸿蒙系统)上可能并未完全实现或存在bug。为了绕过这一限制,我们可以考虑将ArrayBuffer转换为其他格式(如Blob或Base64字符串)进行发送。以下是一个使用Blob和Base64字符串作为替代方案的代码示例:
方案一:使用Blob对象
如果WebSocket接口支持Blob对象,可以尝试将ArrayBuffer转换为Blob,然后发送Blob对象。
// 假设已经有一个ArrayBuffer对象 arrayBuffer
const arrayBuffer = new ArrayBuffer(8); // 示例数据
const uint8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < uint8Array.length; i++) {
uint8Array[i] = i; // 填充数据
}
const blob = new Blob([uint8Array], { type: 'application/octet-stream' });
// 发送Blob对象
webSocket.send(blob);
方案二:使用Base64字符串
将ArrayBuffer转换为Base64字符串,然后发送字符串。接收方需要再进行Base64解码。
// 假设已经有一个ArrayBuffer对象 arrayBuffer
const arrayBuffer = new ArrayBuffer(8); // 示例数据
const uint8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < uint8Array.length; i++) {
uint8Array[i] = i; // 填充数据
}
// ArrayBuffer 转 Base64
const binary = '';
const bytes = new Uint8Array(arrayBuffer);
const len = bytes.byteLength;
const binaryString = Array.from({ length: len }, (_, i) =>
String.fromCharCode(bytes[i])
).join('');
const base64String = window.btoa(binaryString);
// 发送Base64字符串
webSocket.send(base64String);
// 接收方需要将Base64字符串解码回ArrayBuffer
// 示例解码代码:
// const byteCharacters = atob(base64String);
// const byteNumbers = new Array(byteCharacters.length);
// for (let i = 0; i < byteCharacters.length; i++) {
// byteNumbers[i] = byteCharacters.charCodeAt(i);
// }
// const byteArray = new Uint8Array(byteNumbers);
// const arrayBuffer = byteArray.buffer;
请注意,上述代码示例是基于Web标准的实现,可能需要根据uni-app和鸿蒙系统的具体API调整。特别是在uni-app框架中,可能需要额外的配置或插件来处理Blob或Base64字符串的传输。此外,Base64编码会增加数据大小(大约增加33%),这可能会影响性能和带宽使用。因此,在选择方案时需要根据实际需求和限制进行权衡。