【问题标题】:GCM Cloud Connection Server doesn't respond to SASL on XMPPGCM 云连接服务器不响应 XMPP 上的 SASL
【发布时间】:2013-07-15 20:50:59
【问题描述】:

使用 agsXMPP 连接到 Google Cloud Messaging XMPP API 以向 Android 设备发送通知。

连接建立正常,但在 SASL 启动时,发送 PLAIN auth 元素后,服务器停止响应,并在再过 20 秒后关闭连接。

Base64 解码文档页面 (http://developer.android.com/google/gcm/ccs.html) 中的身份验证示例显示以下登录值:

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

agsXMPP 在哪里(我认为是正确的)对字符串进行编码,给出如下内容:

[项目ID]\40gcm.googleapis.com[**API*KEY*PASSWORD**]

注意我的版本中的 \40 而不是 Google 示例中的 @ - 这会有所不同吗?

我期待成功或失败消息,根本没有响应很难调试。这可能是导致某些失败的原因,还是 Google 的 XMPP 实施没有提供正确的响应。

更新:

我在下面回答,基本上,是的,Google 无法处理编码的 @ 字符,因为它不支持 XMPP 扩展。

【问题讨论】:

    标签: xmpp google-cloud-messaging agsxmpp


    【解决方案1】:

    经过更多测试,我在 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"
                                                              };
                                    };
    

    然后我们定义MyPlainMechanismClass,它继承自agsXMPP中的机制,源代码与原始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; }
           }
    

    【讨论】:

    • 不编辑源代码就没有办法了吗?谢谢。
    • @BarbarosAlp 是的,我在答案中添加了一个示例 - 基本上是通过添加一个新的 SaslMechanism,保持原始 agsXMPP 代码不变。
    • 天哪,终于找到了……太棒了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2013-06-26
    • 2013-08-21
    • 1970-01-01
    相关资源
    最近更新 更多