2016-04-04 4 views
2

Habe gcm ccs für Chat-Modul implementiert und ich kann Nachrichten senden und empfangen. Im Folgenden finden Sie die Hauptanschlussmodul,Smack 4.1.0 GCM CCS reagiert nicht mehr nach einer Weile

 config = XMPPTCPConnectionConfiguration.builder() 
       .setServiceName("gcm-pesu.googleapis.com") 
       .setPort(GCM_PORT) 
       .setHost(GCM_SERVER) 
       .setCompressionEnabled(false) 
       .setConnectTimeout(30000) 
       .setSecurityMode(SecurityMode.ifpossible) 
       .setSendPresence(false) 
       .setSocketFactory(SSLSocketFactory.getDefault()) 
       .build(); 

     connection = new XMPPTCPConnection(config); 
     connection.connect(); 

     Roster roster = Roster.getInstanceFor(connection); 
     roster.setRosterLoadedAtLogin(false); 

     connection.addConnectionListener(new LoggingConnectionListener()); 

     // Handle incoming packets 
     connection.addAsyncStanzaListener(new MyStanzaListener(), new MyStanzaFilter()); 

     // Log all outgoing packets 
     connection.addPacketInterceptor(new MyStanzaInterceptor(), new MyStanzaFilter()); 

     connection.login(mProjectId + "@gcm.googleapis.com", mApiKey); 
     logger.info("logged in: " + mProjectId); 

     PingManager pm = PingManager.getInstanceFor(connection); 
     pm.setPingInterval(300); 
     pm.pingMyServer(); 
     pm.registerPingFailedListener(new PingFailedListener() { 
      @Override 
      public void pingFailed() { 
       connection.disconnect(); 
       logger.error("GCM CCS, Ping failed !!"); 
      } 
     }); 

Das Problem, das ich in leite wird keine Nachricht von GCM empfängt, nach einer gewissen Zeit von Clientgerät gesendet. Allerdings sieht der Herzschlag normal aus und ich bekomme auch in diesem Fall Pong von GCM. Hat das etwas mit SSL zu tun?

Haben Verbindung Trockenlegung Fall wie folgt behandelt,

 String controlType = (String) jsonObject.get("control_type"); 
     volatile boolean connectionDraining = false; 
     if ("CONNECTION_DRAINING".equals(controlType)) { 
      connectionDraining = true; 
      try { 
       connection.disconnect(); 
       connect(); 
       connectionDraining = false; 
      } catch (Exception e) { 
       logger.error("Error establishing new connection after draining ", e); 
      } 
     } 

Antwort

1

Implementierte Warteschlange von Kanälen, wenn einer davon drainiert.

  private Deque<Channel> channels; 
      protected void handleControlMessage(Map<String, Object> jsonObject) { 
      logger.info("Control message : " + jsonObject); 
      String controlType = (String) jsonObject.get("control_type"); 
      if ("CONNECTION_DRAINING".equals(controlType)) { 
       connectionDraining = true; 
      } 
     } 

neuen Kanal erstellen, während Nachricht

 public void sendDownstreamMessage(String jsonRequest) { 
     Channel channel = channels.peekFirst(); 
     try { 
      if (channel.connectionDraining) { 
       synchronized (channels) { 
        channel = channels.peekFirst(); 
        if (channel.connectionDraining) { 
         channels.addFirst(connect()); 
         channel = channels.peekFirst(); 
        } 
       } 
      } 
      channel.send(jsonRequest); 
     } catch (Exception e) { 
      logger.error("Message not sent. Error in connecting :", e); 
     } 
    } 

GCM senden, wird die andere der Schließung kümmern. Dies hat das Problem behoben.

0

Ich glaube, ich ist ein gemeinsamen Fall gegenüber GCM mit CSS, die nicht sehr sichtbar in der Dokumentation. Wenn Sie in der doc aussehen, Control Messages Sie lesen:

Periodisch CCS eine Verbindung zu schließen, muss Lastenausgleich durchzuführen. Bevor die Verbindung geschlossen wird, sendet CCS eine CONNECTION_DRAINING-Nachricht, um anzuzeigen, dass die Verbindung abgebaut wird, und wird in Kürze geschlossen. "Leeren" bezieht sich auf das Unterbrechen des Nachrichtenflusses, der in eine Verbindung gelangt, erlaubt aber, was bereits in der Pipeline ist, fortzufahren. Wenn Sie eine CONNECTION_DRAINING-Nachricht erhalten, sollten Sie sofort mit dem Senden von Nachrichten an eine andere CCS-Verbindung beginnen und ggf. eine neue Verbindung öffnen. Sie sollten jedoch die ursprüngliche Verbindung offen lassen und weiterhin Nachrichten empfangen, die über die Verbindung kommen (und sie bestätigen). -CCS-Handles initiieren eine Verbindung schließen, wenn sie fertig ist.

+0

Haben auch die Verbindung Drainage-Logik implementiert.Haben hinzugefügt, dass in dem oben genannten Beitrag überprüfen Sie bitte, ob das korrekt ist. – Itachi

+0

Wenn Sie eine CONNECTION_DRAINING-Nachricht erhalten, sollten Sie sofort damit beginnen, Nachrichten an eine andere CCS-Verbindung zu senden und ggf. eine neue Verbindung zu öffnen. Sie sollten jedoch die ursprüngliche Verbindung offen lassen. ... Schließen Sie die Verbindung nicht, starten Sie eine neue und warten Sie, bis die alte Verbindung von Google geschlossen wird. –