在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

Apple APNS http2 Provider 开发 使用 okHttp

2016-8-29 13:14| 发布者: zhangjf| 查看: 715| 评论: 0

摘要: Apple 升级了后台推送接口,使用 http2 协议,提高了 payload 的最大大小(4k) http2 框架 : okHttp 不要使用 okhttp3 的 Request 类直接发送 post 请求,因为 http3 底层虽然使用了 ConnectionPool,可以设置 keep ...

Apple 升级了后台推送接口,使用 http2 协议,提高了 payload 的最大大小(4k)

http2 框架 : okHttp

不要使用 okhttp3 的 Request 类直接发送 post 请求,因为 http3 底层虽然使用了 ConnectionPool,可以设置 keep alive 和 keep alive duration,但是超过 keep alive duration,链接还是会断开,而 Apple 官方建议保持长链接!

所以最好自建 socket 长链接,使用 okhttp3 底层的 FramedConnection 类来直接发送 http2
请求,并通过定时 PING 帧来保持链接

在实际开发中,Apple 的 development 环境也非常不稳定,经常 链接超时 和 ssl 握手超时,大多数情况下只能建立一个链接,第二个连接要么连不上,要么在 ssl 握手断开

实现 Http2ApnsConnection

Http2ApnsConnection 类负责 ssl socket 链接的建立,心跳包发送以及通过 http2 multiple stream 在一个 frame 中发送多条 push notification

创建 ssl socket:
  1. private Socket createSocket() throws IOException {
  2. debug("connect socket");
  3. Socket socket = new Socket();
  4. socket.connect(new InetSocketAddress(host, port));
  5. debug("socket connected");
  6. SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(
  7. socket, host, port, true);
  8. sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
  9. sslSocket.setKeepAlive(true);
  10. debug("start ssl handshake");
  11. sslSocket.startHandshake();
  12. debug("handshake success");
  13. return sslSocket;
  14. }
复制代码
创建 frame connection:
  1. private void createFramedConnection() throws IOException {
  2. debug("createFramedConnection");
  3. Socket socket = createSocket();
  4. framedConnection = new FramedConnection.Builder(true)
  5. .socket(socket)
  6. .protocol(Protocol.HTTP_2)
  7. .listener(this)
  8. .build();
  9. framedConnection.sendConnectionPreface();
  10. framedConnectionAlive = true;
  11. pingFuture = pingService.scheduleAtFixedRate(new PingTask(), 0, PING_PERIOD, TimeUnit.SECONDS);
  12. }
复制代码
发送 http2 header:
  1. private void sendHeader(String token, int contentLength) throws IOException {
  2. // 创建 http2 header,参考 apple apns 开发文档
  3. List<Header> headers = Arrays.asList(METHOD_POST_HEADER,
  4. SCHEME_HEADER,
  5. USER_AGENT_HEADER,
  6. CONTENT_TYPE_HEADER,
  7. new Header(":path", "/3/device/" + token),
  8. new Header("authority", host),
  9. new Header("content-length", String.valueOf(contentLength)));
  10. // 创建 stream
  11. framedStream = framedConnection.newStream(headers, true, true);
  12. framedStream.readTimeout().timeout(timeOut, TimeUnit.MILLISECONDS);
  13. framedStream.writeTimeout().timeout(timeOut, TimeUnit.MILLISECONDS);
  14. }
复制代码
发送 http2 data:
  1. private void sendData(byte[] bytes) throws IOException {
  2. Buffer buffer = new Buffer();
  3. buffer.write(bytes);
  4. framedStream.getSink().write(buffer, bytes.length);
  5. framedStream.getSink().flush();
  6. }
复制代码
Http2ApnsConnectionPool Http2ApnsService

最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-7-6 19:48

Copyright 2015-2025 djqfx

返回顶部