2

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.

Joe Bloe
  • 383
  • 5
  • 12

1 Answers1

0

Have you tried any of the following?

  • flush() at your android client side
  • use IOUtils.copy() instead of the usual byte writing plumbing code
William Ku
  • 798
  • 5
  • 17