Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

APNsのpushが飛ばなくなってしまったときの対応

More than 1 year has passed since last update.

概要

2018年7月18日に突然APNsを使用したiOSのpushが届かなくなりました。
原因の調査を行なったのでまとめます。
同じ境遇に遭遇した方のお役に立てば幸いです。

原因

pushが飛ばなくなった原因は、AppleのAPNsリクエストの仕様変更によるものだと思われます。
HTTP2のRFCには、すべての擬似ヘッダーが通常ヘッダーよりも先に書かれていなければならない(MUST)と記載があるのですが、この制約の強制をAPNsへ適用したことにより、制約に準拠していないリクエストが通らなくなったことがpushが送信できなくなった原因でした。

HTTP2のRFCが日本語訳されたものもあるので、こちらも参考にしてみてください。
https://summerwind.jp/docs/draft-ietf-httpbis-http2-14#section8-1-2-1

対策

リクエストヘッダー内で、擬似ヘッダーを通常ヘッダーより先に記載するように修正すればリクエストが通るようになります。
私の場合、apnoticというgemを使用していました。
apnoticを使用している場合は、apnotic内で使用しているnet-http2のバージョンを0.18.0以上にすれば直ります。
詳細はこのissueを見てください。

余談

net-http2gemを使用している場合、このgem内で
end.tap { |t| t.abort_on_exception = true }
https://github.com/ostinelli/net-http2/blob/1513fb7cb661bfcc6648ef31fbc3b66095dacc51/lib/net-http2/client.rb#L122
という記載があり、スレッドの外に例外を送った場合は、Rubyインタプリタごと落ちてしまうようになっていました。

そのためsidekiqなどの非同期ワーカーでpushを送信していると、Socket was remotely closedというログを残しsidekiqのワーカーごと落ちてしまいます。
Rubyインタプリタ落ちてしまうのを防ぎたい場合は、下記のようにerrorイベントを拾うコールバックを設定してください。

client.on(:error) { |exception| puts "Exception has been raised: #{exception}" }
詳しくはREADMEを参考にしてください。

参考

instance method Thread#abort_on_exception

rllllho
Rubyとうぇっぶが好きなエンジニア
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away