Android Open Source - ubihelper Peer Connection Scheduler






From Project

Back to project page ubihelper.

License

The source code is released under:

GNU General Public License

If you think the Android project ubihelper listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright (c) 2012 The University of Nottingham
 * /*from   www. j  a v  a2  s. c om*/
 * This file is part of ubihelper
 *
 *  ubihelper is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  ubihelper is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with ubihelper. If not, see <http://www.gnu.org/licenses/>.
 *  
 *  @author Chris Greenhalgh (cmg@cs.nott.ac.uk), The University of Nottingham
 */
package uk.ac.horizon.ubihelper.net;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;



/** Scheduler thread for PeerConnections
 * 
 * @author cmg
 *
 */
public class PeerConnectionScheduler extends Thread {
  static Logger logger = Logger.getLogger(PeerConnectionScheduler.class.getName());
  
  private ServerSocketChannel serverSocketChannel;
  private Selector selector;
  private boolean closed = false;
  private ReentrantLock selectorLock = new ReentrantLock();
  private Listener listener;
  
  public static interface Listener {
    void onAccept(PeerConnectionScheduler pcs, PeerConnection newPeerConnection);
  }
  
  /** cons - with server socket 
   * @throws IOException */
  public PeerConnectionScheduler(ServerSocketChannel ssc) throws IOException {
    serverSocketChannel = ssc;
    serverSocketChannel.configureBlocking(false);
    selector = Selector.open();
    if (serverSocketChannel!=null)
      serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT, serverSocketChannel);
  }

  public synchronized void close() {
    closed = true;
    try {
      selector.close();
    }
    catch (Exception e) {
      /* ignore */
    }
  }
  public synchronized void setListener(Listener l) {
    listener = l;
  }
  public PeerConnection connect(InetSocketAddress address, OnPeerConnectionListener pcl, Object attachment) throws IOException {
    logger.info("Connect to "+address);
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.configureBlocking(false);
    socketChannel.connect(address);
    PeerConnection pc = new PeerConnection(selector, selectorLock);
    pc.setOnPeerConnectionListener(pcl);
    pc.attach(attachment);
    pc.changeSocketChannel(socketChannel);
    return pc;
  }
  
  public void run() {
    while (!closed) {
      try {
        // nasty register problem - see http://stackoverflow.com/questions/1057224/thread-is-stuck-while-registering-channel-with-selector-in-java-nio-server
        // ensure other gets chance to complete
        selectorLock.lock();
        selectorLock.unlock();
        logger.info("Select...");
        int i = selector.select();
        logger.info("select done with "+i+" ready");
      } catch (IOException e) {
        logger.warning("doing select(): "+e.getMessage());
      }
      Set<SelectionKey> keys = null;
      try {
        keys = selector.selectedKeys();
      }
      catch (ClosedSelectorException e) {
        logger.info("Selector closed - exiting");
        break;
      }
      for (SelectionKey key : keys) {
        Object obj = key.attachment();
        if (obj instanceof PeerConnection) {
          PeerConnection pc = (PeerConnection)obj;
          try {
            logger.info("Select on PeerConnection connect="+key.isConnectable()+" read="+key.isReadable()+" write="+key.isWritable()+" "+pc);
            if (key.isConnectable())
              pc.checkConnect();
            if (key.isReadable())
              pc.checkRecv();
            if (key.isWritable())
              pc.checkSend();
            int ops = pc.getWaitingOps();
            logger.info("register for ops "+ops);
            key.channel().register(selector, ops, pc);
          } catch (Exception e) {
            logger.warning("Error checking peer connection: "+e);
            e.printStackTrace();
          }
        } else if (serverSocketChannel!=null && obj==serverSocketChannel && key.isAcceptable()) {
          try {
            SocketChannel socketChannel = serverSocketChannel.accept();
            if (socketChannel==null) {
              logger.info("Event on serverSocketChannel but accept returned null");
              continue;
            }              
            socketChannel.configureBlocking(false);
            //Toast.makeText(service, "Accepted connect", Toast.LENGTH_SHORT).show();
            PeerConnection pc = new PeerConnection(selector, selectorLock);
            pc.changeSocketChannel(socketChannel);
            logger.info("Accepted new connection from "+socketChannel.socket().getInetAddress().getHostAddress()+":"+socketChannel.socket().getPort());
            synchronized (this) {
              if (listener!=null) {
                try {
                  listener.onAccept(this, pc);
                }
                catch (Exception e) {
                  //logger.warning("Error in onAccept listener: "+e.getMessage());
                  logger.log(Level.WARNING, "Error in onAccept listener", e);
                }
              }
            }
          } catch (IOException e) {
            logger.warning("Error accepted new connection: "+e.getMessage());
          }            
        }
      }
    }
    // update closed?!
    synchronized (this) {}
  }
  
  
  // test
  public static void main(String args[]) {
    try {
      ServerSocketChannel ssc = ServerSocketChannel.open();
      // any port
      ssc.socket().bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0));
      int serverPort = ssc.socket().getLocalPort();
      logger.info("Test server socket on port "+serverPort);
      ssc.configureBlocking(false);
      PeerConnectionScheduler pcs = new PeerConnectionScheduler(ssc);
      final OnPeerConnectionListener pcl = new OnPeerConnectionListener() {
        
        public void onRecvMessage(PeerConnection pc) {
          // TODO Auto-generated method stub
          logger.info("onRecvMessage: "+pc);
          while(true) {
            Message m = pc.getMessage();
            if (m==null)
              break;
            logger.info("Got message: "+m);
          }
        }
        
        public void onFail(PeerConnection pc, boolean sendFailed,
            boolean recvFailed, boolean connectFailed) {
          // TODO Auto-generated method stub
          logger.info("onFail: "+pc);
        }

        public void onConnected(PeerConnection pc) {
          // TODO Auto-generated method stub
          logger.info("onConnected: "+pc);
        }
      };
      pcs.setListener(new Listener() {

        public void onAccept(PeerConnectionScheduler pcs,
            PeerConnection newPeerConnection) {
          // TODO Auto-generated method stub
          logger.info("onAccept: "+newPeerConnection);
          
          newPeerConnection.setOnPeerConnectionListener(pcl);
        }
        
      });
      pcs.start();
      logger.info("Started scheduler thread");
      Thread.sleep(1000);
      PeerConnection pc = null;
      for (int i=0;i<args.length; i++) {
        try {
          int port = Integer.parseInt(args[i]);
          logger.info("Try connect to "+port);
          pc = pcs.connect(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), port), pcl, null);
        }
        catch (NumberFormatException e) {
          logger.warning("Arg "+i+" not a port number ("+args[i]+")");
        }
        Thread.sleep(1000);
        if (pc!=null) {
          logger.info("Send hello...");
          Message m =new Message(Message.Type.HELLO, null, null, Message.getHelloBody());
          pc.sendMessage(m);
          logger.info("hello sent");
          Thread.sleep(1000);
        }
      }
    }
    catch (Exception e) {
      logger.warning("Error: "+e);
      e.printStackTrace();
    }
  }
}




