第1步
首先第一步,调试环境必须是https的,由于浏览器的强制安全策略,本地可以采用localhost
第2步
然后,如果打印需要服务UUID(Service UUID) 和 特征UUID(Characteristic UUID),否则无法通信,这里可以咨询厂家或者找官网或技术人员拿去,我是通过浏览器chrome://bluetooth-internals/#devices查询可用的UUID
第3步
然后查询所有蓝牙设备的配对 navigator.bluetooth.requestDevice
const sppUuid = `xxxx-xxx-xx`// 打印机型号的uuid
const device = await navigator.bluetooth.requestDevice({
acceptAllDevices: true, // 不过滤蓝牙设备,接受所有蓝牙设备
optionalServices: [sppUuid] // 打印机服务UUID
});
// 验证GATT可用性
if (!device.gatt) {
throw new Error('设备不支持GATT协议');
}
console.log('配对打印机名称:', device.name)
const server = await device.gatt.connect();
// console.log('server对象:', server)
第4步
获取服务server.getPrimaryService
const service = await server.getPrimaryService(sppUuid);
console.log('获取服务:',service)
if (!service || service.length === 0) {
throw new Error('未发现可用服务');
}
第5步
获取特征对象service.getCharacteristics,同时需要保证其properties需要写的权限(官方标注writeValue后续版本将会删除,必须用writeWithoutResponse)
// 保存特征对象供后续使用
const characteristics = await service.getCharacteristics();
if (!characteristics || characteristics.length === 0) {
throw new Error('未发现可用特征对象');
}
characteristics.forEach(characteristic => {
// console.log('特征:', characteristic.properties);
// 需要配对一个有读写权限的特征对象
if( characteristic.properties.writeWithoutResponse){
this.characteristic = characteristic;
}
});
console.log(this.characteristic)// 打印结果如下:
第6步
打印的字符串如果含有简体中文,必须使用GBK或者GB2312编码格式,同时使用 Uint8Array类型的数据,否则会报错
// TextEncoder默认且唯一支持的编码为 UTF-8,无法指定其他字符集, 打印机无法识别导致乱码
const encoder = new TextEncoder();
const textData = encoder.encode(str);
// 依赖第三方库iconv-lite,将字符串转换为GBK编码
let textData = iconv.encode(printValue, 'GBK');
第7步
最后打印使用characteristic.writeValue,characteristic.writeValue 必须 返回 Uint8Array 类型数据
// 分片发送数据(部分蓝牙设备限制单次发送长度)
const chunkSize = 512;
for (let i = 0; i < textData.length; i += chunkSize) {
const chunk = textData.subarray(i, i + chunkSize);
await characteristic.writeValue(chunk).then(()=>{
console.log("写入成功,等待设备响应...")
});
}