2

このチュートリアルに従って、Google App Engine を使用して Google の Cloud Connection Server を実装しようとしています - XMPP ベースのアプリケーション サーバーの実装http://www.igniterealtime.org/projects/smack/ (smack.jar および smackx.jar)から最新の smack jar をコピーし、それらを WEB-INF/lib に置き、クラスパスに追加しました (eclipse を使用しています)。

私が投稿した最初のリンクのコード サンプルでは、​​XMPPConnection は「メイン」メソッドで開始されます。これは GAE にはあまり適していないため、ServletContextListener を作成して web.xml に追加しました。

public class GCMContextListener implements ServletContextListener {

   private static final String GCM_SENDER_ID = "*GCM_SENDER_ID*";
   private static final String API_KEY = "*API_KEY*";

   private SmackCcsClient ccsClient;

   public GCMContextListener() {
   }

   @Override
   public void contextInitialized(ServletContextEvent arg0) {
       final String userName = GCM_SENDER_ID + "@gcm.googleapis.com";
       final String password = API_KEY;

       ccsClient = new SmackCcsClient();

       try {
           ccsClient.connect(userName, password);
       } catch (XMPPException e) {
           e.printStackTrace();
       }
   }

   @Override
   public void contextDestroyed(ServletContextEvent arg0) {
       try {
           ccsClient.disconnect();
       } catch (XMPPException e) {
        e.printStackTrace();
       }
   }
}

web.xml

<web-app> 
   <listener>
       <listener-class>com.myserver.bootstrap.GCMContextListener</listener-class>
   </listener>
</web-app>

ここで、GAE サーバーを起動すると、次の例外が発生します。

java.lang.NoClassDefFoundError: javax.naming.directory.InitialDirContext は制限されたクラスです。詳細については、Google App Engine デベロッパー ガイドをご覧ください。

「詳細については、Google App Engine 開発者ガイド」を検索しましたが、これについては何も見つかりませんでした。手伝ってくれませんか ?

4

1 に答える 1

2

Google App Engine は、特定の JRE クラスへのアクセスを制限します。実際、どのクラスが使用可能かを示すホワイトリストを公開しています。Smack ライブラリがディレクトリ コンテキストへの参照を必要とする可能性があるように思えます (おそらく XMPP メッセージを作成するためですか?)。それが、サーブレットがこの例外を引き起こす理由です。javax.naming.directoryがホワイトリストにありません。

現在、GCM サーバーのセットアップにも取り組んでいます。例を読んで、そのメイン メソッドが何をしているかを確認する必要があるように思えます。私が見ているのは、GCM サーバーへの接続です。

try {
  ccsClient.connect(userName, password);
} catch (XMPPException e) {
  e.printStackTrace();
}

次に、ダウンストリーム メッセージがデバイスに送信されます。

// Send a sample hello downstream message to a device.
String toRegId = "RegistrationIdOfTheTargetDevice";
String messageId = ccsClient.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;
ccsClient.send(createJsonMessage(toRegId, messageId, payload, collapseKey,
    timeToLive, delayWhileIdle));

}

これらの操作は、アプリケーションのライフサイクルのある時点で完了するため、サーブレットは、ここに貼り付けたコードの最初の部分に表示される接続メソッドなど、例で実装するメソッドを提供することでそれらをサポートする必要があります。私が間違っていなければ、実装は235行目の例にあります。

ドキュメントにあるように、GAE を使用して実装しようとしているサードパーティ アプリケーション サーバーは、次のようにする必要があります。

お客様とコミュニケーションがとれる方。適切にフォーマットされたリクエストを GCM サーバーに送信できます。指数バックオフを使用して、要求を処理し、必要に応じて再送信できます。API キーとクライアント登録 ID を保存できます。API キーは、メッセージを送信する POST リクエストのヘッダーに含まれています。API キーとクライアント登録 ID を保存できます。送信する各メッセージを一意に識別するメッセージ ID を生成できます。

于 2013-09-25T20:44:05.290 に答える