【发布时间】:2014-07-06 09:34:44
【问题描述】:
我正在使用 Apache、WSGI (mod_wsgi) 和 Python 来实现 GCM HTTP 服务器,如 Android 开发者网站中所述:
developer.android.com/google/gcm/server.html
起初我在服务器端实现的用于处理向 GCM 发送消息的代码如下:
def send_to_gcm(data):
url = 'https://android.googleapis.com/gcm/send'
no = 1
while True:
try:
request = Request(url=url, data=json.dumps(data))
request.add_header('Authorization','key=AIzXXX')
request.add_header('Content-Type', 'application/json')
res = urlopen(request)
if res.getcode() == 200: return
except Exception: pass
no += 1
#Discard the message
if no == 16: return
#Exponential backoff
tts = randint(2**(no-1), (2**no) -1)
sleep(tts)
data = dict(registration_id=[regid], data=dict(mymessage=themessage))
thread = Thread(target=send_to_gcm, args=(data,))
thread.start()
过了一段时间(大约一天),GCM 停止接受服务器发送的消息。于是我开始在 GCM 的文档中到处挖掘,我发现了我之前错过的规范的一个重要部分:
developer.android.com/google/gcm/http.html#response
“如果 Retry-After 标头包含在 GCM 服务器的响应中,则尊重它。...导致问题的发件人有被列入黑名单的风险。...当 HTTP 状态代码介于 501 和 599 之间时,或者当结果数组中 JSON 对象的错误字段不可用。”
所以我修补了我的服务器代码如下:
def send_to_gcm(data, environ):
url = 'https://android.googleapis.com/gcm/send'
no = 1
while True:
try:
request = Request(url=url, data=json.dumps(data))
request.add_header('Authorization','key=AIzXXX')
request.add_header('Content-Type', 'application/json')
res = urlopen(request)
if res.getcode() == 200: return
except HTTPError as error:
if error.headers.has_key('Retry-After'):
try: tts = int(response_headers['Retry-After'])
except ValueError:
until = datetime.strptime(response_headers, '%a, %d %b %Y %H:%M:%S GMT')
diff = until - datetime.now()
tts = int(diff.total_seconds()) +1
sleep(tts)
no += 1
#Discard the message
if no == 16: return
#Exponential backoff
tts = randint(2**(no-1), (2**no) -1)
sleep(tts)
但实际上,我的服务器很可能已被列入黑名单,并且对于发送的任何请求,我都会收到 401 状态代码和“未经授权”错误消息。这是我的问题:
我最新的服务器实现有什么问题吗?
我的服务器的静态 IP 地址会被取消禁止吗?如果可以,什么时候取消?
【问题讨论】:
标签: android python google-cloud-messaging