资讯专栏INFORMATION COLUMN

Apple APNS http2 Provider 开发 使用 okHttp

widuu / 1947人阅读

摘要:前言升级了后台推送接口,使用协议,提高了的最大大小,本文介绍新版实现方法基于框架框架不要使用的类直接发送请求,因为底层虽然使用了,可以设置和,但是超过,链接还是会断开,而官方建议保持长链接所以最好自建长链接,使用底层的类来直接发送请求,并通

前言

Apple 升级了后台推送接口,使用 http2 协议,提高了 payload 的最大大小(4k),本文介绍新版 APNS 实现方法

基于 okhttp 框架 http2 框架

不要使用 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
private Socket createSocket() throws IOException {
    debug("connect socket");
    Socket socket = new Socket();
    socket.connect(new InetSocketAddress(host, port));
    debug("socket connected");

    SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(
            socket, host, port, true);
    sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
    sslSocket.setKeepAlive(true);

    debug("start ssl handshake");
    sslSocket.startHandshake();
    debug("handshake success");

    return sslSocket;
}
创建 frame connection
private void createFramedConnection() throws IOException {
    debug("createFramedConnection");
    Socket socket = createSocket();
    framedConnection = new FramedConnection.Builder(true)
            .socket(socket)
            .protocol(Protocol.HTTP_2)
            .listener(this)
            .build();
    framedConnection.sendConnectionPreface();
    framedConnectionAlive = true;
    pingFuture = pingService.scheduleAtFixedRate(new PingTask(), 0, PING_PERIOD, TimeUnit.SECONDS);
}
发送 http2 header
private void sendHeader(String token, int contentLength) throws IOException {
    // 创建 http2 header,参考 apple apns 开发文档
    List
headers = Arrays.asList(METHOD_POST_HEADER, SCHEME_HEADER, USER_AGENT_HEADER, CONTENT_TYPE_HEADER, new Header(":path", "/3/device/" + token), new Header("authority", host), new Header("content-length", String.valueOf(contentLength))); // 创建 stream framedStream = framedConnection.newStream(headers, true, true); framedStream.readTimeout().timeout(timeOut, TimeUnit.MILLISECONDS); framedStream.writeTimeout().timeout(timeOut, TimeUnit.MILLISECONDS); }
发送 http2 data
private void sendData(byte[] bytes) throws IOException {
    Buffer buffer = new Buffer();
    buffer.write(bytes);
    framedStream.getSink().write(buffer, bytes.length);
    framedStream.getSink().flush();
}
Http2ApnsConnectionPool Http2ApnsService 基于 netty 框架

整体代码结构和 基于 okhttp 框架的差不多,可以参考 https://github.com/black-bamb...

总结

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65883.html

相关文章

  • Python使用HTTP2实现苹果原生推送

    摘要:由于苹果原生蛋疼的协议致使本来很简单的个推送服务让人望而却步。直到苹果最近的协议的出现才有所改善。如果推送失败后苹果的推送服务器会返回个错误的信息。结语虽然通过使用来实现苹果的推送服务是个比较简单的事情甚至会觉得比较枯燥无味的事情。 原文地址: http://52sox.com/python-use-h... 说起苹果的推送,可能很多开发人员就开始头疼了,因为实现苹果推送服务是1个比较...

    The question 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<