【问题标题】:Can't connect to Google Cloud Messaging (GCM) server using Google App Engine (GAE)无法使用 Google App Engine (GAE) 连接到 Google Cloud Messaging (GCM) 服务器
【发布时间】:2013-09-08 06:28:25
【问题描述】:

我正在尝试为我的应用设置 Google 云消息传递,并且我正在为我的服务器使用 Google App Engine。我有我的 API 密钥,但我似乎无法连接到谷歌云消息服务器。这是我的代码。

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://android.googleapis.com/gcm/send");
        try {

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("registration_id", regId));
            nameValuePairs.add(new BasicNameValuePair("data.message", messageText));    

            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            post.setHeader("Authorization", "key=*MY_API_KEY_HERE*");
            post.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");


            Header[] s=post.getAllHeaders();


            System.out.println("The header from the httpclient:");

            for(int i=0; i < s.length; i++){
            Header hd = s[i];

            System.out.println("Header Name: "+hd.getName()
                    +"       "+" Header Value: "+ hd.getValue());
            }


            HttpResponse response = client.execute(post);
            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String line = "";
            while ((line = rd.readLine()) != null) {
            System.out.println(line);
            }

            } catch (IOException e) {
                e.printStackTrace();
        }

当我查看日志时,标题设置正确。但是,我收到一个错误提示

org.apache.http.impl.client.DefaultRequestDirector tryConnect:连接到目标主机时捕获 I/O 异常 (java.net.SocketException):权限被拒绝:尝试在未经许可的情况下访问被阻止的收件人。 (映射-IPv4)

我已经在 Google API 控制台中打开了 Google 云消息传递,并且我已经检查了很多次我的 API 密钥。我不知道为什么我会被拒绝。是否有我在战争中需要的罐子或我必须在清单中放入的东西?

感谢您阅读本文! 标记

【问题讨论】:

  • 您是否使用 API 密钥定义了一组列入白名单的 IP 地址,而您尝试连接到 GCM 的 IP 不在该列表中?
  • 否,API 访问权限设置为允许的任何 IP。
  • 您从哪里获取 API 密钥?我只能找到一对密钥。

标签: java google-app-engine google-cloud-messaging


【解决方案1】:

我遇到了同样的问题,我正在使用与您正在使用的类似的东西。

  1. 我必须在我的 GAE 应用程序上启用计费功能(您可能有,但我不知道我必须这样做)
  2. 阅读 https://developers.google.com/appengine/docs/java/sockets/ 和 https://developers.google.com/appengine/docs/java/urlfetch/

因此,我之前看起来像你的代码现在看起来如下:

String json ="{}"; 
URL url = new URL("https://android.googleapis.com/gcm/send");
HTTPRequest request = new HTTPRequest(url, HTTPMethod.POST);
request.addHeader(new HTTPHeader("Content-Type","application/json")); 
request.addHeader(new HTTPHeader("Authorization", "key=<>"));
request.setPayload(json.getBytes("UTF-8"));
HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(request);

【讨论】:

    【解决方案2】:

    我也在用 GAE 实现 GCM,我遇到了这样的错误:

    com.google.apphosting.api.ApiProxy$FeatureNotEnabledException: The Socket API will be enabled for this application once billing has been enabled in the admin console.
    

    Nikunj 的回答也帮助了我。在实施他的建议后,通知会发送到设备,而无需为我的 GAE 应用程序启用计费。 这是我的实现,以防万一,可能对有同样问题的人有用:

    private void sendNotificationRequestToGcm(List<String> registrationIds) {
        LOG.info("In sendNotificationRequestToGcm method!");
        JSONObject json = new JSONObject();
        JSONArray jasonArray = new JSONArray(registrationIds);
        try {
            json.put("registration_ids", jasonArray);
        } catch (JSONException e2) {
            LOG.severe("JSONException: " + e2.getMessage());
        }
        String jsonString = json.toString();
        LOG.info("JSON payload: " + jsonString);
    
        com.google.appengine.api.urlfetch.HTTPResponse response;
        URL url;
        HTTPRequest httpRequest;
        try {
            //GCM_URL = https://android.googleapis.com/gcm/send
            url = new URL(GCM_URL);
            httpRequest = new HTTPRequest(url, HTTPMethod.POST);
            httpRequest.addHeader(new HTTPHeader("Content-Type","application/json"));
            httpRequest.addHeader(new HTTPHeader("Authorization", "key=" + API_KEY));
            httpRequest.setPayload(jsonString.getBytes("UTF-8"));
            LOG.info("Sending POST request to: " + GCM_URL);
            response = URLFetchServiceFactory.getURLFetchService().fetch(httpRequest);
            LOG.info("Status: " + response.getResponseCode());            
            List<HTTPHeader> hdrs = response.getHeaders();
            for(HTTPHeader header : hdrs) {
                LOG.info("Header: " + header.getName());
                LOG.info("Value:  " + header.getValue());
            }            
        } catch (UnsupportedEncodingException e1) {
            LOG.severe("UnsupportedEncodingException" + e1.getMessage());
        } catch (MalformedURLException e1) {
            LOG.severe("MalformedURLException" + e1.getMessage());
        } catch (IOException e) {
            LOG.severe("URLFETCH IOException" + e.getMessage());
        }
    }
    

    希望这会对某人有所帮助...

    【讨论】:

      【解决方案3】:

      最简单的方法是使用gcm-server.jar(您可以从here 获得)。

      那么您需要发送 GCM 消息的代码将如下所示:

      Sender sender = new Sender(apiKey);
      Message message = new Message.Builder()
          .addData("message", "this is the message")
          .addData("other-parameter", "some value")
          .build();
      Result result = sender.send(message, registrationId, numOfRetries);
      

      这是 gradle 依赖: compile 'com.google.gcm:gcm-server:1.0.0'mvnrepository url

      source

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-25
        • 2015-12-18
        • 1970-01-01
        • 2019-11-27
        • 2019-02-25
        • 2017-08-28
        • 2013-06-15
        • 2018-06-20
        相关资源
        最近更新 更多