summaryrefslogtreecommitdiffstats
path: root/docs/html/google
diff options
context:
space:
mode:
authorkmccormick <kmccormick@google.com>2014-07-16 21:02:36 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-07-16 16:25:13 +0000
commitfc8a3b5f06fe725ed561fb3535efd02b16c526ea (patch)
tree9f194ffad64f7e8935a66b2aa06f0f70acd3a390 /docs/html/google
parent046702ba57c34893e058674dc36192796af20da7 (diff)
parent9c311fb4c686b14688c55df4d4df534471314384 (diff)
downloadframeworks_base-fc8a3b5f06fe725ed561fb3535efd02b16c526ea.zip
frameworks_base-fc8a3b5f06fe725ed561fb3535efd02b16c526ea.tar.gz
frameworks_base-fc8a3b5f06fe725ed561fb3535efd02b16c526ea.tar.bz2
Merge "Doc Update: new Smack sample." into klp-modular-docs
Diffstat (limited to 'docs/html/google')
-rw-r--r--docs/html/google/gcm/ccs.jd612
1 files changed, 320 insertions, 292 deletions
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
index 4389e3d..90d8d4c 100644
--- a/docs/html/google/gcm/ccs.jd
+++ b/docs/html/google/gcm/ccs.jd
@@ -535,6 +535,8 @@ import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketInterceptor;
import org.jivesoftware.smack.PacketListener;
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketTypeFilter;
@@ -544,352 +546,378 @@ import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.ProviderManager;
+import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.util.StringUtils;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.xmlpull.v1.XmlPullParser;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
-import java.util.Random;
+import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLSocketFactory;
+
/**
- * Sample Smack implementation of a client for GCM Cloud Connection Server.
+ * Sample Smack implementation of a client for GCM Cloud Connection Server. This
+ * code can be run as a standalone CCS client.
*
* &lt;p&gt;For illustration purposes only.
*/
public class SmackCcsClient {
- Logger logger = Logger.getLogger(&quot;SmackCcsClient&quot;);
+ private static final Logger logger = Logger.getLogger(&quot;SmackCcsClient&quot;);
- public static final String GCM_SERVER = &quot;gcm.googleapis.com&quot;;
- public static final int GCM_PORT = 5235;
+ private static final String GCM_SERVER = &quot;gcm.googleapis.com&quot;;
+ private static final int GCM_PORT = 5235;
- public static final String GCM_ELEMENT_NAME = &quot;gcm&quot;;
- public static final String GCM_NAMESPACE = &quot;google:mobile:data&quot;;
+ private static final String GCM_ELEMENT_NAME = &quot;gcm&quot;;
+ private static final String GCM_NAMESPACE = &quot;google:mobile:data&quot;;
- static Random random = new Random();
- XMPPConnection connection;
- ConnectionConfiguration config;
+ static {
- /**
- * XMPP Packet Extension for GCM Cloud Connection Server.
- */
- class GcmPacketExtension extends DefaultPacketExtension {
- String json;
+ ProviderManager.addExtensionProvider(GCM_ELEMENT_NAME, GCM_NAMESPACE,
+ new PacketExtensionProvider() {
+ &#64;Override
+ public PacketExtension parseExtension(XmlPullParser parser) throws
+ Exception {
+ String json = parser.nextText();
+ return new GcmPacketExtension(json);
+ }
+ });
+ }
- public GcmPacketExtension(String json) {
- super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
- this.json = json;
+ private XMPPConnection connection;
+
+ /**
+ * Indicates whether the connection is in draining state, which means that it
+ * will not accept any new downstream messages.
+ */
+ protected volatile boolean connectionDraining = false;
+
+ /**
+ * Sends a downstream message to GCM.
+ *
+ * &#64;return true if the message has been successfully sent.
+ */
+ public boolean sendDownstreamMessage(String jsonRequest) throws
+ NotConnectedException {
+ if (!connectionDraining) {
+ send(jsonRequest);
+ return true;
+ }
+ logger.info(&quot;Dropping downstream message since the connection is draining&quot;);
+ return false;
}
- public String getJson() {
- return json;
+ /**
+ * Returns a random message id to uniquely identify a message.
+ *
+ * &lt;p&gt;Note: This is generated by a pseudo random number generator for
+ * illustration purpose, and is not guaranteed to be unique.
+ */
+ public String nextMessageId() {
+ return &quot;m-&quot; + UUID.randomUUID().toString();
}
- &#64;Override
- public String toXML() {
- return String.format(&quot;&lt;%s xmlns=\&quot;%s\&quot;&gt;%s&lt;/%s&gt;&quot;, GCM_ELEMENT_NAME,
- GCM_NAMESPACE, json, GCM_ELEMENT_NAME);
+ /**
+ * Sends a packet with contents provided.
+ */
+ protected void send(String jsonRequest) throws NotConnectedException {
+ Packet request = new GcmPacketExtension(jsonRequest).toPacket();
+ connection.sendPacket(request);
}
- &#64;SuppressWarnings(&quot;unused&quot;)
- public Packet toPacket() {
- return new Message() {
- // Must override toXML() because it includes a &lt;body&gt;
- &#64;Override
- public String toXML() {
+ /**
+ * Handles an upstream data message from a device application.
+ *
+ * &lt;p&gt;This sample echo server sends an echo message back to the device.
+ * Subclasses should override this method to properly process upstream messages.
+ */
+ protected void handleUpstreamMessage(Map&lt;String, Object&gt; jsonObject) {
+ // PackageName of the application that sent this message.
+ String category = (String) jsonObject.get(&quot;category&quot;);
+ String from = (String) jsonObject.get(&quot;from&quot;);
+ &#64;SuppressWarnings(&quot;unchecked&quot;)
+ Map&lt;String, String&gt; payload = (Map&lt;String, String&gt;) jsonObject.get(&quot;data&quot;);
+ payload.put(&quot;ECHO&quot;, &quot;Application: &quot; + category);
+
+ // Send an ECHO response back
+ String echo = createJsonMessage(from, nextMessageId(), payload,
+ &quot;echo:CollapseKey&quot;, null, false);
- StringBuilder buf = new StringBuilder();
- buf.append(&quot;&lt;message&quot;);
- if (getXmlns() != null) {
- buf.append(&quot; xmlns=\&quot;&quot;).append(getXmlns()).append(&quot;\&quot;&quot;);
- }
- if (getLanguage() != null) {
- buf.append(&quot; xml:lang=\&quot;&quot;).append(getLanguage()).append(&quot;\&quot;&quot;);
- }
- if (getPacketID() != null) {
- buf.append(&quot; id=\&quot;&quot;).append(getPacketID()).append(&quot;\&quot;&quot;);
- }
- if (getTo() != null) {
- buf.append(&quot; to=\&quot;&quot;).append(StringUtils.escapeForXML(getTo())).append(&quot;\&quot;&quot;);
- }
- if (getFrom() != null) {
- buf.append(&quot; from=\&quot;&quot;).append(StringUtils.escapeForXML(getFrom())).append(&quot;\&quot;&quot;);
- }
- buf.append(&quot;&gt;&quot;);
- buf.append(GcmPacketExtension.this.toXML());
- buf.append(&quot;&lt;/message&gt;&quot;);
- return buf.toString();
+ try {
+ sendDownstreamMessage(echo);
+ } catch (NotConnectedException e) {
+ logger.log(Level.WARNING, &quot;Not connected anymore, echo message is
+ not sent&quot;, e);
}
- };
}
- }
- public SmackCcsClient() {
- // Add GcmPacketExtension
- ProviderManager.getInstance().addExtensionProvider(GCM_ELEMENT_NAME,
- GCM_NAMESPACE, new PacketExtensionProvider() {
-
- &#64;Override
- public PacketExtension parseExtension(XmlPullParser parser)
- throws Exception {
- String json = parser.nextText();
- GcmPacketExtension packet = new GcmPacketExtension(json);
- return packet;
- }
- });
- }
-
- /**
- * Returns a random message id to uniquely identify a message.
- *
- * &lt;p&gt;Note:
- * This is generated by a pseudo random number generator for illustration purpose,
- * and is not guaranteed to be unique.
- *
- */
- public String getRandomMessageId() {
- return &quot;m-&quot; + Long.toString(random.nextLong());
- }
-
- /**
- * Sends a downstream GCM message.
- */
- public void send(String jsonRequest) {
- Packet request = new GcmPacketExtension(jsonRequest).toPacket();
- connection.sendPacket(request);
- }
+ /**
+ * Handles an ACK.
+ *
+ * &lt;p&gt;Logs a {@code INFO} message, but subclasses could override it to
+ * properly handle ACKs.
+ */
+ protected void handleAckReceipt(Map&lt;String, Object&gt; jsonObject) {
+ String messageId = (String) jsonObject.get(&quot;message_id&quot;);
+ String from = (String) jsonObject.get(&quot;from&quot;);
+ logger.log(Level.INFO, &quot;handleAckReceipt() from: &quot; + from + &quot;,
+ messageId: &quot; + messageId);
+ }
- /**
- * Handles an upstream data message from a device application.
- *
- * &lt;p&gt;This sample echo server sends an echo message back to the device.
- * Subclasses should override this method to process an upstream message.
- */
- public void handleIncomingDataMessage(Map&lt;String, Object&gt; jsonObject) {
- String from = jsonObject.get(&quot;from&quot;).toString();
-
- // PackageName of the application that sent this message.
- String category = jsonObject.get(&quot;category&quot;).toString();
-
- // Use the packageName as the collapseKey in the echo packet
- String collapseKey = &quot;echo:CollapseKey&quot;;
- &#64;SuppressWarnings(&quot;unchecked&quot;)
- Map&lt;String, String&gt; payload = (Map&lt;String, String&gt;) jsonObject.get(&quot;data&quot;);
- payload.put(&quot;ECHO&quot;, &quot;Application: &quot; + category);
-
- // Send an ECHO response back
- String echo = createJsonMessage(from, getRandomMessageId(), payload, collapseKey, null, false);
- send(echo);
- }
+ /**
+ * Handles a NACK.
+ *
+ * &lt;p&gt;Logs a {@code INFO} message, but subclasses could override it to
+ * properly handle NACKs.
+ */
+ protected void handleNackReceipt(Map&lt;String, Object&gt; jsonObject) {
+ String messageId = (String) jsonObject.get(&quot;message_id&quot;);
+ String from = (String) jsonObject.get(&quot;from&quot;);
+ logger.log(Level.INFO, &quot;handleNackReceipt() from: &quot; + from + &quot;,
+ messageId: &quot; + messageId);
+ }
- /**
- * Handles an ACK.
- *
- * &lt;p&gt;By default, it only logs a {@code INFO} message, but subclasses could override it to
- * properly handle ACKS.
- */
- public void handleAckReceipt(Map&lt;String, Object&gt; jsonObject) {
- String messageId = jsonObject.get(&quot;message_id&quot;).toString();
- String from = jsonObject.get(&quot;from&quot;).toString();
- logger.log(Level.INFO, &quot;handleAckReceipt() from: &quot; + from + &quot;, messageId: &quot; + messageId);
- }
+ protected void handleControlMessage(Map&lt;String, Object&gt; jsonObject) {
+ logger.log(Level.INFO, &quot;handleControlMessage(): &quot; + jsonObject);
+ String controlType = (String) jsonObject.get(&quot;control_type&quot;);
+ if (&quot;CONNECTION_DRAINING&quot;.equals(controlType)) {
+ connectionDraining = true;
+ } else {
+ logger.log(Level.INFO, &quot;Unrecognized control type: %s. This could
+ happen if new features are &quot; + &quot;added to the CCS protocol.&quot;,
+ controlType);
+ }
+ }
- /**
- * Handles a NACK.
- *
- * &lt;p&gt;By default, it only logs a {@code INFO} message, but subclasses could override it to
- * properly handle NACKS.
- */
- public void handleNackReceipt(Map&lt;String, Object&gt; jsonObject) {
- String messageId = jsonObject.get(&quot;message_id&quot;).toString();
- String from = jsonObject.get(&quot;from&quot;).toString();
- logger.log(Level.INFO, &quot;handleNackReceipt() from: &quot; + from + &quot;, messageId: &quot; + messageId);
- }
+ /**
+ * Creates a JSON encoded GCM message.
+ *
+ * &#64;param to RegistrationId of the target device (Required).
+ * &#64;param messageId Unique messageId for which CCS will send an
+ * &quot;ack/nack&quot; (Required).
+ * &#64;param payload Message content intended for the application. (Optional).
+ * &#64;param collapseKey GCM collapse_key parameter (Optional).
+ * &#64;param timeToLive GCM time_to_live parameter (Optional).
+ * &#64;param delayWhileIdle GCM delay_while_idle parameter (Optional).
+ * &#64;return JSON encoded GCM message.
+ */
+ public static String createJsonMessage(String to, String messageId,
+ Map&lt;String, String&gt; payload, String collapseKey, Long timeToLive,
+ Boolean delayWhileIdle) {
+ Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
+ message.put(&quot;to&quot;, to);
+ if (collapseKey != null) {
+ message.put(&quot;collapse_key&quot;, collapseKey);
+ }
+ if (timeToLive != null) {
+ message.put(&quot;time_to_live&quot;, timeToLive);
+ }
+ if (delayWhileIdle != null &amp;&amp; delayWhileIdle) {
+ message.put(&quot;delay_while_idle&quot;, true);
+ }
+ message.put(&quot;message_id&quot;, messageId);
+ message.put(&quot;data&quot;, payload);
+ return JSONValue.toJSONString(message);
+ }
- /**
- * Creates a JSON encoded GCM message.
- *
- * &#64;param to RegistrationId of the target device (Required).
- * &#64;param messageId Unique messageId for which CCS will send an &quot;ack/nack&quot; (Required).
- * &#64;param payload Message content intended for the application. (Optional).
- * &#64;param collapseKey GCM collapse_key parameter (Optional).
- * &#64;param timeToLive GCM time_to_live parameter (Optional).
- * &#64;param delayWhileIdle GCM delay_while_idle parameter (Optional).
- * &#64;return JSON encoded GCM message.
- */
- public static String createJsonMessage(String to, String messageId, Map&lt;String, String&gt; payload,
- String collapseKey, Long timeToLive, Boolean delayWhileIdle) {
- Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
- message.put(&quot;to&quot;, to);
- if (collapseKey != null) {
- message.put(&quot;collapse_key&quot;, collapseKey);
+ /**
+ * Creates a JSON encoded ACK message for an upstream message received
+ * from an application.
+ *
+ * &#64;param to RegistrationId of the device who sent the upstream message.
+ * &#64;param messageId messageId of the upstream message to be acknowledged to CCS.
+ * &#64;return JSON encoded ack.
+ */
+ protected static String createJsonAck(String to, String messageId) {
+ Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
+ message.put(&quot;message_type&quot;, &quot;ack&quot;);
+ message.put(&quot;to&quot;, to);
+ message.put(&quot;message_id&quot;, messageId);
+ return JSONValue.toJSONString(message);
}
- if (timeToLive != null) {
- message.put(&quot;time_to_live&quot;, timeToLive);
+
+ /**
+ * Connects to GCM Cloud Connection Server using the supplied credentials.
+ *
+ * &#64;param senderId Your GCM project number
+ * &#64;param apiKey API Key of your project
+ */
+ public void connect(long senderId, String apiKey)
+ throws XMPPException, IOException, SmackException {
+ ConnectionConfiguration config =
+ new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
+ config.setSecurityMode(SecurityMode.enabled);
+ config.setReconnectionAllowed(true);
+ config.setRosterLoadedAtLogin(false);
+ config.setSendPresence(false);
+ config.setSocketFactory(SSLSocketFactory.getDefault());
+
+ connection = new XMPPTCPConnection(config);
+ connection.connect();
+
+ connection.addConnectionListener(new LoggingConnectionListener());
+
+ // Handle incoming packets
+ connection.addPacketListener(new PacketListener() {
+
+ &#64;Override
+ public void processPacket(Packet packet) {
+ logger.log(Level.INFO, &quot;Received: &quot; + packet.toXML());
+ Message incomingMessage = (Message) packet;
+ GcmPacketExtension gcmPacket =
+ (GcmPacketExtension) incomingMessage.
+ getExtension(GCM_NAMESPACE);
+ String json = gcmPacket.getJson();
+ try {
+ &#64;SuppressWarnings(&quot;unchecked&quot;)
+ Map&lt;String, Object&gt; jsonObject =
+ (Map&lt;String, Object&gt;) JSONValue.
+ parseWithException(json);
+
+ // present for &quot;ack&quot;/&quot;nack&quot;, null otherwise
+ Object messageType = jsonObject.get(&quot;message_type&quot;);
+
+ if (messageType == null) {
+ // Normal upstream data message
+ handleUpstreamMessage(jsonObject);
+
+ // Send ACK to CCS
+ String messageId = (String) jsonObject.get(&quot;message_id&quot;);
+ String from = (String) jsonObject.get(&quot;from&quot;);
+ String ack = createJsonAck(from, messageId);
+ send(ack);
+ } else if (&quot;ack&quot;.equals(messageType.toString())) {
+ // Process Ack
+ handleAckReceipt(jsonObject);
+ } else if (&quot;nack&quot;.equals(messageType.toString())) {
+ // Process Nack
+ handleNackReceipt(jsonObject);
+ } else if (&quot;control&quot;.equals(messageType.toString())) {
+ // Process control message
+ handleControlMessage(jsonObject);
+ } else {
+ logger.log(Level.WARNING,
+ &quot;Unrecognized message type (%s)&quot;,
+ messageType.toString());
+ }
+ } catch (ParseException e) {
+ logger.log(Level.SEVERE, &quot;Error parsing JSON &quot; + json, e);
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, &quot;Failed to process packet&quot;, e);
+ }
+ }
+ }, new PacketTypeFilter(Message.class));
+
+ // Log all outgoing packets
+ connection.addPacketInterceptor(new PacketInterceptor() {
+ &#64;Override
+ public void interceptPacket(Packet packet) {
+ logger.log(Level.INFO, &quot;Sent: {0}&quot;, packet.toXML());
+ }
+ }, new PacketTypeFilter(Message.class));
+
+ connection.login(senderId + &quot;&#64;gcm.googleapis.com&quot;, apiKey);
}
- if (delayWhileIdle != null &amp;&amp; delayWhileIdle) {
- message.put(&quot;delay_while_idle&quot;, true);
+
+ public static void main(String[] args) throws Exception {
+ final long senderId = 1234567890L; // your GCM sender id
+ final String password = &quot;Your API key&quot;;
+
+ SmackCcsClient ccsClient = new SmackCcsClient();
+
+ ccsClient.connect(senderId, password);
+
+ // Send a sample hello downstream message to a device.
+ String toRegId = &quot;RegistrationIdOfTheTargetDevice&quot;;
+ String messageId = ccsClient.nextMessageId();
+ Map&lt;String, String&gt; payload = new HashMap&lt;String, String&gt;();
+ payload.put(&quot;Hello&quot;, &quot;World&quot;);
+ payload.put(&quot;CCS&quot;, &quot;Dummy Message&quot;);
+ payload.put(&quot;EmbeddedMessageId&quot;, messageId);
+ String collapseKey = &quot;sample&quot;;
+ Long timeToLive = 10000L;
+ String message = createJsonMessage(toRegId, messageId, payload,
+ collapseKey, timeToLive, true);
+
+ ccsClient.sendDownstreamMessage(message);
}
- message.put(&quot;message_id&quot;, messageId);
- message.put(&quot;data&quot;, payload);
- return JSONValue.toJSONString(message);
- }
- /**
- * Creates a JSON encoded ACK message for an upstream message received from an application.
- *
- * &#64;param to RegistrationId of the device who sent the upstream message.
- * &#64;param messageId messageId of the upstream message to be acknowledged to CCS.
- * &#64;return JSON encoded ack.
- */
- public static String createJsonAck(String to, String messageId) {
- Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();
- message.put(&quot;message_type&quot;, &quot;ack&quot;);
- message.put(&quot;to&quot;, to);
- message.put(&quot;message_id&quot;, messageId);
- return JSONValue.toJSONString(message);
- }
+ /**
+ * XMPP Packet Extension for GCM Cloud Connection Server.
+ */
+ private static final class GcmPacketExtension extends DefaultPacketExtension {
- /**
- * Connects to GCM Cloud Connection Server using the supplied credentials.
- *
- * &#64;param username GCM_SENDER_ID&#64;gcm.googleapis.com
- * &#64;param password API Key
- * &#64;throws XMPPException
- */
- public void connect(String username, String password) throws XMPPException {
- config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
- config.setSecurityMode(SecurityMode.enabled);
- config.setReconnectionAllowed(true);
- config.setRosterLoadedAtLogin(false);
- config.setSendPresence(false);
- config.setSocketFactory(SSLSocketFactory.getDefault());
-
- // NOTE: Set to true to launch a window with information about packets sent and received
- config.setDebuggerEnabled(true);
-
- // -Dsmack.debugEnabled=true
- XMPPConnection.DEBUG_ENABLED = true;
-
- connection = new XMPPConnection(config);
- connection.connect();
-
- connection.addConnectionListener(new ConnectionListener() {
-
- &#64;Override
- public void reconnectionSuccessful() {
- logger.info(&quot;Reconnecting..&quot;);
- }
+ private final String json;
- &#64;Override
- public void reconnectionFailed(Exception e) {
- logger.log(Level.INFO, &quot;Reconnection failed.. &quot;, e);
- }
+ public GcmPacketExtension(String json) {
+ super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
+ this.json = json;
+ }
- &#64;Override
- public void reconnectingIn(int seconds) {
- logger.log(Level.INFO, &quot;Reconnecting in %d secs&quot;, seconds);
- }
+ public String getJson() {
+ return json;
+ }
- &#64;Override
- public void connectionClosedOnError(Exception e) {
- logger.log(Level.INFO, &quot;Connection closed on error.&quot;);
- }
+ &#64;Override
+ public String toXML() {
+ return String.format(&quot;&lt;%s xmlns=\&quot;%s\&quot;&gt;%s&lt;/%s&gt;&quot;,
+ GCM_ELEMENT_NAME, GCM_NAMESPACE,
+ StringUtils.escapeForXML(json), GCM_ELEMENT_NAME);
+ }
- &#64;Override
- public void connectionClosed() {
- logger.info(&quot;Connection closed.&quot;);
- }
- });
-
- // Handle incoming packets
- connection.addPacketListener(new PacketListener() {
-
- &#64;Override
- public void processPacket(Packet packet) {
- logger.log(Level.INFO, &quot;Received: &quot; + packet.toXML());
- Message incomingMessage = (Message) packet;
- GcmPacketExtension gcmPacket =
- (GcmPacketExtension) incomingMessage.getExtension(GCM_NAMESPACE);
- String json = gcmPacket.getJson();
- try {
- &#64;SuppressWarnings(&quot;unchecked&quot;)
- Map&lt;String, Object&gt; jsonObject =
- (Map&lt;String, Object&gt;) JSONValue.parseWithException(json);
-
- // present for &quot;ack&quot;/&quot;nack&quot;, null otherwise
- Object messageType = jsonObject.get(&quot;message_type&quot;);
-
- if (messageType == null) {
- // Normal upstream data message
- handleIncomingDataMessage(jsonObject);
-
- // Send ACK to CCS
- String messageId = jsonObject.get(&quot;message_id&quot;).toString();
- String from = jsonObject.get(&quot;from&quot;).toString();
- String ack = createJsonAck(from, messageId);
- send(ack);
- } else if (&quot;ack&quot;.equals(messageType.toString())) {
- // Process Ack
- handleAckReceipt(jsonObject);
- } else if (&quot;nack&quot;.equals(messageType.toString())) {
- // Process Nack
- handleNackReceipt(jsonObject);
- } else {
- logger.log(Level.WARNING, &quot;Unrecognized message type (%s)&quot;,
- messageType.toString());
- }
- } catch (ParseException e) {
- logger.log(Level.SEVERE, &quot;Error parsing JSON &quot; + json, e);
- } catch (Exception e) {
- logger.log(Level.SEVERE, &quot;Couldn't send echo.&quot;, e);
+ public Packet toPacket() {
+ Message message = new Message();
+ message.addExtension(this);
+ return message;
}
- }
- }, new PacketTypeFilter(Message.class));
+ }
+ private static final class LoggingConnectionListener
+ implements ConnectionListener {
- // Log all outgoing packets
- connection.addPacketInterceptor(new PacketInterceptor() {
- &#64;Override
- public void interceptPacket(Packet packet) {
- logger.log(Level.INFO, &quot;Sent: {0}&quot;, packet.toXML());
- }
- }, new PacketTypeFilter(Message.class));
+ &#64;Override
+ public void connected(XMPPConnection xmppConnection) {
+ logger.info(&quot;Connected.&quot;);
+ }
- connection.login(username, password);
- }
+ &#64;Override
+ public void authenticated(XMPPConnection xmppConnection) {
+ logger.info(&quot;Authenticated.&quot;);
+ }
- public static void main(String [] args) {
- final String userName = &quot;Your GCM Sender Id&quot; + &quot;&#64;gcm.googleapis.com&quot;;
- final String password = &quot;API Key&quot;;
+ &#64;Override
+ public void reconnectionSuccessful() {
+ logger.info(&quot;Reconnecting..&quot;);
+ }
- SmackCcsClient ccsClient = new SmackCcsClient();
+ &#64;Override
+ public void reconnectionFailed(Exception e) {
+ logger.log(Level.INFO, &quot;Reconnection failed.. &quot;, e);
+ }
- try {
- ccsClient.connect(userName, password);
- } catch (XMPPException e) {
- e.printStackTrace();
- }
+ &#64;Override
+ public void reconnectingIn(int seconds) {
+ logger.log(Level.INFO, &quot;Reconnecting in %d secs&quot;, seconds);
+ }
- // Send a sample hello downstream message to a device.
- String toRegId = &quot;RegistrationIdOfTheTargetDevice&quot;;
- String messageId = ccsClient.getRandomMessageId();
- Map&lt;String, String&gt; payload = new HashMap&lt;String, String&gt;();
- payload.put(&quot;Hello&quot;, &quot;World&quot;);
- payload.put(&quot;CCS&quot;, &quot;Dummy Message&quot;);
- payload.put(&quot;EmbeddedMessageId&quot;, messageId);
- String collapseKey = &quot;sample&quot;;
- Long timeToLive = 10000L;
- Boolean delayWhileIdle = true;
- ccsClient.send(createJsonMessage(toRegId, messageId, payload, collapseKey,
- timeToLive, delayWhileIdle));
- }
+ &#64;Override
+ public void connectionClosedOnError(Exception e) {
+ logger.info(&quot;Connection closed on error.&quot;);
+ }
+
+ &#64;Override
+ public void connectionClosed() {
+ logger.info(&quot;Connection closed.&quot;);
+ }
+ }
}</pre>
+
<h3 id="python">Python sample</h3>
<p>Here is an example of a CCS app server written in Python. This sample echo