2

Android デバイスに通知を送信する目的で、agsXMPP を使用して Google Cloud Messaging XMPP API に接続します。

接続は正常に確立されますが、SASL の開始時に PLAIN auth 要素を送信した後、サーバーは応答を停止し、さらに 20 秒後に接続を閉じます。

ドキュメント ページ ( http://developer.android.com/google/gcm/ccs.html )の認証例を Base64 でデコードすると、次のログイン値が表示されます。

126200347933@projects.gcm.android.com12620034793@projects-ga-.android.comAIzaSyB3rcZNkfnqKdFb9mhzCBiYpORDA2JWWtw

agsXMPP は (正しく私が思うに) 文字列をエンコードしているため、次のようになります。

[プロジェクト ID]\40gcm.googleapis.com[**API*キー*パスワード**]

私のバージョンでは、Google の例の@の代わりに\40に注意してください。これは違いを生む可能性がありますか?

成功または失敗のいずれかのメッセージが表示されることを期待していますが、デバッグが困難な応答はまったくありません。これが何らかの失敗の原因である可能性がありますか、それとも Google の XMPP の実装が正しい応答を提供しないだけなのでしょうか。

更新しました:

基本的に、はい、Google はエンコードされた @ 文字を処理できません。その XMPP 拡張機能をサポートしていないためです。

4

1 に答える 1

2

さらにテストした後、agsXMPP に新しい SaslFactory メカニズムを追加し、エンコーディングなしでユーザー名を使用するようにバインドしました ( Google がサポートしていない拡張子http://xmpp.org/extensions/xep-0106.htmlの一部)。次に、SaslStartEvent で、組み込みの単純なメカニズムの代わりにそのメカニズムを使用することを指定します。- これで、接続は正常に続行されます。

xmpp = new XmppClientConnection();
xmpp.UseSSL = true;
xmpp.UseStartTLS = false;
xmpp.Server = "gcm.googleapis.com";
xmpp.ConnectServer = "gcm.googleapis.com";
xmpp.Port = 5235;
/* Other connection settings /*

SaslFactory.AddMechanism("MyPLAINMechanism", typeof(MyPlainMechanismClass));

xmpp.OnSaslStart += (sender, args) =>
                                {
                                   args.Auto = false;
                                   args.Mechanism = "MyPLAINMechanism";
                                   args.ExtentedData = new GcmPlainSaslExtendedData
                                                          {
                                                             Username = "MY UNENCODED USERNAME"
                                                          };
                                };

次に、agsXMPP で Mechanism から継承する を定義しますMyPlainMechanismClass。ソース コードは、ユーザー名を入力する行を除いて元の PlainSaslMechanism と同じです。args のExtendedDataプロパティを使用して、エンコードされていないユーザー名を渡すことができます。

public class MyPlainMechanismClass: Mechanism
   {
      private XmppClientConnection m_XmppClient = null;

      public GcmPlainSaslMechanism()
      {
      }

      public override void Init(XmppClientConnection con)
      {
         m_XmppClient = con;

         // <auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">$Message</auth>
         m_XmppClient.Send(new agsXMPP.protocol.sasl.Auth(agsXMPP.protocol.sasl.MechanismType.PLAIN, Message()));
      }

      public override void Parse(Node e)
      {
         // not needed here in PLAIN mechanism
      }


      private string Message()
      {
         // NULL Username NULL Password
         StringBuilder sb = new StringBuilder();

         //sb.Append( (char) 0 );
         //sb.Append(this.m_XmppClient.MyJID.Bare);

         sb.Append((char)0);
         //sb.Append(this.Username);
         sb.Append(((GcmPlainSaslExtendedData) this.ExtentedData).Username);
         sb.Append((char)0);
         sb.Append(this.Password);

         byte[] msg = Encoding.UTF8.GetBytes(sb.ToString());
         return Convert.ToBase64String(msg, 0, msg.Length);
      }
   }

ExtendedDataこの場合のエンコードされていないユーザー名など、カスタム引数を渡すために使用するカスタムオブジェクト。

       public class GcmPlainSaslExtendedData : agsXMPP.Sasl.ExtendedData
       {
          public string Username { get; set; }
       }
于 2013-07-17T10:44:03.003 に答える