无法接收来自使用Smack的CCS的Google Cloud Messaging中的所有消息

时间:2015-07-23 09:54:06

标签: java google-cloud-messaging smack

我正在尝试使用Smack 4.1.2通过Cloud Connection Server(XMPP-Connection)建立与Google Cloud Messaging的连接。 我已经能够建立连接并接收传入的消息。但我的问题是StanzaListener不是由每条消息触发的(但只是每一秒消息)。 Smack调试控制台显示所有“原始接收数据包”,因此从设备到云的发送适用于每条消息。

感谢您的帮助!

这是来自Server App的代码:

My Class GCMServer with Main:

public class GCMServer {

public static final Logger logger = Logger.getLogger(GCMServer.class.getName());
public static SSLContext sslCtx;
public static XMPPTCPConnection connection;

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

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

private static final String YOUR_PROJECT_ID = "xxxxxxxxxxxx";
private static final String YOUR_API_KEY = "xxxx";



public static void main(String[] args) {

    ConnectionListener cl;

    try {        

        KeyStore windowsRootTruststore = KeyStore.getInstance("Windows-ROOT", "SunMSCAPI");
        windowsRootTruststore.load(null, null);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(windowsRootTruststore);
        sslCtx = SSLContext.getInstance("TLS");
        sslCtx.init(null, tmf.getTrustManagers(), null);

       } catch (KeyStoreException | NoSuchProviderException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException ex) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.SEVERE, null, ex);
        } 



        XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder()
                .setSecurityMode(SecurityMode.ifpossible)
                .setUsernameAndPassword(YOUR_PROJECT_ID, YOUR_API_KEY)
                .setHost(GCM_SERVER)
                .setServiceName(GCM_SERVER)
                .setPort(5235)
                .setDebuggerEnabled(true)
                .setCompressionEnabled(false)
                .setSocketFactory(sslCtx.getSocketFactory())
                .build();


    cl = new ConnectionListener() {

        @Override
        public void connected(XMPPConnection xmppc) {
             Logger.getLogger(GCMServer.class.getName()).log(Level.INFO, "connected");
             System.out.println("Conncetion is secure: "+connection.isSecureConnection());
        }

        @Override
        public void authenticated(XMPPConnection xmppc, boolean bln) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.INFO, "authenticated");
        }

        @Override
        public void connectionClosed() {
            Logger.getLogger(GCMServer.class.getName()).log(Level.INFO, "connection closed");
        }

        @Override
        public void connectionClosedOnError(Exception excptn) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.INFO, "conncetion closed on error");
        }

        @Override
        public void reconnectionSuccessful() {
            Logger.getLogger(GCMServer.class.getName()).log(Level.INFO, "reconnection successful");
        }

        @Override
        public void reconnectingIn(int i) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.INFO, "reconnecting..");
        }

        @Override
        public void reconnectionFailed(Exception excptn) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.INFO, "reconnection failed");
        }
    };

        connection = new XMPPTCPConnection(conf);

        //disable Roster; it seems it's not supported by GCM
        Roster roster = Roster.getInstanceFor(connection);  
        roster.setRosterLoadedAtLogin(false);  


        try {
            connection.connect();
            connection.addAsyncStanzaListener(new MyStanzaListener(),new StanzaTypeFilter(Message.class));
            connection.addConnectionListener(cl);
            connection.login(YOUR_PROJECT_ID + "@gcm.googleapis.com", YOUR_API_KEY);
        } catch (SmackException ex) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.SEVERE, null, ex);

        } catch (IOException ex) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (XMPPException ex) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.SEVERE, null, ex);
        }

}

Class MyStanzaListener:

private static class MyStanzaListener implements StanzaListener{

    @Override
    public void processPacket(Stanza stanza) {
                System.out.println("hei ho, new message: " + stanza.toXML());

                Message incomingMessage = (Message) stanza;
                GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage.getExtension(GCM_NAMESPACE);
                String json = gcmPacket.getJson();

                try {
                    Map<String, Object> jsonObject = (Map<String, Object>) JSONValue.parseWithException(json);

                    Object messageType = jsonObject.get("message_type");
                    String from = (String)jsonObject.get("from");
                    String messageId = (String)jsonObject.get("message_id");
                    String category = (String)jsonObject.get("category");


                    if(messageType == null) {
                        String ack = createJsonAck(from, messageId);
                        System.out.println(ack);
                        send(ack);

                        handleMessage(jsonObject);
                    }
                    else{
                        Logger.getLogger(GCMServer.class.getName()).log(Level.SEVERE, "ERROR IN HANDLING MESSAGE");
                    } 
                } catch (ParseException ex) {
                    Logger.getLogger(GCMServer.class.getName()).log(Level.SEVERE, null, ex);
                }
    }

}

方法HandleMessage,CreateJSONAck,发送:

public static void handleMessage(Map<String, Object> jsonObject) {
      DBConnect db = new DBConnect();

      Map<String, Object> messageData = (Map<String, Object>) jsonObject.get("data");
      String phoneNumber = (String)messageData.get("phoneNumber");
      String text = (String)messageData.get("message");


      db.inBoundMessage(phoneNumber, text);

  }

   public static String createJsonAck(String to, String messageId) {
        Map<String, Object> message = new LinkedHashMap<String, Object>();
        message.put("to", to);
        message.put("message_id", messageId);
        message.put("message_type", "ack");

        return JSONValue.toJSONString(message);
    }

   /**
     * Sends a downstream GCM message.
     */
    public static void send(String jsonRequest) {
        Stanza request = (Stanza)new GcmPacketExtension(jsonRequest).toPacket();
        try {
            connection.sendStanza(request);
        } catch (NotConnectedException ex) {
            Logger.getLogger(GCMServer.class.getName()).log(Level.SEVERE, "ERROR WHILE SENDING: ", ex);
        }
    }

1 个答案:

答案 0 :(得分:0)

这是Smack 4.1.3中的一个错误(SMACK-695),它已修复/将在4.1.4中修复。有关详细信息,请参阅https://community.igniterealtime.org/thread/56610