一个简单的想法。我想在通过AJAX调用的Web浏览器中显示计算机范围内的蓝牙设备(通过蓝牙 - 串口 - 端口NodeJS包使用蓝牙加密狗)。
我遇到的问题是,使用以下脚本,我无法同时扫描设备并提供网站服务。你能解释一下这个工作流程以及为什么/什么是纠正这个问题的好方向?
var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs"),
port = process.argv[2] || 8888,
btSerial = new (require('bluetooth-serial-port')).BluetoothSerialPort();
btSerial.inquire();
// Get the devices
var devices = [];
btSerial.on('found', function(address, name) {
if(typeof devices[address] === 'undefined'){
devices.push({'address': address,'name': name});
console.log("Device Found: "+address+" which is named: "+name);
}
});
// Keep searching
btSerial.on('finished', function() {
console.log("Done searching");
console.log(devices);
//btSerial.inquire();
});
http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname,
filename = path.join(process.cwd(), uri);
if (uri == '/devices') {
response.writeHead(200, {"Content-Type": "application/json"});
response.write(JSON.stringify(devices));
response.end();
return;
}
fs.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
return;
}
if (fs.statSync(filename).isDirectory()) filename += 'public/index.html';
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
return;
}
response.writeHead(200);
response.write(file, "binary");
response.end();
});
});
}).listen(parseInt(port, 10));
console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown");
答案 0 :(得分:2)
解决方案比预期简单得多。
首先,我创建了一个蓝牙扫描程序服务(永远运行),打开一个套接字,并在每个设备的查找位置将更新的结果发送到服务器服务。我将setTimeout函数设置为1s(1000ms),否则结果将不会传递给侦听服务器。
var port = 9838,
devices = {},
socket = require('socket.io-client')('http://localhost:'+port);
btSerial = new (require('bluetooth-serial-port')).BluetoothSerialPort();
var onFinishedFoundDevice = function(message){
// Add new device to object array
if(typeof message.address !== 'undefined' && typeof message.name !== 'undefined')
devices[message.address] = {'address': message.address,'name': message.name};
console.log("Sent new device", message);
};
var sendMessage = function(type, message, callback){
this.message = message;
socket.emit(type, message);
if(callback)
callback(message);
};
var findBluetooths = function () {
// Scan for BT devices in range
btSerial.on('found', function(address, name) {
if(typeof devices[address] === 'undefined'){
var message = {'address': address, 'name': name}; // prepare message
sendMessage('add-device', message, onFinishedFoundDevice); // actually send message to server
console.log("Device Found: "+address+" which is named: "+name);
}
});
// Keep searching
btSerial.on('finished', function() {
console.log("Received Finished... cont'd");
setTimeout(function(){btSerial.inquire();}, 1000);
});
// Scan for devices
console.log("Begin scanning");
btSerial.inquire();
}
// Do the magic
findBluetooths();
我创建了一个服务器服务(永远运行),它启用了HTTP服务器以及socket.io事件的监听器。它接收来自蓝牙扫描仪和index.html页面的事件。
var app = require('http').createServer(handler),
io = require('socket.io')(app),
fs = require('fs'),
port = 9838,
devices = [];
app.listen(port);
function handler (req, res) {
fs.readFile(__dirname + '/public/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
socket.emit('devices', devices);
socket.on('add-device', function(device) {
devices.push({'address': device.address,'name': device.name});
socket.broadcast.emit('device-added', device); // send device to browsers
console.log("Device Found: "+device.address+" which is named: "+device.name);
});
socket.on('get-devices', function(payload){
n });
});
最后,我创建了一个public / index.html文件来显示扫描结果,并从服务器发出更多信息请求。
<!DOCTYPE html>
<html>
<head>
<title>Bluetooth Scanner</title>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var port = 9838;
var hostname = window.location.hostname;
var socket = io(hostname+':'+port);
socket.on('welcome', function (message) {
console.log(message);
});
socket.on('device-added', function (device) {
$("#no-devices").hide();
$('<li>', {
html: "Device named "+device.name+" with MAC "+ device.address+" is online."
}).appendTo('#devices');
});
socket.on('devices', function(devices){
if(devices.length > 0) $("#no-devices").hide();
$.each(devices, function(key, device){
$('<li>', {
html: "Device named <b>"+device.name+"</b> with MAC <b>"+ device.address+"</b> is online."
}).appendTo('#devices');
});
});
</script>
</head>
<body>
<div>
<span id="no-devices">No devices yet...</span>
<ul id="devices"></ul>
</div>
</body>
</html>
谢谢大家的帮助。它缺乏真正使其可用的必要功能,但它是我项目的良好开端
答案 1 :(得分:0)
要在后台定期扫描设备,请使用setInterval
:
setInterval(btSerial.inquire, 10000);
这将每10秒调用btSerial.inquire
一次。您需要确定应用程序的最佳刷新间隔。权衡的是,您可以使用更短的间隔获取更多最新的设备数据,但这样可以缩短您的服务器的HTTP请求时间。