Java Source Code List

org.json.JSONArray.java
org.json.JSONException.java
org.json.JSONObject.java
org.json.JSONString.java
org.json.JSONStringer.java
org.json.JSONTokener.java
org.json.JSONWriter.java
uk.ac.horizon.ubihelper.channel.ChannelFactory.java
uk.ac.horizon.ubihelper.channel.ChannelListener.java
uk.ac.horizon.ubihelper.channel.ChannelManager.java
uk.ac.horizon.ubihelper.channel.ChannelValueEvent.java
uk.ac.horizon.ubihelper.channel.NamedChannel.java
uk.ac.horizon.ubihelper.channel.PullSubscription.java
uk.ac.horizon.ubihelper.channel.SharedVariableChannel.java
uk.ac.horizon.ubihelper.channel.Subscription.java
uk.ac.horizon.ubihelper.dns.DnsClient.java
uk.ac.horizon.ubihelper.dns.DnsProtocol.java
uk.ac.horizon.ubihelper.dns.DnsServer.java
uk.ac.horizon.ubihelper.dns.DnsUtils.java
uk.ac.horizon.ubihelper.httpserver.HttpClientHandler.java
uk.ac.horizon.ubihelper.httpserver.HttpContinuation.java
uk.ac.horizon.ubihelper.httpserver.HttpError.java
uk.ac.horizon.ubihelper.httpserver.HttpListener.java
uk.ac.horizon.ubihelper.j2se.Base64.java
uk.ac.horizon.ubihelper.j2se.Server.java
uk.ac.horizon.ubihelper.net.Fragment.java
uk.ac.horizon.ubihelper.net.Marshaller.java
uk.ac.horizon.ubihelper.net.Message.java
uk.ac.horizon.ubihelper.net.OnPeerConnectionListener.java
uk.ac.horizon.ubihelper.net.PeerConnectionScheduler.java
uk.ac.horizon.ubihelper.net.PeerConnection.java
uk.ac.horizon.ubihelper.protocol.ClientInfo.java
uk.ac.horizon.ubihelper.protocol.ClientState.java
uk.ac.horizon.ubihelper.protocol.MessageUtils.java
uk.ac.horizon.ubihelper.protocol.PeerInfo.java
uk.ac.horizon.ubihelper.protocol.ProtocolManager.java
uk.ac.horizon.ubihelper.service.BroadcastIntentSubscription.java
uk.ac.horizon.ubihelper.service.EnabledPeersChannel.java
uk.ac.horizon.ubihelper.service.LogManager.java
uk.ac.horizon.ubihelper.service.LogSubscription.java
uk.ac.horizon.ubihelper.service.PeerManager.java
uk.ac.horizon.ubihelper.service.PeersOpenHelper.java
uk.ac.horizon.ubihelper.service.Service.java
uk.ac.horizon.ubihelper.service.WifiDiscoveryManager.java
uk.ac.horizon.ubihelper.service.channel.BluetoothDiscoveryChannel.java
uk.ac.horizon.ubihelper.service.channel.CellLocationChannel.java
uk.ac.horizon.ubihelper.service.channel.CellStrengthChannel.java
uk.ac.horizon.ubihelper.service.channel.GpsStatusChannel.java
uk.ac.horizon.ubihelper.service.channel.LocationChannel.java
uk.ac.horizon.ubihelper.service.channel.MicChannel.java
uk.ac.horizon.ubihelper.service.channel.PollingChannel.java
uk.ac.horizon.ubihelper.service.channel.SensorChannel.java
uk.ac.horizon.ubihelper.service.channel.TimeChannel.java
uk.ac.horizon.ubihelper.service.channel.WifiScannerChannel.java
uk.ac.horizon.ubihelper.ui.AboutActivity.java
uk.ac.horizon.ubihelper.ui.ChannelListActivity.java
uk.ac.horizon.ubihelper.ui.ChannelPeerListActivity.java
uk.ac.horizon.ubihelper.ui.ChannelValueActivity.java
uk.ac.horizon.ubihelper.ui.ChannelViewActivity.java
uk.ac.horizon.ubihelper.ui.LoggingChannelListActivity.java
uk.ac.horizon.ubihelper.ui.LoggingPreferences.java
uk.ac.horizon.ubihelper.ui.MainPreferences.java
uk.ac.horizon.ubihelper.ui.ManagePeersActivity.java
uk.ac.horizon.ubihelper.ui.PeerInfoActivity.java
uk.ac.horizon.ubihelper.ui.PeerManualAddActivity.java
uk.ac.horizon.ubihelper.ui.PeerRequestActivity.java
uk.ac.horizon.ubihelper.ui.PeerRequestInfoActivity.java
uk.ac.horizon.ubihelper.ui.SearchPeersActivity.java
uk.ac.horizon.ubihelper.ui.TestActivity.java
uk.ac.horizon.ubihelper.ui.WifiStatusActivity.java
uk.ac.horizon.ubihelper.websocket.ClientWebsocket.java
uk.ac.horizon.ubihelper.websocket.ReadyState.java
uk.ac.horizon.ubihelper.websocket.SocketChannelWebsocket.java
uk.ac.horizon.ubihelper.websocket.WebsocketListener.java
uk.ac.horizon.ubihelper.websocket.Websocket.java