• 服务器端接入华为推送遇到的connection reset问题


    整个四月份都在做服务器端推送接入的工作,第一期接入的平台只包括小米,魅族,华为。

    其中,小米魅族是支持用户全量推送的,不需要客户端上报用户的pushId,接入过程比较方便快速。

    华为则比较坑了:

    开发文档写的烂;

    不支持全量推送,需要客户端上报一个推送一个;

    为了解决开发中遇到的一些问题,专门加了华为官方的开发者群,但是提的问题基本上没人回答,导致开发进度一度暂停。

    通过其他渠道解决了开发中遇到的问题后,就把项目部署到测试服务器了,但是测试服务器上,项目并不像在本地开发时一样良好运行,在调用推送接口时出现了这个错误。

    在华为的群里问了官方,但是没人理,其他开发者也没有遇到这种情况,只有自己找出原因了。

    测试服务器与本地开发环境主要的不同有两点:

    ①测试服务器在日本,而我在中国大陆

    ②测试服务器是linux,我的电脑是Windows

    接下来就是使用排除法排除了。

    刚好公司在阿里云上还有一台闲置的linux服务器,在简单搭建环境后,我把项目部署到了这台阿里云服务器上,发现可以正常推送。

    可以看出,同是linux服务器,中国区的ip访问华为推送后台是没有问题的,但是日本东京的ip不可以。那就应该是华为的后台限制了日本的ip访问了。

    不过这个需要华为官方的确认。于是我找到产品经理,产品经理通过公司运营那边的关系,终于得到了华为的回复:不支持日本。

    那就很尴尬了,毕竟公司的测试服以及以后生产服务器都在东京。

    和其他同事讨论这个情况后,他们提出了一种解决办法:在国内搭建一个转发的服务,华为推送请求先从日本发到这个转发服务,通过转发服务发到华为后台,华为的响应也是按照这个路径处理。

    在仔细考虑可行性后,认为可以这么处理,于是开干。

    这个中转服务器要做的非常简单,就是原封不动的转发我们服务器的请求及华为服务器的响应。一个action类就可以满足了,具体代码如下:

    @Controller
    @RequestMapping(value = "push")
    public class PushCtrl {
        private Logger logger = LoggerFactory.getLogger(this.getClass());
        private static String apiUrl = "https://api.push.hicloud.com/pushsend.do"; // 应用级消息下发API
        @ResponseBody
        @RequestMapping(value = "doTransfer",method=RequestMethod.POST)
        public void doTransfer(HttpServletRequest request,HttpServletResponse httpServletResponse)
                throws Exception {
            byte[] data = FileCopyUtils.copyToByteArray(request.getInputStream());
            String jsonData = new String(data, "UTF-8");
            JSONObject jo = JSONObject.fromObject(new String(request.getParameter("nsp_ctx")));
            String appId = (String)jo.get("appId");
            String postUrl = apiUrl + "?nsp_ctx=" + URLEncoder.encode("{"ver":"1", "appId":"" + appId + ""}", "UTF-8");
            String response = httpPost(postUrl, jsonData, 50000, 50000);
            httpServletResponse.setContentType("text/plain;charset=utf-8");
            PrintWriter responseStream = httpServletResponse.getWriter();
            responseStream.println(response);
            responseStream.close();
        }
    
        @ResponseBody
        @RequestMapping(value = "test",method=RequestMethod.GET)
        public ModelMap test(ModelMap m) {
            m.put("key", "value");
            return m;
        }
        
        public String httpPost(String httpUrl, String data, int connectTimeout,
                int readTimeout) throws Exception {
            OutputStream outPut = null;
            HttpURLConnection urlConnection = null;
            InputStream in = null;
    
            try {
                URL url = new URL(httpUrl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setDoOutput(true);
                urlConnection.setDoInput(true);
                urlConnection.setRequestProperty("Content-Type",
                        "application/x-www-form-urlencoded; charset=UTF-8");
                urlConnection.setConnectTimeout(connectTimeout);
                urlConnection.setReadTimeout(readTimeout);
                urlConnection.connect();
    
                // POST data
                outPut = urlConnection.getOutputStream();
                outPut.write(data.getBytes("UTF-8"));
                outPut.flush();
    
                // read response
                if (urlConnection.getResponseCode() < 400) {
                    in = urlConnection.getInputStream();
                } else {
                    in = urlConnection.getErrorStream();
                }
    
                List<String> lines = IOUtils.readLines(in,
                        urlConnection.getContentEncoding());
                StringBuffer strBuf = new StringBuffer();
                for (String line : lines) {
                    strBuf.append(line);
                }
                logger.info(strBuf.toString());
                return strBuf.toString();
            } finally {
                IOUtils.closeQuietly(outPut);
                IOUtils.closeQuietly(in);
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }
        }
    }
    View Code

    接下来,就是部署,测试,竟然真的可行。那这个问题就算是解决了。

  • 相关阅读:
    kvm虚拟机网络管理
    kvm虚拟机存储管理
    kvm虚拟机迁移
    KVM嵌套虚拟化nested之CPU透传
    kvm认识和安装
    博客美化(二)
    日志管理
    IP分为五类
    windows(xshell)免密码登录
    mpvue的toast弹窗组件-mptosat
  • 原文地址:https://www.cnblogs.com/wangchaoBlog/p/9001908.html
Copyright © 2020-2023  润新知