MrFour 2017-09-24
操作系统名称 Microsoft Windows 10 专业版 版本 10.0.15063 版本 15063
Microsoft Visual Studio Community 2017 版本 15.3.3 VisualStudio.15.Release/15.3.3+26730.12 Microsoft .NET Framework 版本 4.7.02046 已安装的版本: Community Visual Basic 2017 00369-60000-00001-AA520 Microsoft Visual Basic 2017 Visual C# 2017 00369-60000-00001-AA520 Microsoft Visual C# 2017 Visual C++ 2017 00369-60000-00001-AA520 Microsoft Visual C++ 2017 Application Insights Tools for Visual Studio 包 8.8.00712.1 Application Insights Tools for Visual Studio ASP.NET and Web Tools 2017 15.0.30726.0 ASP.NET and Web Tools 2017 ASP.NET Core Razor Language Services 1.0 Provides languages services for ASP.NET Core Razor. ASP.NET 模板引擎 2017 15.0.30726.0 ASP.NET 模板引擎 2017 JavaScript Project System 2.0 JavaScript Project System JavaScript UWP 项目系统 2.0 JavaScript UWP 项目系统 JavaScript 语言服务 2.0 JavaScript 语言服务 Microsoft JVM Debugger 1.0 Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines Microsoft MI-Based Debugger 1.0 Provides support for connecting Visual Studio to MI compatible debuggers Microsoft Visual C++ 向导 1.0 Microsoft Visual C++ 向导 Microsoft Visual Studio VC 软件包 1.0 Microsoft Visual Studio VC 软件包 NuGet 包管理器 4.3.1 Visual Studio 中的 NuGet 包管理器。有关 NuGet 的详细信息,请访问 http://docs.nuget.org/。 TypeScript 2.3.4.0 用于 Visual Studio 的 TypeScript 工具 Visual Studio Code Debug Adapter Host Package 1.0 Interop layer for hosting Visual Studio Code debug adapters in Visual Studio Visual Studio tools for CMake 1.0 Visual Studio tools for CMake Visual Studio Tools for Universal Windows Apps 15.0.26730.08 Visual Studio Tools for Universal Windows Apps 让你能够构建一种通用的应用体验,运行 Windows 10 的每种设备都可以获得这种体验,如手机、平板电脑、PC 等。它包含 Microsoft Windows 10 软件开发工具包。 通用 Azure 工具 1.10 通过 Azure 移动服务和 Microsoft Azure Tools 提供通用服务。
蓝牙开发MSDN资料 https://docs.microsoft.com/zh-cn/windows/uwp/devices-sensors/bluetooth
主要涉及的包
//导入包 let { BluetoothCacheMode, BluetoothDevice } = Windows.Devices.Bluetooth; let { RfcommDeviceService, RfcommServiceId } = Windows.Devices.Bluetooth.Rfcomm; let { DeviceInformation } = Windows.Devices.Enumeration; let { StreamSocket, SocketProtectionLevel } = Windows.Networking.Sockets; let { DataWriter, DataReader, UnicodeEncoding } = Windows.Storage.Streams;
/** * 一些常量 */ const Constants = { RfcommServiceUuid: RfcommServiceId.fromUuid("58517d84-357d-c58a-0000-000000000000"), // RfcommServiceUuid: RfcommServiceId.obexObjectPush, SdpServiceNameAttributeId: 0x100, SdpServiceNameAttributeType: (4 << 3) | 5, SdpServiceName: "My Win1o BLE" };
创建RfcommServiceProvider
provider = await RfcommServiceProvider.createAsync(Constants.RfcommServiceUuid);
使用StreamSocketListener监听socket连接,并且启动监听
listener = new StreamSocketListener(); listener.addEventListener("connectionreceived", onConnectionreceived); await listener.bindServiceNameAsync(provider.serviceId.asString(), SocketProtectionLevel.bluetoothEncryptionAllowNullAuthentication);
provider.startAdvertising(listener, true);
监听连接客户端的socket连接
/** * 监听客户端连接 * @param {Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs} evt */ async function onConnectionreceived(evt) { console.log(evt); let socket; try { socket = evt.socket; } catch (e) { console.log(e); disconnect(); return; } console.log("socket连接", socket); let information = socket.information; info(information.remoteAddress + " 正在接入..."); let remoteDevice = await BluetoothDevice.fromHostNameAsync(information.remoteHostName);//获取实际设备名 console.log(remoteDevice); let holder = clients[information.remoteAddress]; if (holder == null)//添加元素 { holder = {}; let ele = document.createElement("div"); ele.className = "clientItem"; ele.innerHTML = "<span>" + remoteDevice.name + "</span><span>" + information.remoteAddress + "</span><input type=\"checkbox\" />"; clientList.appendChild(ele); holder.socket = socket; holder.ele = ele; holder.name = remoteDevice.name; Object.defineProperty(holder, "isSelected", { get: function () { return ele.querySelector("input").checked; } }); holder.writer = new DataWriter(socket.outputStream); clients[information.remoteAddress] = holder; } else//更新元素 { //do noting } let reader = new DataReader(socket.inputStream); //断开异常处理 let errFun = function (igr) { console.log(igr); //断开连接 info(holder.name + "断开连接.."); delete clients[information.remoteAddress]; clientList.removeChild(holder.ele); }; //迭代循环读取 function run() { reader.loadAsync(4).then(len => { let size = reader.readInt32();//抛出异常处理 return size; }).then(size => { console.log(size); return reader.loadAsync(size); }).then(textLen => { console.log("文本长度:" + textLen); let str = reader.readString(textLen); return str; }).then(str => { console.log(str); info(holder.name, str); run(); }, errFun); } run(); }
向连接的客户端发送消息
sendBtn.onclick = function () { let msg = sendText.value; console.log("发送文本", msg); info("服务器", msg); for (mac in clients) { let holder = clients[mac]; if (holder.isSelected) { let writer = holder.writer; sendMsg(writer, msg); } } } /** * * @param {Windows.Storage.Streams.DataWriter} writer * @param {string} msg */ function sendMsg(writer, msg) { let textLen = writer.measureString(msg); console.log("写入长度:" + textLen); writer.writeInt32(textLen); writer.writeString(msg); writer.storeAsync(); }
断开服务
function disconnect() { startBtn.removeAttribute("disabled"); startBtn.checked = false; for (mac in clients) { let holder = clients[mac]; holder.socket.close(); } if (listener != null) { info("服务已经断开"); listener.close(); listener = null; } if (provider != null) { provider.stopAdvertising(); provider = null; } }
查找蓝牙设备
async function search() { console.clear(); connectBtn.setAttribute("disabled", true); // RfcommDeviceService.getDeviceSelector.getDeviceSelector(Constants.RfcommServiceUuid); let selector = BluetoothDevice.getDeviceSelector(); console.log("selector", selector); let devices = await DeviceInformation.findAllAsync(selector); console.log("devices", devices); info("正在搜索周边设备..."); let bluetoothDevices = new Map(); for (const device of devices) { let bluetoothDevice = await BluetoothDevice.fromIdAsync(device.id); if (bluetoothDevice != null) { //console.log(bluetoothDevice); bluetoothDevices.set(bluetoothDevice.deviceId, bluetoothDevice); } } console.log(bluetoothDevices); info("找到周边设备有" + bluetoothDevices.size + "个"); notifyDataSetChanged(bluetoothDevices); }
需要注意
DeviceInformation.findAllAsync(selector)
得到并一定全是BluetoothDevice或RfcommDeviceService,(至少js的api是这样,bug?),需要
let bluetoothDevice = await BluetoothDevice.fromIdAsync(device.id);
判断是否为蓝牙设备
检索蓝牙服务,通过bluetoothDevice.rfcommServices获取缓存结果
bluetoothDevice.getRfcommServicesAsync(BluetoothCacheMode.uncached).then(result => { console.log("返回服务", result); for (const rfcommService of bluetoothDevice.rfcommServices) { let inputDiv = document.createElement("div"); inputDiv.className = "itemLabel"; let inputEle = document.createElement("label"); inputEle.innerHTML = rfcommService.serviceId.asString() + "<input name='rfcommService' type='radio' />"; inputDiv.appendChild(inputEle); itemDiv.appendChild(inputDiv); inputDiv.onclick = function () { clientList.className = "left"; msgText.className = "right"; connect(rfcommService); }; } });
连接指定的服务
/** * 连接到指定服务 * @param {Windows.Devices.Bluetooth.Rfcomm.RfcommDeviceService} rfcommService */ async function connect(rfcommService) { console.log(rfcommService); connectText.textContent = "已连接到" + rfcommService.device.name + rfcommService.device.hostName; info("正在连接到 " + rfcommService.serviceId.uuid + " ..."); socket = new StreamSocket(); try { await socket.connectAsync(rfcommService.connectionHostName, rfcommService.connectionServiceName, SocketProtectionLevel.bluetoothEncryptionAllowNullAuthentication); info("连接成功"); } catch (e) { console.log(e); error("不能连接到服务端!"); connectText.textContent = "搜索设备"; connectBtn.checked = false; socket = null; return; } writer = new DataWriter(socket.outputStream); let reader = new DataReader(socket.inputStream); //迭代循环读取 function run() { reader.loadAsync(4).then(len => { let size = reader.readInt32();//抛出异常处理 return size; }).then(size => { console.log(size); return reader.loadAsync(size); }).then(textLen => { console.log("文本长度:" + textLen); let str = reader.readString(textLen); return str; }).then(str => { console.log(str); info("服务器", str); run(); }, err => { console.log(err); disconnect(); }); } run(); }
在win10中,设置 -> 设备 -> 蓝牙和其他设备 -> 切换 蓝牙 开关, 点击 添加蓝牙或其他设备 -> 蓝牙 ,需要 匹配Android蓝牙设备 才能正常通信
使用Android作为客户端,win10服务端;
或者Android作为服务端,或者Win10为客户端
win10 源码:https://github.com/zhhaogen/BuletoothTest-UWP.git
android 源码:https://github.com/zhhaogen/BuletoothTest-Android.git