Package net.tomp2p.relay.android

Source Code of net.tomp2p.relay.android.AndroidRelayConnection

package net.tomp2p.relay.android;

import net.tomp2p.connection.ConnectionConfiguration;
import net.tomp2p.futures.BaseFutureAdapter;
import net.tomp2p.futures.FutureDone;
import net.tomp2p.futures.FutureResponse;
import net.tomp2p.message.Message;
import net.tomp2p.message.Message.Type;
import net.tomp2p.p2p.Peer;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.relay.BaseRelayConnection;
import net.tomp2p.relay.RelayUtils;
import net.tomp2p.rpc.DispatchHandler;
import net.tomp2p.rpc.RPC.Commands;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* When an Android device is behind a NAT, this class Holds a connection to one relay. It has
* additional capabilities like retrieving the buffer.
*
* @author Nico Rutishauser
*
*/
public class AndroidRelayConnection extends BaseRelayConnection {

  private static final Logger LOG = LoggerFactory.getLogger(AndroidRelayConnection.class);
  /**
   * The maximum number of attempts to reach the relay peer. If the counter exceeds this limit, the relay is
   * declared as unreachable
   */
  private static final int MAX_FAIL_COUNT = 5;

  private final DispatchHandler dispatchHandler;
  private final Peer peer;
  private final ConnectionConfiguration config;
  private final GCMServerCredentials gcmServerCredentials;
  private int reachRelayFailCounter = 0;
  private final BufferedMessageHandler bufferedMessageHandler;

  public AndroidRelayConnection(PeerAddress relayAddress, DispatchHandler dispatchHandler, Peer peer,
      ConnectionConfiguration config, GCMServerCredentials gcmServerCredentials) {
    super(relayAddress);
    this.dispatchHandler = dispatchHandler;
    this.peer = peer;
    this.config = config;
    this.gcmServerCredentials = gcmServerCredentials;
    this.bufferedMessageHandler = new BufferedMessageHandler(peer, dispatchHandler, config);
  }

  @Override
  public FutureResponse sendToRelay(Message message) {
    // send it over a newly opened connection
    return RelayUtils.connectAndSend(peer, message, config);
  }

  /**
   * Get the buffer from the relay. This method should be called as soon as the device receives the tickle
   * message from the relay over GCM.
   *
   * @return when the buffer request is done
   */
  public FutureDone<Void> sendBufferRequest() {
    final FutureDone<Void> futureDone = new FutureDone<Void>();

    Message message = dispatchHandler.createMessage(relayAddress(), Commands.RELAY.getNr(), Type.REQUEST_4);
    // close the connection after this message
    message.keepAlive(false);

    FutureResponse response = sendToRelay(message);
    response.addListener(new BaseFutureAdapter<FutureResponse>() {
      @Override
      public void operationComplete(FutureResponse futureResponse) throws Exception {
        if (futureResponse.isSuccess()) {
          // reset the fail counter
          reachRelayFailCounter = 0;
         
          LOG.debug("Successfully got the buffer from relay {}", relayAddress());
          bufferedMessageHandler.handleBufferResponse(futureResponse.responseMessage(), futureDone);
        } else {
          LOG.error("Cannot get the buffer from relay {}. Reason: {}", relayAddress(), futureResponse.failedReason());
          futureDone.failed(futureResponse);
          failedToContactRelay();
        }
      }
    });

    return futureDone;
  }

  @Override
  public FutureDone<Void> shutdown() {
    // Nothing to do
    return new FutureDone<Void>().done();
  }
 
  private void failedToContactRelay() {
    LOG.warn("Failed to contact the relay peer. Increase the counter to detect long-term disconnections");
    reachRelayFailCounter++;
    if(reachRelayFailCounter > MAX_FAIL_COUNT) {
      LOG.error("The relay {} was not reachable for {} send attempts", relayAddress(), reachRelayFailCounter);
      notifyCloseListeners();
    }
  }

  @Override
  public void onMapUpdateFailed() {
    failedToContactRelay();
  }

  @Override
  public void onMapUpdateSuccess() {
    // reset the couter
    reachRelayFailCounter = 0;
  }

  public GCMServerCredentials gcmServerCredentials() {
    return gcmServerCredentials;
  }

}
TOP

Related Classes of net.tomp2p.relay.android.AndroidRelayConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.