A simple idea. I would like to show bluetooth devices in range of the computer (using a bluetooth dongle via bluetooth-serial-port NodeJS package) in the web browser served up upon call over AJAX.
The issue I am having is that with the following script, I can't continiously scan for devices and serve up web sites at the same time. Could you explain the workflow in this and why/what would be a good direction to rectify the issue?
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");
The solution was much simpler than expected.
First I created a bluetooth scanner service (running with forever) that opens a socket and delivers updated results to the server service at the find of each device. I set the setTimeout function to 1s (1000ms) otherwise the results would not be delivered to the listening server.
Than I created a server service (running in forever as well) that enables HTTP server as well as a listener for socket.io events. It takes in events from the bluetooth scanner as well as the index.html page.
Finally I created a public/index.html file to display the scanning results as well as issue requests for more information from the server.
Thank you all for the help. It lacks necessary functionality to really make it usable but it is a good start for my project
To periodically scan for devices in the background, use
setInterval
:This will call
btSerial.inquire
once every 10 seconds. You'll need to decide on the best refresh interval for your application. The trade-off is that you can get more up-to-date device data with a shorter interval, but that gives your server less time for HTTP requests.