既不获取下游消息也不使用CCS获取echo消息

时间:2014-07-22 12:58:25

标签: java android xmpp google-cloud-messaging

我从android的以下链接下载了代码,其中包含发送echo,广播以及用户通知消息的选项。

Link for Android

然后我尝试在服务器端使用许多代码而没有任何成功,所以我研究并编写了我在Tomcat服务器上托管的服务器端的以下代码,并且有一个servlet可以激活客户端。

public class CcsServlet extends HttpServlet
{
private static Logger logger = Logger.getLogger(CcsServlet.class.getName());
private static final String USERNAME = "855350893195" + "@gcm.googleapis.com";
private static final String PASSWORD = "AIzaSyA9DQTcggUtABVC9lnV_Xb5VEQ8iKBEaP4";//AIzaSyAxDKiYUkU8EvtOgaCeZMypVJpzcYgyjhw-server

public void init(ServletConfig config) throws ServletException
{
   SmackCcsClient ccsManager = SmackCcsClient.getInstance();
    try
    {
        ccsManager.connect(USERNAME,PASSWORD);

    }
    catch (Exception e)
    {
        logger.warning("Cannot connect to CCS server.");
        e.printStackTrace();
    }
  }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{



 }
}

SmackCcsClient的代码

public class SmackCcsClient {

private static Logger log = LoggerFactory.getLogger(SmackCcsClient.class);
private static SmackCcsClient sInstance = null;

XMPPConnection connection;
ConnectionConfiguration config;



public SmackCcsClient() {
    // Add GcmPacketExtension
    ProviderManager.getInstance().addExtensionProvider(
            GCMConstants.GCM_ELEMENT_NAME, 
            GCMConstants.GCM_NAMESPACE, 
            new PacketExtensionProvider() {
                @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.
 * 
 */
public String getRandomMessageId() {
    return UUID.randomUUID().toString();
}

/**
 * Sends a downstream GCM message.
 */
public void send(String jsonRequest) {
    Packet request = new GcmPacketExtension(jsonRequest).toPacket();
    connection.sendPacket(request);
}
 public static SmackCcsClient getInstance()
    {
        if (sInstance == null)
            sInstance = new SmackCcsClient();
        return sInstance;
    }
/**
 * Handles an upstream data message from a device application.
 * 
 * <p>
 * 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<String, Object> jsonObject) {
    String from = jsonObject.get("from").toString();

    // PackageName of the application that sent this message.
    String category = jsonObject.get("category").toString();

    // Use the packageName as the collapseKey in the echo packet
    String collapseKey = "echo:CollapseKey";
    @SuppressWarnings("unchecked")
    Map<String, String> payload = (Map<String, String>) jsonObject.get("data");
    payload.put("ECHO", "Application: " + category);

    // Send an ECHO response back
    String echo = createJsonMessage(from, getRandomMessageId(), payload, collapseKey, null, false);
    send(echo);
}

/**
 * Handles an ACK.
 * 
 * <p>
 * By default, it only logs a INFO message, but subclasses could override it
 * to properly handle ACKS.
 */
public void handleAckReceipt(Map<String, Object> jsonObject) {
    String messageId = jsonObject.get("message_id").toString();
    String from = jsonObject.get("from").toString();
    log.debug("handleAckReceipt from: {}, messageId: {}", from, messageId);
}

/**
 * Handles a NACK.
 * 
 * <p>
 * By default, it only logs a INFO message, but subclasses could override it
 * to properly handle NACKS.
 */
public void handleNackReceipt(Map<String, Object> jsonObject) {
    String messageId = jsonObject.get("message_id").toString();
    String from = jsonObject.get("from").toString();
    log.debug("handleNackReceipt() from: {}, messageId: {}",from, messageId);
}

/**
 * Creates a JSON encoded GCM message.
 * 
 * @param to
 *            RegistrationId of the target device (Required).
 * @param messageId
 *            Unique messageId for which CCS will send an "ack/nack"
 *            (Required).
 * @param payload
 *            Message content intended for the application. (Optional).
 * @param collapseKey
 *            GCM collapse_key parameter (Optional).
 * @param timeToLive
 *            GCM time_to_live parameter (Optional).
 * @param delayWhileIdle
 *            GCM delay_while_idle parameter (Optional).
 * @return JSON encoded GCM message.
 */
public static String createJsonMessage(String to, String messageId,
        Map<String, String> payload, String collapseKey, Long timeToLive,
        Boolean delayWhileIdle) {
    Map<String, Object> message = new HashMap<String, Object>();
    message.put("to", to);
    if (collapseKey != null) {
        message.put("collapse_key", collapseKey);
    }
    if (timeToLive != null) {
        message.put("time_to_live", timeToLive);
    }
    if (delayWhileIdle != null && delayWhileIdle) {
        message.put("delay_while_idle", true);
    }
    message.put("message_id", messageId);
    message.put("data", payload);
    return JSONValue.toJSONString(message);
}

/**
 * Creates a JSON encoded ACK message for an upstream message received from
 * an application.
 * 
 * @param to
 *            RegistrationId of the device who sent the upstream message.
 * @param messageId
 *            messageId of the upstream message to be acknowledged to CCS.
 * @return JSON encoded ack.
 */
public static String createJsonAck(String to, String messageId) {
    Map<String, Object> message = new HashMap<String, Object>();
    message.put("message_type", "ack");
    message.put("to", to);
    message.put("message_id", messageId);
    return JSONValue.toJSONString(message);
}

/**
 * Connects to GCM Cloud Connection Server using the supplied credentials.
 * 
 * @param username
 *            GCM_SENDER_ID@gcm.googleapis.com
 * @param password
 *            API Key
 * @throws XMPPException
 */
public void connect(String username, String password) throws XMPPException {
    config = new ConnectionConfiguration(GCMConstants.GCM_SERVER, GCMConstants.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();
    //**code used to send downstream message**
    String toRegId = "APA91bECAx_1rzceJbPwas5FyRGPmpYFvWSJ0hfUlT30DSsrsXmBC5W-VmYTI0p8Gg9VZh598iNBcVki-H1dloBnaETfvZlJUZskTxHKE7DoDAgapH_X_DJE3toyZwXS4SHIdt5lYLty6OU_tmAOTZN4n88jlmSaR2_MrNmY1HuAMlddMfqAr10";
    String messageId = sInstance.getRandomMessageId();
    Map<String, String> payload = new HashMap<String, String>();
    payload.put("Hello", "World");
    payload.put("CCS", "Dummy Message");
    payload.put("EmbeddedMessageId", messageId);
    String collapseKey = "sample";
    Long timeToLive = 10000L;
    Boolean delayWhileIdle = true;
    sInstance.send(createJsonMessage(toRegId, messageId, payload,
            collapseKey, timeToLive, delayWhileIdle));
    connection.addConnectionListener(new ConnectionListener() {

        @Override
        public void reconnectionSuccessful() {
            log.info("Reconnecting..");
        }

        @Override
        public void reconnectionFailed(Exception e) {
            log.info( "Reconnection failed.. ", e);
        }

        @Override
        public void reconnectingIn(int seconds) {
            log.info( "Reconnecting in %d secs", seconds);
        }

        @Override
        public void connectionClosedOnError(Exception e) {
            log.info( "Connection closed on error.");
        }

        @Override
        public void connectionClosed() {
            log.info("Connection closed.");
        }
    });

    // Handle incoming packets
    connection.addPacketListener(new PacketListener() {

        @Override
        public void processPacket(Packet packet) {
            log.info( "Received: " + packet.toXML());
            Message incomingMessage = (Message) packet;
            GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage.getExtension(GCMConstants.GCM_NAMESPACE);
            String json = gcmPacket.getJson();
            try {
                @SuppressWarnings("unchecked")
                Map<String, Object> jsonObject = (Map<String, Object>) JSONValue
                        .parseWithException(json);

                // present for "ack"/"nack", null otherwise
                Object messageType = jsonObject.get("message_type");

                if (messageType == null) {
                    // Normal upstream data message
                    handleIncomingDataMessage(jsonObject);

                    // Send ACK to CCS
                    String messageId = jsonObject.get("message_id")
                            .toString();
                    String from = jsonObject.get("from").toString();
                    String ack = createJsonAck(from, messageId);
                    send(ack);
                } else if ("ack".equals(messageType.toString())) {
                    // Process Ack
                    handleAckReceipt(jsonObject);
                } else if ("nack".equals(messageType.toString())) {
                    // Process Nack
                    handleNackReceipt(jsonObject);
                } else {
                    // logger.log(Level.WARNING,
                    // "Unrecognized message type (%s)",
                    messageType.toString();
                }
            } catch (Exception e) {
                // logger.log(Level.SEVERE, "Couldn't send echo.", e);
            }
        }
    }, new PacketTypeFilter(Message.class));

    // Log all outgoing packets
    connection.addPacketWriterInterceptor(new PacketInterceptor() {
        @Override
        public void interceptPacket(Packet packet) {
            log.info( "Sent: {0}", packet.toXML());
        }
    }, new PacketTypeFilter(Message.class));

    connection.login(username, password);
}


}

GcmPacketExtension代码

class GcmPacketExtension extends DefaultPacketExtension {
String json;

public GcmPacketExtension(String json) {
    super(GCMConstants.GCM_ELEMENT_NAME, GCMConstants.GCM_NAMESPACE);
    this.json = json;
}

public String getJson() {
    return json;
}

@Override
public String toXML() {
    return String.format("<%s xmlns=\"%s\">%s</%s>", GCMConstants.GCM_ELEMENT_NAME,
            GCMConstants.GCM_NAMESPACE, json, GCMConstants.GCM_ELEMENT_NAME);
}

@SuppressWarnings("unused")
public Packet toPacket() {
    return new Message() {
        // Must override toXML() because it includes a <body>
        @Override
        public String toXML() {

            StringBuilder buf = new StringBuilder();
            buf.append("<message");
            if (getXmlns() != null) {
                buf.append(" xmlns=\"").append(getXmlns()).append("\"");
            }
            if (getDefaultLanguage() != null) {
                buf.append(" xml:lang=\"").append(getDefaultLanguage())
                        .append("\"");
            }
            if (getPacketID() != null) {
                buf.append(" id=\"").append(getPacketID()).append("\"");
            }
            if (getTo() != null) {
                buf.append(" to=\"")
                        .append(StringUtils.escapeForXML(getTo()))
                        .append("\"");
            }
            if (getFrom() != null) {
                buf.append(" from=\"")
                        .append(StringUtils.escapeForXML(getFrom()))
                        .append("\"");
            }
            buf.append(">");
            buf.append(GcmPacketExtension.this.toXML());
            buf.append("</message>");
            return buf.toString();
        }
    };
}
}

GcmConstants的代码

public class GCMConstants {

public static final String GCM_SERVER = "gcm.googleapis.com";
public static final int GCM_PORT = 5235;

public static final String GCM_ELEMENT_NAME = "gcm";
public static final String GCM_NAMESPACE = "google:mobile:data";
}

现在,当我尝试使用connect中的代码发送下游消息时,该代码未到达我所提供的设备ID或设备的Echo消息也未被服务器回显。

是否需要为CCS注册事项,因为我已经注册,但没有得到任何回复。

第二个问题是为什么沟通都不起作用。

现在我已经解决了所有问题,现在我的servlet正在运行并建立连接但它返回“没有来自服务器的响应”,我在连接时遇到异常。

0 个答案:

没有答案