如何在Python中实现GCM HTTP服务器,同时避免我的服务器IP被谷歌列入黑名单?

3 投票
1 回答
4036 浏览
提问于 2025-04-18 06:54

我正在使用Apache、WSGI(mod_wsgi)和Python,按照Android开发者网站上的说明,来实现一个GCM HTTP服务器:

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

“如果GCM服务器的响应中包含Retry-After头部,请遵循它。……造成问题的发送者可能会被列入黑名单。……当HTTP状态码在501到599之间,或者结果数组中的JSON对象的错误字段为Unavailable时,会发生这种情况。”

于是我修改了我的服务器代码,如下所示:

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地址会被解禁吗?如果会,什么时候?

1 个回答

2

我在找同样的主题。这个模块可能对你有帮助:https://github.com/geeknam/python-gcm

撰写回答