2

I'm developing an android application which need to open up to 20 sockets (in parallel), and get an update from each one of them every 4 seconds (and update the UI respectively).

This is what I tried so far:

  1. Creating a TimerTask for each socket connection and use a handler and messages to post the updates to the UI thread. Problems with this solution: after creating about 15 TimerTasks (each one is on a different thread), the UI of my application (really simple) starts to leg. Second problem is that the updates from each socket is not even remotely synced (one updates each 4 seconds and the other one each 20 seconds for example).
  2. Creating one thread that deals all the communication using async socket channels and selector. Problems with this solution: Java doesn't have built in support for SSL (rather they just supplied an SSL engine, instead of an SSLChannelSocket), and I need SSL sockets.

Any Suggestions/other solutions?

Daniel L.
  • 5,060
  • 10
  • 36
  • 59
  • What is it that you're delivering every 4 seconds? is it some sort of heartbeat? is your client (the 'other end') sending you these packets every 4 seconds? maybe it's not really necessary to spawn the timers. please clarify – Tomasz W Nov 05 '12 at 11:39
  • Hi Tichy, every 4 seconds I'm sending a request (xml) through each of the sockets and the other side responds with an answer containing information I need to show in my UI (the information is changing all the time). – Daniel L. Nov 05 '12 at 11:44

1 Answers1

0

I believe you may be interested in NIO (aka non-blocking I/O) in your app. it should enable you to handle multiple clients in much more efficient manner - see this post - it will give you some information on how to do it efficiently and properly.

You can find example how to deal with this for example in Google's Anymote library. They do particularly what i mentioned in comments - dedicated thread for reading:

  mReceiverThread = new Thread(new Runnable() {
  public void run() {
    boolean available = true;
    while (available) {
      available = getNextRemoteMessage();
    }
    stop();
  }});

although it uses direct callbacks (so the interface methods are invoked from reading thread, rather than posted via Handler.

Good luck!

Community
  • 1
  • 1
Tomasz W
  • 1,841
  • 1
  • 16
  • 25
  • As i mentioned in solution number 2, I tried working with java NIO (that is, using async sockets, channels, selector...), but this folder doesn't supply SSL out of the box, instead you need to actually use SSL Engine which is really complex and hard to implement. I also tried to follow [this](http://rox-xmlrpc.sourceforge.net/niotut/index.html) implementation, with no success. – Daniel L. Nov 05 '12 at 12:11
  • One thing you may want to try then is simply to have a reading thread along with blocking i/o on socket. no timers, just let it stay reading data from socket. Writing back to the socket from another thread should not be a problem then. Use Handlers to communicate with the client thread. NIO would still work, but that would require most likely too big effort to get it done - and done right. – Tomasz W Nov 05 '12 at 12:49
  • one last thing regarding "writing" to these every 4 seconds. Use the same handlers. Handlers utilize something called postDelayed / sendEmptyMessageDelayed / sendMessageDelayed. Just post a delayed request / message and don't spawn timers. it will work like a charm. – Tomasz W Nov 05 '12 at 13:01
  • Can you please elaborate a little more about your solution, I'm not sure I understand it. – Daniel L. Nov 05 '12 at 13:13
  • For every client connection that you have spawn one reading thread and if you wish - one client handler (let's assume for simplicity, that the handler has a dedicated thread, so every client connection has two threads - one reading data and one dealing with it). let reading thread be 'stuck' reading data. simply put: while (!closed) { processData(socket); }. processData() should capture your entire packet, and when done - use aforementioned handler to post it to client thread. – Tomasz W Nov 05 '12 at 15:56
  • the same handler can be used for periodically querying data from client, by calling sendMessageDelayed() for example (or postDelayed, if you wish). single ssl socket can be shared among two threads. – Tomasz W Nov 05 '12 at 15:57
  • Hi @Tichy, I Tried to do it with handlers (each socket has its own thread, and handler). This works but still when I'm updating my UI (list view) I get small lags (about half a second). I already tried to improve the list view performance (by using holder, and by recycling convert view). any thoughts? – Daniel L. Nov 06 '12 at 11:37