GCM 无效 JSON 缺少有效负载
GCM Invalid JSON Missing Payload
我正在尝试使用 Python sleekXMPP 通过 Google 云消息传递发送消息。我尝试按照 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)
这是我收到的错误:
<message to="REDACTED@gcm.googleapis.com/475DBA7C" type="error" xml:lang="en"><body><gcm xmlns:"google:mobile:data">{"to": "REDACTED", "data": {"hello": "world"}, "message_id": "ZGDZ9QTD"}</gcm></body><error code="400" type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /><text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">InvalidJson : MissingPayload</text></error></message>
您收到的 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.
事实证明,SleekXMPP 自动将我的消息包含在 <body />
标记中,这不是 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)
我正在尝试使用 Python sleekXMPP 通过 Google 云消息传递发送消息。我尝试按照 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)
这是我收到的错误:
<message to="REDACTED@gcm.googleapis.com/475DBA7C" type="error" xml:lang="en"><body><gcm xmlns:"google:mobile:data">{"to": "REDACTED", "data": {"hello": "world"}, "message_id": "ZGDZ9QTD"}</gcm></body><error code="400" type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /><text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">InvalidJson : MissingPayload</text></error></message>
您收到的 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.
事实证明,SleekXMPP 自动将我的消息包含在 <body />
标记中,这不是 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)