Skip to content

Instantly share code, notes, and snippets.

@uupaa uupaa/WebSocket.Nagle.md
Last active Feb 27, 2017

Embed
What would you like to do?
WebSocket Nagle アルゴリズム問題

http://www.html5rocks.com/ja/tutorials/casestudies/world_wide_maze/ によると、

普通の OS では、TCP レベルでバッファリングすることで、効率良く通信するための Nagle アルゴリズム という仕組みがが実装されているのですが、このアルゴリズムが有効なままだとリアルタイムにデータを送信することができないという現象がありました。(正確にはこれに加えて TCP 遅延 ACK が組み合わさった場合。遅延 ACK でなくても、サーバーが海外にあったりして ACK がある一定レベル遅れる場合には同様の問題が発生します。)

Chrome for Android の WebSocket 実装では Nagle を無効にするための TCP_NODELAY オプションが付いているので、Nagle 遅延問題は発生しませんでしたが、Chrome for iOS につかわれている WebKit の WebSocket 実装には、このオプションが指定されておらず、遅延問題が発生します。同じ WebKit を使っている Safari も同様。この問題は Google を通して Apple に報告され、開発バージョンの WebKit ではすでに修正されている とのこと。

実際、この問題が発生すると、100ms ごとに送信している傾きデータが、500ms ごとにまとめて PC 側に届きます。これではゲームとして成立しないので、サーバーサイドから短い間隔(50msぐらい)でデータを送り続けることで遅延を回避しています。これはおそらく ACK が短い間隔で届くために、Nagle アルゴリズム的に送信可能な状態になるからだと考えています。

との事です。

changeset 138352

WebKit の changeset 138352 に上記の修正が取り込まれたらしので、138352 が iOS に実際に取り込まれたバージョンを確認して見ると。。。

  • MAJOR_VERSION = 537;
  • MINOR_VERSION = 24;
  • SYSTEM_VERSION_PREFIX_iphoneos = 6; // iOS is most like SnowLeopard currently.

なるほど、537.24 以降なら修正されているようです。

iOS 6 の userAgent

では、iOS 6 の userAgent を見てみましょう。

  • iOS 6.1
    • Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A406 Safari/8536.25
  • iOS 6.1.4
    • Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_4 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B350 Safari/8536.25

微妙です。changeset 138352 は、2012-12-20 (8ヵ月前) に行われているため、iOS 6.0 〜 iOS 6.1.4 には、この修正は入っていないかもしれません。

iOS 7 の userAgent

では、iOS 7 の userAgent を見てみましょう。

  • iOS 7 beta 6
    • Mozilla/5.0 (iPhone; CPU OS 7 like Mac OS X) AppleWebKit/537.xx.x (KHTML, like Gecko) Version/7.0 Mobile/xxxxxx Safari/xxxxx )

一部伏せ字にしていますが、iOS 7 で、Nagle アルゴリズムが修正された WebSocket が入ってることが期待されます。

iOS 7 がリリースされたら確認してみたいと思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.