I have a BlueCove bluetooth server program running on my laptop that waits for my Android phone to connect as client (running my app). When the connection is established, I can send touch coordinates from the phone to the laptop via bluetooth, where the coordinates are to be used to move the cursor. The coordinates are sent ~20 times per second as byte-arrays with 9 bytes:
- the first byte is used to describe the type of data being transmitted (I'm sending other stuff, too)
- the bytes 2-5 and 6-9 are used to store two float values
All that works, but the read part on the server is a bit slow at times:
To find out where the lag occurs, I ran only the parts necessary for connecting and data transferring (in separate threads of course) and printed a line every time new input was read (so no slow input processing) - Sometimes, when I "draw" a line on my phone, the data input on the laptop is steady and ends almost instantly when I lift my finger, but other times, the read rate gets slower and I still get my debug print line called up to two seconds after lifting my finger. I can rule out the client-side sending as cause of the delay, the send method calls there all return in a timely manner. I also reduced the amount of data sent by only sending coordinates from every third move event.
My question is: is there some way I can increase the server's read performance? And is there some way I can find out what exactly is causing those delays that seem to occur randomly?
I'm also curious, if there is a rule of thumb for the byte-array buffer size (I figured higher values don't make much sense in my case as I send relatively small pieces of data pretty frequently that need to be processed right away, but I'm not sure?).
Source code (server-side):
Establishing connection:
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import java.io.IOException;
public class WaitThread implements Runnable {
private static final UUID MY_UUID =
new UUID("514C8B00AD8311E5A8370800200C9A66", false);
public WaitThread() { }
@Override
public void run() {
waitForConnection();
}
private void waitForConnection() {
LocalDevice localDevice = null;
StreamConnectionNotifier server;
StreamConnection connection = null;
try {
localDevice = LocalDevice.getLocalDevice();
localDevice.setDiscoverable(DiscoveryAgent.GIAC); // General/Unlimited Inquiry Access Code
String url = "btspp://localhost:" + MY_UUID.toString() + ";authenticate=false;encrypt=false";
server = (StreamConnectionNotifier) Connector.open(url);
while (true) {
System.out.println("waiting for connection...");
connection = server.acceptAndOpen();
Thread processThread = new Thread(new ProcessConnectionThread(connection));
processThread.start();
}
} catch (BluetoothStateException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
}
}
}
Reading input:
import java.io.InputStream;
import javax.microedition.io.StreamConnection;
public class ProcessConnectionThread implements Runnable {
private StreamConnection streamConnection;
public ProcessConnectionThread(StreamConnection connection) {
streamConnection = connection;
}
@Override
public void run() {
try {
InputStream inputStream = streamConnection.openInputStream();
System.out.println("waiting for input");
byte[] input = new byte[64]; // buffer size ?
int numberOfBytesReceived;
while (true) {
numberOfBytesReceived = inputStream.read(input);
System.out.println("read data");
//processInput(input, numberOfBytesReceived)
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
The laptop runs Windows 10 x64 with BlueCove version 2.1.1-SNAPSHOT on winsock.