2016-04-04 10 views
2

チャットモジュール用にgcm ccsを実装しました。メッセージを送受信できます。以下は主な接続モジュール、Smack 4.1.0 GCM CCSがしばらくしてから応答を停止する

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

は、私はしばらく後にクライアントデバイスによって送信されたGCMから任意のメッセージを、受信していないに実行しています問題です。心拍は正常に見えますが、その場合でもGCMからポンを得るのです。 SSLと何か関係はありますか?

は、私はあなたがマニュアルに非常に表示されていないGCMのCSSを使用した一般的なケースに直面していると信じて、次のようにケースを排出

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

答えて

1

1つのチャネルが排水されている場合、チャネルのキューが実装されています。

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

メッセージ

 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は、他の閉鎖の世話をします。これで問題は解決しました。

0

を接続を扱っています。あなたは、ドキュメントで見てControl Messages場合 あなたが読んであげる:

を定期的に、CCSは、負荷分散を実行するための接続を閉鎖する必要があります。接続を閉じる前に、CCSはCONNECTION_DRAININGメッセージを送信して、接続が切断されていてすぐに終了することを示します。 「排水」とは、接続に入ってくるメッセージの流れを止めることですが、すでにパイプラインに入っているものは何でも続けることができます。 CONNECTION_DRAININGメッセージを受信すると、すぐに別のCCS接続にメッセージを送信し、必要に応じて新しい接続を開始する必要があります。ただし、元の接続を開いたままにしておき、接続を介して来る可能性のあるメッセージの受信を続行する必要があります。

+0

接続排水ロジックも実装されています。上記の記事で正しいかどうか確認してください。 – Itachi

+0

CONNECTION_DRAININGメッセージを受け取ったら、すぐに別のCCS接続にメッセージを送信し、必要に応じて新しい接続を開始する必要があります。ただし、元の接続を開いたままにしておく必要があります。 ...接続を閉じたり、新しい接続を開始したり、古い接続がGoogleによって閉じられるのを待ちます。 –

関連する問題