【问题标题】:GCM Invalid JSON Missing PayloadGCM 无效的 JSON 缺少有效负载
【发布时间】:2015-05-22 09:49:07
【问题描述】:

我正在尝试使用 Python slimXMPP 通过 Google Cloud Messaging 发送消息。我尝试按照GCM docs 中的示例进行操作。但是,当我调用 send_command 时,我收到“InvalidJson:MissingPayload”错误响应 (400)。我在这里想念什么?以下是我使用的代码。

def random_id():
    return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(8))

class GcmNotifier(sleekxmpp.ClientXMPP):

    def __init__(self, jid, password):
        super(GcmNotifier, self).__init__(jid, password)
        self.add_event_handler('message', self.on_message_received)

    def send_gcm_message(self, message):
        body = '<gcm xmlns:"google:mobile:data">%s</gcm>' % json.dumps(message)
        print(body)
        self.send_message(mto='', mbody=body)

    def on_message_received(self, message):
        print(message)

    def send_command(self, recipient):
        self.send_gcm_message({ 
            'to': recipient,
            'message_id': random_id(),
            'data':
            {
                'hello': 'world'
            }
        })

xmpp = GcmNotifier(GCM_SENDER_ID + '@gcm.googleapis.com', GCM_API_KEY)
if xmpp.connect((GCM_SERVER, GCM_PORT), use_ssl=True):
    xmpp.process(block=False)

这是我收到的错误:

&lt;message to="REDACTED@gcm.googleapis.com/475DBA7C" type="error" xml:lang="en"&gt;&lt;body&gt;&amp;lt;gcm xmlns:&amp;quot;google:mobile:data&amp;quot;&amp;gt;{&amp;quot;to&amp;quot;: &amp;quot;REDACTED&amp;quot;, &amp;quot;data&amp;quot;: {&amp;quot;hello&amp;quot;: &amp;quot;world&amp;quot;}, &amp;quot;message_id&amp;quot;: &amp;quot;ZGDZ9QTD&amp;quot;}&amp;lt;/gcm&amp;gt;&lt;/body&gt;&lt;error code="400" type="modify"&gt;&lt;bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /&gt;&lt;text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"&gt;InvalidJson : MissingPayload&lt;/text&gt;&lt;/error&gt;&lt;/message&gt;

【问题讨论】:

    标签: python xmpp google-cloud-messaging


    【解决方案1】:

    事实证明,SleekXMPP 自动将我的消息包含在 &lt;body /&gt; 标记中,这不是 GCM 服务器预期的消息格式。我最终通过定义自己的节来解决问题,如下所示:

     class Gcm(ElementBase):
        namespace = 'google:mobile:data'
        name = 'gcm'
        plugin_attrib = 'gcm'
        interfaces = set('gcm')
        sub_interfaces = interfaces
    
    class GcmMessage(ElementBase):
        namespace = ''
        name = 'message'
        interfaces = set('gcm')
        sub_interfaces = interfaces
        subitem = (Gcm,)
    
    register_stanza_plugin(GcmMessage, Gcm)
    

    然后像这样发送消息:

    def send_gcm_message(self, message):
        msg = GcmMessage()
        msg['gcm'].xml.text = xml.sax.saxutils.escape(json.dumps(message, ensure_ascii=False))
        self.send(msg)
    

    【讨论】:

      【解决方案2】:

      您收到的Missing Payload 错误是因为您没有将任何参数作为键和值格式传递给被识别为有效负载。

      首先,您必须定义一个函数,您将在其中传递有效负载,然后在 GCm 服务器响应后将其转换回纯文本。

      这是一个例子:

      def plaintext_request(self, registration_id, data=None, collapse_key=None,
                                delay_while_idle=False, time_to_live=None, retries=5, dry_run=False):
      if not registration_id:
              raise GCMMissingRegistrationException("Missing registration_id")
      
          payload = self.construct_payload(
              registration_id, data, collapse_key,
              delay_while_idle, time_to_live, False, dry_run
          )
      

      如果您的代码中需要在一段时间后 ping 服务器,您可以使用指数回退机制。

      详细代码实现请阅读以下document

      【讨论】:

      • 这算不算有效载荷:{ 'to': recipient, 'message_id': random_id(), 'data': { 'hello': 'world' } } 还是我的格式有问题?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-06
      • 1970-01-01
      • 1970-01-01
      • 2018-08-22
      • 1970-01-01
      • 2020-12-01
      相关资源
      最近更新 更多