2

我很想向我的手机发送消息。通过浏览器我调用了执行此操作的方法,我已经记录了registrationId、authToken等。这是正确的,因为我在本地服务器中进行了测试,并且消息已使用这些键发送到我的手机。

但是在 App Engine 上,urlfetch.fetchfor ' https://android.clients.google.com/c2dm/send'的结果出现 401 错误。

或者,如果这是身份验证问题。我怀疑是上面的问题,因为调用了该方法,并且错误发生在我的 App Engine 服务器中方法的末尾。

以下是我向 C2DM 服务器发出请求的方式:

params = {
          'registration_id':registrationId,
          'collapse_key':0,
          'data.payload':encoded_msg
         }

        paramsByte = urllib.urlencode(params)
        logging.info(registrationId)

        url = 'https://android.clients.google.com/c2dm/send'
        logging.info(token)
        result = urlfetch.fetch(url=url,
                                payload=paramsByte,
                                method=urlfetch.POST,
                                headers={'Content-Type':'application/x-www-form-urlencoded',
                                         'Authorization':'GoogleLogin auth='+token}
                                )

任何帮助,将不胜感激。谢谢。


更新

现在客户端按照建议在托管服务器中运行,并且在联系“https://android.clients.google.com/c2dm/send”时发生 401 错误。

但是,当在具有相同令牌和 regId 的终端上使用以下命令时,它可以工作。

curl --header "授权:GoogleLogin auth=your_authenticationid" "https://android.apis.google.com/c2dm/send" -d registration_id=your_registration -d "data.payload=payload" -d collapse_key=0

客户端代码调用服务器中的方法:

$.getJSON('http://myapp.appspot.com/method?userId='+userId+'&message='+theMessage+'&callback=?', 
    function(data)
    {
        console.log(data);
    });

服务器的完整方法代码:

class PushHandler(webapp.RequestHandler):

    '''This method sends the message to C2DM server to send the message to the phone'''
    def get(self):
        logging.info('aqui dentro')
        userId = self.request.get('userId')
        message = self.request.get('message')
        callback = self.request.get('callback')
        token = getToken(self) #this is a method I've implemented to get the token from C2DM servers by passing the SenderId and Password
        registrationId = ''
        contactNumber = ''

        # Get the registrationId to send to the C2DM server to know which 
        # device it may send the message
        regQuery = C2DMUser.all()
        regQuery.filter('userId =', int(userId))
        for k in regQuery:
            registrationId = k.registrationId

        # Builds the json to be sent to the phone
        record_to_json = {
                          'userId':userId,
                          'message':message
                          }
        data = []
        data.append(record_to_json)
        jsondata = simplejson.dumps(data) # Creates the json

        # Encode the JSON String
        u = unicode(jsondata, "utf-8")
        encoded_msg = u.encode("utf-8")

        params = {
                  'registration_id':registrationId,
                  'collapse_key':0,
                  'data.payload':encoded_msg
                  }

        paramsByte = urllib.urlencode(params)

        url = 'https://android.clients.google.com/c2dm/send'
        logging.info(token)
        result = urlfetch.fetch(url=url,
                                payload=paramsByte,
                                method=urlfetch.POST,
                                headers={'Content-Type':'application/x-www-form-urlencoded',
                                         'Authorization':'GoogleLogin auth='+token}
                                )

        data = []
        params_key = { 'status_code':result.status_code }
        data.append(params_key)
        self.response.headers['Content-Type'] = 'application/json'
        jsondata = simplejson.dumps(data)

        if result.status_code == 200:
            logging.info(result.status_code)
            self.response.out.write('' + callback + '(' + jsondata + ')') # handle the JSONP
        else:
            logging.info(result.status_code)
            self.response.out.write(result.status_code)
4

2 回答 2

1

您的代码包名称必须与您在注册​​ c2dm 帐户时提供的名称一致。对于 Java,如果您在注册时提供了 com.myapp,则您的 c2dm 调用必须发生在该包中。不过,不确定这如何转化为 Python。

于 2012-05-18T19:47:30.223 回答
0

就 C2DM 部分而言,一切似乎都还好。如果您说使用相同的凭据可以与您的本地服务器一起使用,我猜它应该可以在 App Engine 上使用。

就 XMLHttpRequest 错误而言,您不能通过 XMLHttpRequest 向其他域或子域发出请求。因此,您不能从 localhost 向yourSite. 一个解决方案是使用JSONP

于 2012-05-09T12:04:03.947 回答