引用微信小程序文档中wx.writeBLECharacteristicValue() API接口中的注意事项。
1 并行调用多次会存在写失败的可能性。
2 小程序不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙 4.0 单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过 20 字节。
/**
* 睡眠
*/
function sleep(msTime){
return new Promise(resolve => setTimeout(()=>{
resolve({
success: true,
time: msTime
})
}, msTime));
}
/**
* 字符串转Uint8Array(不支持小程序)
* @param {*} input 需要转换的字符串
* @returns 返回 arrayBuffer
*/
function str2Uint8Array(input) {
const encoder = new TextEncoder()
const view = encoder.encode(input)
return view.buffer
}
/**
* Uint8Array转字符串
* @param input Uint8Array
* @returns 返回 字符串
*/
const ab2str = (
input:
| ArrayBuffer
| Uint8Array
| Int8Array
| Uint16Array
| Int16Array
| Uint32Array
| Int32Array,
outputEncoding: string = "utf8"
): string => {
const decoder = new TextDecoder(outputEncoding);
return decoder.decode(input);
};
/**
* 字符串转Uint8Array(支持小程序)
* @param {*} input 需要转换的字符串
* @returns 返回 arrayBuffer
*/
function stringToArrayBuffer(str) {
let bytes = new Array();
let len, c;
len = str.length;
for (let i = 0; i < len; i++) {
c = str.charCodeAt(i);
if (c >= 0x010000 && c <= 0x10ffff) {
bytes.push(((c >> 18) & 0x07) | 0xf0);
bytes.push(((c >> 12) & 0x3f) | 0x80);
bytes.push(((c >> 6) & 0x3f) | 0x80);
bytes.push((c & 0x3f) | 0x80);
} else if (c >= 0x000800 && c <= 0x00ffff) {
bytes.push(((c >> 12) & 0x0f) | 0xe0);
bytes.push(((c >> 6) & 0x3f) | 0x80);
bytes.push((c & 0x3f) | 0x80);
} else if (c >= 0x000080 && c <= 0x0007ff) {
bytes.push(((c >> 6) & 0x1f) | 0xc0);
bytes.push((c & 0x3f) | 0x80);
} else {
bytes.push(c & 0xff);
}
}
let array = new Int8Array(bytes.length);
for (let i in bytes) {
array[i] = bytes[i];
}
return array.buffer;
}
// 不支持小程序
// let bufferData = str2Uint8Array('Hello world')
// 支持小程序
let bufferDate = stringToArrayBuffer('Hello world')
/**
* 命令式代码逻辑
*/
async function subpackage(bufferData,length = bufferData.byteLength,current = 0){
let limit = 20,
index = (length / limit),
min = 0,
max = 0;
if(index <= 0){
return
}
min = current * limit;
max = index < 1 ? min + (index*limit) : (current + 1) * 20;
await sleep(30);
const newBuffer = bufferData.slice(min,max)
console.log(newBuffer)
length -= limit;
current += 1;
return subpackage(bufferData,length,current);
}
subpackage(bufferData);
/**
* 响应式代码逻辑
*/
import { of, bufferCount,concatMap,delay} from "rxjs";
of(...new Uint8Array(bufferData))
.pipe(
bufferCount(20),
concatMap((x) => of(x).pipe(delay(5000)))
)
.subscribe({
next: (res) => {
console.log(ab2str(new Uint8Array(res)));
},
});