Android Open Source - smsgateway-android Bosh Connection






From Project

Back to project page smsgateway-android.

License

The source code is released under:

GNU General Public License

If you think the Android project smsgateway-android 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

/*
 */*from   w w  w  .  j ava2 s.c o m*/
 * ((e)) emite: A pure gwt (Google Web Toolkit) xmpp (jabber) library
 *
 * (c) 2008-2009 The emite development team (see CREDITS for details)
 * This file is part of emite.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package com.calclab.emite.core.client.bosh;

import java.util.List;

import android.util.Log;

import com.calclab.emite.core.client.packet.IPacket;
import com.calclab.emite.core.client.packet.Packet;
import com.calclab.emite.core.client.services.ConnectorCallback;
import com.calclab.emite.core.client.services.ConnectorException;
import com.calclab.emite.core.client.services.ScheduledAction;
import com.calclab.emite.core.client.services.Services;
import com.calclab.suco.client.events.Event;
import com.calclab.suco.client.events.Event0;
import com.calclab.suco.client.events.Listener;

public class BoshConnection implements Connection {
  private int activeConnections;
  private Packet body;
  private final Services services;
  private final ConnectorCallback listener;
  private boolean running;
  private StreamSettings stream;
  private final Event<String> onError;
  private final Event<String> onDisconnected;
  private final Event0 onConnected;
  private final Event<IPacket> onStanzaReceived;
  private final Event<IPacket> onStanzaSent;
  private boolean shouldCollectResponses;
  private BoshSettings userSettings;
  private int errors;
  private final Event<String> onResponse;

  public BoshConnection(final Services services) {
    this.services = services;
    this.onError = new Event<String>("bosh:onError");
    this.onDisconnected = new Event<String>("bosh:onDisconnected");
    this.onConnected = new Event0("bosh:onConnected");
    this.onStanzaReceived = new Event<IPacket>("bosh:onReceived");
    this.onResponse = new Event<String>("bosh:onResponse");
    this.onStanzaSent = new Event<IPacket>("bosh:onSent");
    this.errors = 0;

    this.listener = new ConnectorCallback() {

      public void onError(final String request, final Throwable throwable) {
        if (running) {
          Log.d("gw", "Connection error (total: {0}): {1}", throwable);
          errors++;
          if (errors > 2) {
            running = false;
            onError.fire("Connection error: " + throwable.toString());
          } else {
            Log.d("gw", "Error retry: " + throwable);
            send(request);
          }
        }
      }

      public void onResponseReceived(final int statusCode, final String content) {
        try {
          errors = 0;
          activeConnections--;
          if (running) {
            if (statusCode != 200) {
              running = false;
              onError.fire("Bad status: " + statusCode);
            } else {
              onResponse.fire(content);
              final IPacket response = services.toXML(content);
              if (response != null
                  && "body".equals(response.getName())) {
                handleResponse(response);
              } else {
                onError.fire("Bad response: " + content);
              }
            }
          }
        } catch (Exception e) {
        }
      }
    };
  }

  public void connect() {
    assert userSettings != null;

    if (!running) {
      this.running = true;
      this.stream = new StreamSettings();
      this.activeConnections = 0;
      createInitialBody(userSettings);
      sendBody();
    }
  }

  public void disconnect() {
    createBody();
    body.setAttribute("type", "terminate");
    sendBody();
    running = false;
    stream = null;
    onDisconnected.fire("logged out");
  }

  public boolean isConnected() {
    return stream != null;
  }

  public void onError(final Listener<String> listener) {
    onError.add(listener);
  }

  public void onResponse(final Listener<String> listener) {
    onResponse.add(listener);
  }

  public void onStanzaReceived(final Listener<IPacket> listener) {
    onStanzaReceived.add(listener);
  }

  public void onStanzaSent(final Listener<IPacket> listener) {
    onStanzaSent.add(listener);
  }

  public StreamSettings pause() {
    createBody();
    body.setAttribute("pause", stream.maxPause);
    sendBody();
    return stream;
  }

  public void removeOnStanzaReceived(final Listener<IPacket> listener) {
    onStanzaReceived.remove(listener);
  }

  public void restartStream() {
    createBody();
    body.setAttribute("xmlns:xmpp", "urn:xmpp:xbosh");
    body.setAttribute("xmpp:restart", "true");
    body.setAttribute("to", userSettings.hostName);
    body.setAttribute("xml:lang", "en");
  }

  public boolean resume(final StreamSettings settings) {
    running = true;
    stream = settings;
    continueConnection(null);
    return running;
  }

