2013-07-17 126 views
2

使用agsXMPP連接到Google Cloud Messaging XMPP API以向Android設備發送通知。GCM雲連接服務器不響應XMPP上的SASL

連接建立成功,但在SASL啓動時,發送PLAIN身份驗證元素後,服務器停止響應,並在20秒後關閉連接。

Base64的解碼從所述文檔頁面的AUTH的例子(http://developer.android.com/google/gcm/ccs.html)示出的登錄值:

126200347933 @ projects.gcm.android.com12620034793 @項目-GA-.android.comAIzaSyB3rcZNkfnqKdFb9mhzCBiYpORDA2JWWtw

凡爲agsXMPP是(正確的,我認爲)編碼字符串,給類似:

[專案編號] \ 40gcm.googl eapis.com [** * API KEY *密碼**]

注意\ 40在我的版本,而不是在谷歌例如@ - 這可以有所作爲?

我期待成功或失敗的消息,根本沒有答覆是很難調試。這可能是造成某種失敗的原因之一,或者Google的XMPP實施方案沒有提供正確的答案。

更新:

下面我回答說,從本質上講,是的,谷歌無法處理的編碼@字符,因爲它不支持XMPP擴展。

回答

2

經過一些更多的測試後,我在agsXMPP中添加了一個新的SaslFactory機制,並將其綁定爲使用沒有編碼的用戶名(擴展http://xmpp.org/extensions/xep-0106.html的一部分,Google不支持),然後在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機制繼承MyPlainMechanismClass,源代碼是相同的,不同之處的線原始PlainSaslMechanism其中用戶名是輸入 - 可以使用ExtendedData屬性中的未編碼的用戶名傳遞在args上。

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

沒有編輯源代碼沒有辦法嗎?謝謝。 –

+0

@BarbarosAlp是的,我在答案中增加了一個例子 - 基本上通過添加一個新的SaslMechanism,使原始agsXMPP代碼保持不變。 – simbolo

+0

上帝,終於找到了......很棒 –