簡體   English   中英

使用Smack無法通過CCS從Google Cloud Messaging接收所有消息,僅每秒一次

[英]Not able receiving all messages, only every second, from Google Cloud Messaging with CCS using Smack

我正在嘗試使用Smack 4.1.2通過Cloud Connection Server(XMPP-Connection)建立與Google Cloud Messaging的連接。 我已經能夠建立連接並接收傳入的消息。 但是我的問題是StanzaListener不是由每條消息觸發的(而是每秒鍾才觸發的)。 Smack調試控制台顯示所有“原始接收的數據包”,因此從設備到雲的發送適用於每條消息。

謝謝您的幫助!

這是服務器應用程序中的代碼:

我的帶有Main的GCMServer類:

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);
        }

}

類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);
        }
    }

這是Smack 4.1.3中的錯誤( SMACK-695 ),此錯誤已修復/將在4.1.4中修復。 有關更多信息,請參見https://community.igniterealtime.org/thread/56610

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM