2013-07-17 70 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

上帝,终于找到了......很棒 –