  public void send(final IPacket packet) {
    createBody();
    body.addChild(packet);
    sendBody();
    onStanzaSent.fire(packet);
  }

  public void setSettings(final BoshSettings settings) {
    this.userSettings = settings;
  }

  private void continueConnection(final String ack) {
    if (isConnected() && activeConnections == 0) {
      if (body != null) {
        sendBody();
      } else {
        final long currentRID = stream.rid;
        // FIXME: hardcoded
        final int msecs = 6000;
        services.schedule(msecs, new ScheduledAction() {
          public void run() {
            if (body == null && stream != null && stream.rid == currentRID) {
              createBody();
              sendBody();
            }
          }
        });
      }
    }
  }

  private void createBody() {
    if (body == null) {
      this.body = new Packet("body");
      body.With("xmlns", "http://jabber.org/protocol/httpbind");
      body.With("rid", stream.getNextRid());
      if (stream != null) {
        body.With("sid", stream.sid);
      }
    }
  }

  private void createInitialBody(final BoshSettings userSettings) {
    this.body = new Packet("body");
    body.setAttribute("content", "text/xml; charset=utf-8");
    body.setAttribute("xmlns", "http://jabber.org/protocol/httpbind");
    body.setAttribute("xmlns:xmpp", "urn:xmpp:xbosh");
    body.setAttribute("ver", userSettings.version);
    body.setAttribute("xmpp:version", "1.0");
    body.setAttribute("xml:lang", "en");
    body.setAttribute("ack", "1");
    body.setAttribute("secure", "true");
    body.setAttribute("rid", stream.getNextRid());
    body.setAttribute("to", userSettings.hostName);
    body.With("hold", userSettings.hold);
    body.With("wait", userSettings.wait);
  }

  private void handleResponse(final IPacket response) {
    if (isTerminate(response.getAttribute("type"))) {
      onDisconnected.fire("disconnected by server");
    } else {
      if (stream.sid == null) {
        initStream(response);
        onConnected.fire();
      }
      shouldCollectResponses = true;
      final List<? extends IPacket> stanzas = response.getChildren();
      for (final IPacket stanza : stanzas) {
        onStanzaReceived.fire(stanza);
      }
      shouldCollectResponses = false;
      continueConnection(response.getAttribute("ack"));
    }
  }

  private void initStream(final IPacket response) {
    stream.sid = response.getAttribute("sid");
    stream.wait = response.getAttribute("wait");
    stream.inactivity = response.getAttribute("inactivity");
    stream.maxPause = response.getAttribute("maxpause");
  }

  private boolean isTerminate(final String type) {
    // Openfire bug: terminal instead of terminate
    return "terminate".equals(type) || "terminal".equals(type);
  }

  /**
   * Sends a new request (and count the activeConnections)
   * 
   * @param request
   */
  private void send(final String request) {
    try {
      activeConnections++;
      services.send(userSettings.httpBase, request, listener);
      stream.lastRequestTime = services.getCurrentTime();
    } catch (final ConnectorException e) {
      activeConnections--;
      e.printStackTrace();
    }
  }

  private void sendBody() {
    if (!shouldCollectResponses) {
      final String request = services.toString(body);
      body = null;
      send(request);
    }
  }
}




Java Source Code List

