Originally posted on the cownado.com blog.
With cordova-plugin-chrome-apps-bluetoothsocket already there, why bother creating a new Bluetooth networking plugin?
I will blog about it someday, but I'm researching ways to implement a local multiplayer game for mobile devices using HTML5.
Bluetooth communication can be a way to achieve such goal, and pretty much the only available Cordova plugin to enable such functionality is cordova-plugin-chrome-apps-bluetoothsocket.
That is, until now.
In theory cordova-plugin-chrome-apps-bluetoothsocket has a nice API, but the problem is that its implementation is quite buggy:
- First of all, even though it is advertised as working on both Android and iOS, in pratice only the Android platform is implemented (this is not their fault, but rather on iOS not supporting Bluetooth socket communication).
- The Bluetooth adapter gets enabled at application start without asking anything to anyone (in contrast to the Android recommendation to ask permission to the user before enabling Bluetooth); moreover there is no API to enable/disable the Bluetooth adapter.
- While there is an API to enable and disable device discovery and it works very well, there is no API to request device discoverability.
- The getDevices function does not work, so connection is possible only when one device is discoverable and the other device is discovering, but, as mentioned earlier, lacking an API to request device discoverability, it is very hard for the user to instantiate a connection.
- Error handling does not work: The chrome.runtime.lastError variable requires a separate Cordova plugin that has to be manually installed, and the onReceiveError event gets fired only once in the application lifetime if you're lucky.
- Sending data over a socket is done synchronously, even though the API is asynchronous.
Can we do better?
Of course, that's why I'm pleased to announce:
It's an implementation of Bluetooth sockets, with an API inspired by the Chrome Apps, but it does not strive to achieve full API compatibility with Chrome Apps.
It addresses the limitations mentioned earlier in the following ways:
- For now only the Android platform is implemented, but I plan to implement support for Windows in the future.
- There are APIs to enable/disable the Bluetooth adapter, and to nicely ask the user to enable the adapter.
- There is an API to request device discoverability.
- The getDevices function correctly lists all the paired devices, so connection is possible even without requesting discoverability on one device.
- Error handling is implemented according to the Cordova Plugin specification, that is each function has both a success and error callback. The onReceiveError and onAcceptError events get fired every time there is an error.
- Sending data over a socket is done asynchronously.
The API has been simplified compared to the Chrome Apps, in particular:
- In the device discovery API only the onDeviceAdded event is implemented, and it will be fired also for already paired devices.
- There is no need to manually create a socket. The socketId will be passed as a parameter to the connect success callback, and the onAccept event.
- There are no paused sockets, and at the first onReceiveError or onAcceptError event, the socket will be automatically closed.
A final note regarding synchronous versus asynchronous send: When you call the send function, it is important to have it return immediately, or else the game frame rate will suffer.
I hope that you will find cordova-plugin-networking-bluetooth as useful as I do.
Of course Bluetooth is not the only option to implement local multiplayer, so stay tuned for more.