com.calclab.emite.core.client.EmiteCoreModule.java
com.calclab.emite.core.client.bosh.BoshConnection.java
com.calclab.emite.core.client.bosh.BoshSettings.java
com.calclab.emite.core.client.bosh.Connection.java
com.calclab.emite.core.client.bosh.StreamSettings.java
com.calclab.emite.core.client.packet.AbstractPacket.java
com.calclab.emite.core.client.packet.DelegatedPacket.java
com.calclab.emite.core.client.packet.IPacket.java
com.calclab.emite.core.client.packet.MatcherFactory.java
com.calclab.emite.core.client.packet.NoPacket.java
com.calclab.emite.core.client.packet.PacketMatcher.java
com.calclab.emite.core.client.packet.PacketRenderer.java
com.calclab.emite.core.client.packet.PacketTestSuite.java
com.calclab.emite.core.client.packet.Packet.java
com.calclab.emite.core.client.packet.TextPacket.java
com.calclab.emite.core.client.packet.TextUtils.java
com.calclab.emite.core.client.packet.android.AndroidPacket.java
com.calclab.emite.core.client.services.ConnectorCallback.java
com.calclab.emite.core.client.services.ConnectorException.java
com.calclab.emite.core.client.services.ScheduledAction.java
com.calclab.emite.core.client.services.Services.java
com.calclab.emite.core.client.services.android.AndroidConnector.java
com.calclab.emite.core.client.services.android.AndroidScheduler.java
com.calclab.emite.core.client.services.android.AndroidServices.java
com.calclab.emite.core.client.services.android.AndroidXMLService.java
com.calclab.emite.core.client.xmpp.resource.ResourceBindingManager.java
com.calclab.emite.core.client.xmpp.sasl.AuthorizationTransaction.java
com.calclab.emite.core.client.xmpp.sasl.Base64Coder.java
com.calclab.emite.core.client.xmpp.sasl.SASLManager.java
com.calclab.emite.core.client.xmpp.session.AbstractSession.java
com.calclab.emite.core.client.xmpp.session.IMSessionManager.java
com.calclab.emite.core.client.xmpp.session.IQManager.java
com.calclab.emite.core.client.xmpp.session.SessionComponent.java
com.calclab.emite.core.client.xmpp.session.SessionImpl.java
com.calclab.emite.core.client.xmpp.session.SessionReady.java
com.calclab.emite.core.client.xmpp.session.Session.java
com.calclab.emite.core.client.xmpp.stanzas.BasicStanza.java
com.calclab.emite.core.client.xmpp.stanzas.IQ.java
com.calclab.emite.core.client.xmpp.stanzas.Message.java
com.calclab.emite.core.client.xmpp.stanzas.Presence.java
com.calclab.emite.core.client.xmpp.stanzas.Stanza.java
com.calclab.emite.core.client.xmpp.stanzas.XmppURICache.java
com.calclab.emite.core.client.xmpp.stanzas.XmppURI.java
com.calclab.emite.im.client.InstantMessagingModule.java
com.calclab.emite.im.client.chat.AbstractChat.java
com.calclab.emite.im.client.chat.ChatManager.java
com.calclab.emite.im.client.chat.Chat.java
com.calclab.emite.im.client.chat.PairChatManager.java
com.calclab.emite.im.client.chat.PairChat.java
com.calclab.emite.im.client.presence.PresenceManagerImpl.java
com.calclab.emite.im.client.presence.PresenceManager.java
com.calclab.emite.im.client.roster.RosterImpl.java
com.calclab.emite.im.client.roster.RosterItem.java
com.calclab.emite.im.client.roster.Roster.java
com.calclab.emite.im.client.roster.SubscriptionManagerImpl.java
com.calclab.emite.im.client.roster.SubscriptionManager.java
com.calclab.emite.im.client.roster.SubscriptionState.java
com.calclab.suco.client.SucoCoreModule.java
com.calclab.suco.client.SucoFactory.java
com.calclab.suco.client.Suco.java
com.calclab.suco.client.events.Event0.java
com.calclab.suco.client.events.Event2.java
com.calclab.suco.client.events.Event.java
com.calclab.suco.client.events.Listener0.java
com.calclab.suco.client.events.Listener2.java
com.calclab.suco.client.events.Listener.java
com.calclab.suco.client.ioc.Container.java
com.calclab.suco.client.ioc.Decorator.java
com.calclab.suco.client.ioc.HashMapContainer.java
com.calclab.suco.client.ioc.Provider.java
com.calclab.suco.client.ioc.decorator.Chain.java
com.calclab.suco.client.ioc.decorator.GroupedSingleton.java
com.calclab.suco.client.ioc.decorator.NoDecoration.java
com.calclab.suco.client.ioc.decorator.ProviderCollection.java
com.calclab.suco.client.ioc.decorator.Singleton.java
com.calclab.suco.client.ioc.module.AbstractModule.java
com.calclab.suco.client.ioc.module.Factory.java
com.calclab.suco.client.ioc.module.ModuleBuilderImpl.java
com.calclab.suco.client.ioc.module.ModuleBuilder.java
com.calclab.suco.client.ioc.module.SucoModule.java
com.calclab.suco.client.log.Logger.java
com.calclab.suco.client.signal.Signal0.java
com.calclab.suco.client.signal.Signal2.java
com.calclab.suco.client.signal.Signal.java
com.calclab.suco.client.signal.Slot0.java
com.calclab.suco.client.signal.Slot2.java
com.calclab.suco.client.signal.Slot.java
com.nubgames.smsgateway.BOSHConnection.java
com.nubgames.smsgateway.BootCompleted.java
com.nubgames.smsgateway.Password.java
com.nubgames.smsgateway.SMSGateway.java
com.nubgames.smsgateway.SMSReceiver.java
com.nubgames.smsgateway.Settings.java
com.nubgames.smsgateway.StatusTextView.java
com.nubgames.smsgateway.Status.java
com.nubgames.smsgateway.TextRouter.java