2013年5月6日月曜日

Chrome でもう大量のタブに悩まされない Project Tab Manager 2.0 リリース

昨年夏に公開した Project Tab Manager という Chrome Extension のバージョン 2.0 をリリースしました。2.0 での変更点は下記の通り:
  • 新しい UI。より直感的で使いやすくなりました。
  • タブの状態を追跡するようになりました。プロジェクトとして保存さえしていれば、気軽にウィンドウを閉じて構いません。いつでも閉じた時の状態に復元可能です。
  • Chrome 再起動時にウィンドウとプロジェクトが自動的に関連付けられるようになりました。以前はマニュアルで関連付けなければなりませんでした。
  • キーボードナビゲーションが可能になりました。
  • オプションがクラウドに保存されるようになりました。自宅や会社で共通の設定が利用できます (要 Chrome サインイン)。
  • サマリー機能が拡張されました。自分がどのプロジェクトにどれくらい時間を費やしたのか、2 ヶ月まで遡ることができます。
Project Tab Manager 知らなかった!という人がほとんどだと思うので、ゼロから書いてみます。

Project Tab Manager が解決する問題

元々、仕事上コンテキストスイッチ (プロジェクトごとに頭を切り替える) がかなり頻繁に必要なため、それを少しでも楽になるようにと作ったのが Project Tab Manager でした。予めタブをセットにして保存しておき、手軽にひとつのウィンドウとして呼び出せる、というのが Project Tab Manager の基本コンセプトです。
こういう人にぜひ使って欲しいです
  • Chrome のタブが常に 100 個近く開いている
  • そのせいで Chrome だけでかなりメモリを消費している
  • 仕事中に Twitter や Facebook (もちろん Google+ も!) を見ちゃって気が散る
Project Tab Manager (以下 PTM) を使えば、常に必要最低限なタブのみを開いておけるので、今やっている仕事への集中力が高まり、Chrome の消費メモリが減少し、彼女ができます。
興味を持った方は、まずは Chrome Web Store からインストールしてください。

Getting Started

以前のバージョンではせっかくインストールしてもらったのに使い方がわからないという方が結構いました。ので 2.0 からヘルプを用意したのですが、日本語ヘルプを書くのがめんどいのでここに書いちゃいます。
PTM をインストールしたらまず下記を行なってそのパワーを実感して下さい。
  1. 新しいウィンドウを開く
  2. 何かウェブページを開く
  3. PTM のアイコンをクリック
  4. プロジェクト名を入力して保存する
  5. 以上

これでこのウィンドウにプロジェクト名が付きました。以後このウィンドウで開くあらゆるタブは、いつでも状態を復元することができます。以下を試してみて下さい。
  1. 先ほど開いたウィンドウにいくつか新しいタブを開き、ウェブページを読み込む
  2. ウィンドウごと閉じる (タブをひとつひとつ閉じるのではなく、ウィンドウ自体を閉じて下さい)
  3. PTM のアイコンをクリックして今閉じたウィンドウのプロジェクトを開く

元のタブの状態が復元されましたか?これが Project Tab Manager のパワーです!

その他の使い方

ブックマークを保存する

  • PTM では、プロジェクトを保存するとブックマークが作られます。また、プロジェクト保存時に含まれなかったタブも、以後は復元可能になります。必要に応じてプロジェクト内のタブ名横に表示されるスターアイコン (Chrome のブックマークと同じ) をクリックして保存しておけば、後から再度開くことが可能です。頻繁に使うページはブックマークしておきましょう。
  • 先ほどのブックマークとは、本当に Chrome のブックマークのことです。Bookmark Manager を開いて “Project Tab Manager” というフォルダ (デフォルト) を探してみて下さい。保存したプロジェクトがフォルダとして、タブがブックマークとして保存されていることがわかると思います。
  • これにより、Chrome for iOS や Chrome for Android からでも必要なブックマークにアクセスできるのが特徴です。


プロジェクトを編集する

  • プロジェクトの並べ替え、名前変更などは Bookmark Manager で行なって下さい。PTM 自体に編集機能はありません。

プロジェクトを削除する

  • プロジェクトの削除は PTM のポップアップから行えます。プロジェクト名右のゴミ箱アイコンをクリックするだけです。
  • 間違えて消しちゃった!という場合でも大丈夫。”__Archive__” というフォルダに移動されているだけです。Bookmark Manager で戻してあげるだけで復活します。

プロジェクトを関連付ける

  • バージョン 2.0 から Chrome を再起動してもウィンドウの関連付けが自動復元されるようにはなりましたが、場合によっては外れてしまうこともあるでしょう。そんな時はプロジェクト名横のピンアイコンをクリックして関連付けて下さい。

Lazy Load とは

  • 複数のタブをまとめて開こうとした時に長時間かかること、ありますよね?PTM の特徴のひとつとして Lazy Load という機能があります。これにより、プロジェクトで大量のタブを開こうとした時でも、アクティブなもの以外は読み込まなくなり、時間が短縮され、リソースをほとんど食わなくなり、彼女ができます。
  • Lazy Load されたタブのタイトルには “*” がプレフィックスされます。
  • オプションで Lazy Load を無効にすることもできます。

オプション

  • オプションでは下記を設定することができます
    • プロジェクトを保存するブックマークの場所
    • プロジェクトを保存するブックマークの名前
    • Lazy Load の有効・無効

Summary 機能

  • PTM ポップアップの時計アイコンをクリックすることで、どのプロジェクトにどれくらいの時間を費やしたか、まとめを見ることができます。
  • この記録は 2 ヶ月保存されます。「今月どのプロジェクトに一番時間使ったのかな?」「あー俺 Twitter ばっか見てるわ!」なんてことに便利かも。


キーボードナビゲーション

  • 慣れてくると、PTM ポップアップを開いた後、キーボードで操作したいという人は少なくないと思います。
  • 検索、その後 “tab” で絞りこまれたプロジェクトを選び、”return” でプロジェクトを開くことができます。
  • PTM ポップアップを開くこと自体も、ショートカットすることができます (Chrome の標準機能) “chrome://extensions” を開き、一番下の “Keyboard shortcuts” からお好みの設定を行なって下さい。僕は “Ctrl+p” にしてます。

最後に

バグを発見した場合、機能要望がある場合はこちらからリクエストしてください。開発者の方は直接 github から contribute して頂けると嬉しいです。

2013年4月11日木曜日

Google の Developer Advocate とはどんな仕事なのか?

僕の仕事は Google の Chrome Developer Advocate です。
Google Japan では先週 (2013 年 4 月) からこの Chrome の Developer Advocate を募集開始しました。他にもGoogle+、YouTube、Android など同種の担当者も募集しているのですが、よく聞かれるし、リクエストもありましたので、この機会に Developer Advocate がどんな仕事をしているのか、ご説明したいと思います。

Developer Relations とは

上記一連のお仕事ですが、すべて Google 内の Developer Relations チーム (以下 DevRel) という部署に属します。おそらく Google の中でも、開発者の皆さんが一番接触する機会の多いチームではないかと思います。DevRel はさらに Chrome や Android といった、プロダクトごとのチームに分かれています。

業務内容は名前から想像できる通り、Google と外部開発者との関係を築いていくことを中心としています。職種は Program Manager、Developer Programs Engineer、Developer Advocate、Technical Writer などがありますが、僕が担当しているのは Developer Advocate です。
Advocate という言葉だけで仕事の内容がピンと来る人はほぼいないと思いますが、学校で教わるような単語ではないので当たり前ですね。他社で言うところの Evangelist が一番近い仕事かと思います。それでも分からない方には、「Google のテクノロジーを外部の開発者の方にも使って頂けるよう啓蒙活動する仕事」という説明をすることが多いです。

Developer Advocate という言葉の由来はこんな感じ:
Evangelist という言葉は元々宗教の伝道師に使われる言葉です。しかし Google で Evangelist に類する仕事が作られた際、開発者の方に一方的に伝えていくだけでなく、対話やフィードバックから Google 自身も学び成長していくという意味を込めるため、Advocate という言葉が選ばれました。

以下、具体的な仕事内容に触れて行きますが、本記事は僕が担当している Chrome 周辺について述べているものであり、他のプロダクトについては必ずしも当てはまらない点を予めご了承下さい。今取り組んでいる仕事の一部を怒られないであろう範囲で書いてみます。

啓蒙活動

DevRel の仕事は、「Google のプロダクトをプラットフォームとしたアプリを使ってもらいたい人のお手伝いをする」のがメインです。Chrome に関して言えば、「Chrome をプラットフォームとしたアプリ、つまりウェブサイトやウェブアプリを制作する人を手伝う」言い換えると「Chrome だけでなく HTML5 を含めたウェブ全体、特にフロントエンド周りを盛り上げる」というのがミッションになります。非常にざっくりしてますし、はっきり言われたことはないですが、僕は勝手にそんなイメージを持って仕事しています。

講演

おそらくこれが一番業務として目立つ部分だと思いますが、外部で開催されるイベントで講演を行います。内容は大抵 Chrome の技術を紹介するものか、HTML5 の機能を紹介をするものです (ちなみに最近は HTML5 より Open Web Platform、OWP という言葉を使う機会が多いです)。当然資料も自分で作成するので、事前のインプットがかなり必要ですし、ある程度質問も想定して準備をするため、結構な時間が割かれます。地方で講演する場合は出張も伴います。

ソーシャルメディア

ブログGoogle+Twitter などのソーシャルメディアを使って最新の情報を流します。これは見られている方も多いと思います。

HTML5Rocks

HTML5Rocks の記事を書いたり、サイトのメンテナンスをしたりします。HTML5Rocks 自体がオープンソースですので、Pull Request も受け付けていますし、記事のレビュー、それから日本語の翻訳を頂いた場合のレビューもしたりします。

Google Developers Live

毎月YouTube Liveを使って生放送しているウェブ番組が Google Developers Live (GDL) です。ご覧になったことがある方はご存知だと思いますが、ゲストを呼んで技術セッションをして頂く内容です。スタジオの準備などは手伝ってくれるスタッフがいますが、その他の部分、ゲストの手配や内容の選定、番組の司会進行などはすべて自分でやります。アメリカとイギリスの GDL では、ゲストではなく Advocate が直接セッションをやっていますが、日本では今のところゲストの方にお願いしています。



せっかく作ったコンテンツをどう広げていくか考えるのも、Advocate の仕事です。過去にこんなブログ記事を書いたこともありました。これは見てくれる方々にとっても、コンテンツを作っている我々にとっても嬉しい、良案だったのではないでしょうか。

StackOverflow

フォーラム的な場でのサポートも業務のひとつです。日本語であれば Google Groups を使った質問の回答なども行なっていますが、グローバルでは StackOverflow を公式にサポートの場にしています。Google Code ではなく github にオープンソースのコードを置いてしまうところもそうですが、Google の (というより DevRel の?) 自前のシステムに拘らないところとか、合理的でよいと思いません?

コミュニティ

DevRel は全世界で 200 名程度 (日本では現在 4 名) しかおらず、スケーラビリティが重視されます。そこで、外部コミュニティの一部となってテクノロジーを盛り上げる場面も多々あります。

Google Developers Expert

ご存知の方は多いと思いますが、Microsoft でいうところの MVP のような、優秀な外部の開発者を認定する Google Developers Expert という制度があります。GDE の皆さんとの情報交換も重要なお仕事です。

これは以前 Google API Expert と呼ばれていたもので、元々日本発のプログラムが、昨年から全世界共通のプログラムになりました (Naoki IshiharaFumi Yamazaki のおかげです!)。ちなみに僕も入社前は OpenSocial の API Expert でした。 

コミュニティとのお付き合い

日本の DevRel で Chrome 担当は僕だけですので、当然やれることは限られてきます。そこで、上記 GDE を含め、志を同じくする開発者コミュニティと協力し合い、時には一部となってお手伝いをするのも重要な仕事です。コミュニティを盛り上げるために何ができるか考えるのは、かなり楽しいです。

イベント運営

コミュニティのお手伝いの一環として、Google の会場や設備を提供し、人員としてお手伝いするのも重要なお仕事です。勉強会などのイベントを開催する、プロダクトに関わるエンジニアに講演してもらう、など。2011 年には html5j とコラボで Chrome+HTML5 Conference を開催しました。Chrome Tech Talk Night は既に 5 回を数えています。6 月には Test The Web Forward というイベントの開催も予定しています。

パートナー、インプット、Hacking、etc

実際はもっと雑多な仕事がありますが、上記に分類されない仕事としては主に以下のようなものがあります。

パートナーとのお付き合い

オープンな一般開発者向けの仕事が占める割合はかなり大きいですが、表からは見えないパートナー向きの仕事もあります。何かプロダクトを作ってもらうための交渉をすることもありますし、コンフィデンシャルな情報を含む技術的問題を受けて、Chrome 自体の機能を改善したりといったこともあります。技術的にパートナーとの間を取り持つのも、Developer Advocate の重要な役割です。

インプット

ここまであまり技術的な話がなかったですが、もちろん最先端の技術力も求められる仕事です。インプットなしにアウトプットなどできる訳もありませんので、常に最新情報にキャッチアップしていることが求められます。

Hacking

理屈だけインプットしていても仕方ありませんので、実際の開発も行います。大きなものを作る機会はそれほど多くありませんが、技術の啓蒙に直接繋がるデモや、社内向けのツールを作る場合もあります。

今まで作ったものとしては、東京の Chrome エンジニアチームが担当している範囲のものをテーマにして、WebSocketForms、最近は FileSystem 関連のデモも。後は趣味と実益を兼ねて Chrome ExtensionChrome App を作ったり。コードは github で公開しています。
基本的にプロダクションレベルのコードを自分で書くことはないですが、同僚の中にはパッチを送り続けて WebKit (今は Blink ですが) の committer になっちゃった人もいます。

Chrome Experiments

また、過去に話題になった Chrome Experiments の中には日本発のものもあることをご存知でしょうか?例えば先日発表された World Wide Maze もそう。ああいったプロジェクトにテクニカルなサポートを行うのも、Developer Advocate が担当します。

エンジニアとのやりとり

Google 東京オフィスの Chrome エンジニアチームはそれなりの規模です。先述のように、 WebSocket や FileSystem、Forms、WebComponents周りなど、主に OWP 機能を実装しています。W3C や IETF のサイトに載る標準仕様を自分の手で書いている人も少なくありません。そんなエンジニアたちと外部開発者の橋渡しをするのも、僕の仕事です。GDL や講演を通じてエンジニア自ら啓蒙してもらうこともあれば、外部開発者のフィードバックを届けることもあります。

仕事の楽しさ

日常業務は上記のような感じです。ただ、これはあくまで僕の例であって、Developer Advocate 全員に当てはまるものではありません。同じ Chrome DevRel のメンバーは、本社のある Mountain View を中心に、日本を含めて世界 7 カ国に散らばっていますが、それぞれに得意分野を持ち、異なる仕事をしています。

Google では、仕事は与えられるものではなく、自分で作り出していくものです。そのため、人によってやってることが全く違うのは、ごく自然なことなのです。いいと思ったことは何でもやれるし、それでもちゃんと評価もしてもらえる。

僕が過去にやった思い出深い仕事をふたつ挙げます。
ひとつは、2011 年の GDD での Developer Link です。2 つのセッションやキーノートなどに加え、企画から制作、パートナーとの交渉まで含め、イベント当日までにサービスを完成させるべくプロジェクトをリードしました。コードも一部書いてます。

もうひとつは現在進行形ですが、Web Music Developers Japan の活動です(仕事というより趣味ですが)。元々音楽好きでブラウザでシンセサイザーが作れる Web Audio API に大興奮していた身としては、それを通じて開発者はもちろん、過去であれば無関係だった業界の有名人と関われたりするのは、役得だなあと思います。Web MIDI API が登場してくれば、今後ますます面白いことをしかけていけるんじゃないかとワクワクしています。

難しい所

周囲がハイレベルで、正直ついていくのに必死です。技術的にも、仕事のやり方的にも。
加えて、上記のような仕事が常に同時進行している感じなので、時間配分や集中力の管理も難しい部分です。

それに拍車をかけるのが、Regional (本社から離れている) であることです。Chrome DevRel で日本担当は僕だけですので、チームメンバーとのコミュニケーションは基本メールか Hangout。Hangout は便利ですが、テクノロジーで時差は超えられません (今だと日本の朝 9 時が本社の 17 時、日本の 17 時が London の朝 9 時)。メールは文字情報だけなので、相手の表情は見えないですし、空気が伝わって来ません。

そこで出張ということになる訳ですが、今度は対面コミュニケーションに苦労します。僕の英語力は 3 年前の時点で TOEIC ほぼ満点でしたが、それでもまだ十分とは言えません。言語そのものというよりも、自分の性格だったり、カルチャー的な部分の方が大きいかもしれませんが、話が長くなりそうなので、この辺はまた別の機会に。

環境

これまで何社か渡り歩いてきましたが、働きやすさという意味では群を抜いて快適な会社です。無料のランチ (実は朝食と夕食もある) が取り沙汰されることが多いですが、産休は父親 (Paternity Leave)、母親 (Maternity Leave) ともに取ることができますし、休暇も柔軟で、まとめて 1 ヶ月休んじゃう人も少なくありません。チームでのコミュニケーションを充実させるためのアクティビティも頻繁にありますし、社内ではしょっちゅう Tech Talk や部活動が行われていて、とてもよい雰囲気です。こればっかりは、入ってみないとわからないと思います。

求めている人材

Chrome DevRel で募集している人材は 先日も書いたように、「英語、日本語が堪能で交渉力、技術力、講演、イベント開催に自信のある方」です。この言葉の意味が今回の記事で少しはお分かり頂けたのであれば、書いた甲斐があったというもの。

もちろん、ここでの話はあくまで「僕の場合」であり、新しく担当する方に同じような仕事をして欲しいと思っていませんし、むしろその人なりのやり方を生み出して欲しい、生み出すべきです。

自分で仕事を作り、こなしていける人。コミュニケーション能力が高く、色んなことをグイグイと、楽しみながら前に進められる人に来てもらえたら、嬉しいな。

その他の職種について

今回は主に僕と一緒に仕事してくれる方をターゲットに、仕事内容について説明しましたが、最後に DevRel で募集しているものを、他の職種も含めてご紹介しておきます。

Developer Advocate - Chrome

こちらが今回紹介した僕と同じ仕事です。

Developer Advocate - Google+

僕と同じ Developer Advocate で Google+ を担当します。

Developer Advocate - YouTube

こちらも Developer Advocate で YouTube を担当します。

Developer Programs Engineer - Android

Developer Programs Engineer は Developer Advocate よりもテクニカル寄りな仕事です。パートナーやコミュニティとのコミュニケーションよりも、コードを書いたりオンラインサポートをしたりするのが中心になります。ちなみに昨年末米国に転籍となった Takashi Steveland Matsuo は現在 AppEngine の DPE です。

Program Manager

こちらは米国に転籍した Fumi Yamazaki が以前担当していた仕事です。Program Manager は特定のプロダクトを持ちません。日本の DevRel の代表者としてチームをまとめ、予算、コミュニティ、イベントなどの管理を行います。高い交渉能力と英語力、リーダーシップが必要とされます。
というわけで、皆さんからの応募をお待ちしております :)

関連記事

2012年7月29日日曜日

プロジェクトごとにタブを管理できるChrome Extension "Project Tab Manager" を公開しました

かなり前から自分で欲しいと思っていた Chrome Extension を、ようやく Chrome Web Store で公開することができましたのでご紹介。

なぜ?

Chrome のブックマークの思想はとてもシンプルです。一度星を付けたら(ブックマークしたら)、基本的には Omnibox (URLバーのところ) から数文字打つだけで候補に出てくる、という極限までスリム化した使い方を想定しています。そのため、ブックマークはカテゴリに分けて整理して使いたい、という方にとっては痒いところに手が届かない部分もあるかもしれません。僕自身もそう感じるひとりです。

ブックマークの整理というと、僕も以前であればカテゴリーで分ける使い方がメインだったのですが、それだと探すのが面倒だし、結局検索してしまったり、直接URLを覚えて入力してしまうことが多々ありました。そこで最近は、カテゴリごとではなくプロジェクトごとにフォルダを作って、必要なブックマークを集めるという使い方をし始めていました。こうしておくことで、必要な時に必要なページをまとめて開く、といった使い方ができるからです。仕事柄複数のプロジェクトを同時並行で進めることが多いので、頭を整理しやすくなりますし、開いているタブの数を減らす効果も得られます。
ただ、このやり方だとプロジェクトに後からブックマークを追加しにくいとか、プロジェクトの一部だけど最初から開かないようにできない、とか、不便な点も少なからず残ります。そこで作ったのがこの Project Tab Manager 。完全に上記の使い方に最適化された Chrome Extension です。

基本的な使い方

インストールして頂くと、Omnibox の右側に Extension のボタン (フォルダの形をしたアイコン) が表示されます。これをクリックすると、何もプロジェクトが登録されていない状態の Project Tab Manager が開きます。

プロジェクトを登録するには、「新しいプロジェクト」に名前を入力して保存するだけ。今開いているウィンドウのタブがまとめてプロジェクトに保存されます。これを繰り返すことで、ウィンドウごとにプロジェクトが管理できるようになります。



次にプロジェクトを開きたい時は、プロジェクト名をクリックすれば、新しいウィンドウが開き、すべての必要なタブがまとめて開きます。ポイントのひとつは、この時にアクティブなタブだけが実際にウィンドウをロードするところ。別のタブを選択すると、そこで初めてページがロードされます (レイジーロード機能)。こうすることで、たくさんのタブを開いても、実際に使い始めるまでの時間は短縮できます。もちろんこの機能は設定でオフにできます。

Project Tab Manager からプロジェクトを開くと、プロジェクトのブックマークと共に、現在開いているまだブックマークしていないタブのページもグレーで表示されます。マウスオーバーした時に右側に表示される + をクリックすれば、そのタブのURLをプロジェクトに追加できます。
既にあるブックマークにマウスオーバーした場合は、四角形と✕が表示されます。四角形はアクティブ・パッシブを切り替えるもので、パッシブ (薄い青) にしておくと、プロジェクトの一部にはなりますが、プロジェクトウィンドウを開いた場合にタブとして追加されません。なので、必要な時だけ開く扱いにできます。✕をクリックすると、ブックマークは削除されます。



Project Tab Manager の特徴のひとつは、これらのブックマークがネイティブ機能のブックマークとして保存される点です。設定を見て頂くとわかりますが、デフォルトでは「その他のブックマーク」に「Project Tab Manager」というフォルダを作って、その下にプロジェクトごとのブックマークが作られることになります。こうすることで、Chrome Sync を利用してさえいれば、Chrome for Android や Chrome for iOS からでもプロジェクトのブックマークを利用可能です。外部のサーバーに保存されるといったことはありません。
また、Project Tab Manager 自体の編集機能は最低限に留め、表示順を変更したり、削除したりといったことはネイティブのブックマークマネージャーから行うことができます。



Project Tab Manager のもうひとつの特徴は、各プロジェクトにどれだけの時間を費やしたのかをあとで振り返ることができる点です。ウィンドウの右上に表示される時計アイコンをクリックすると統計画面が開き、どの時間帯にどのプロジェクトウィンドウを使っていたのか、どのプロジェクトに何割くらいの時間を割いたのかを確認することができます。

各プロジェクト名にマウスオーバーした場合は、ピンアイコンとゴミ箱アイコンが表示されます。ピンアイコンはウィンドウにプロジェクトを紐付けます。こうすることで、このウィンドウはこのプロジェクト用ですよ、ということを Project Tab Manager に教えることができます (ここはできれば自動化したい部分)。これは統計機能で必要になります。
ゴミ箱アイコンは、プロジェクトを削除するのではなく、アーカイブします。ブックマークの中に __Archives__ というフォルダがあるのですが、そこに移動されるだけですので、必要な時に元に戻すこともできます。

技術的な部分

この Extension は元々素の JavaScript で作ったものだったのですが、HTML5とか勉強会での講演のために、AngularJS ベースに変更しました。おかげでコードは格段に整理できましたし、AngularJS に興味がある方には面白いものだと思います。ソースコードはこちらで公開しています。
AngularJS とは Google のエンジニアも関わっている JavaScript のフレームワークで、他のフレームワークとはちょっと違ったアプローチが体験できます。詳しくはまた別の機会にブログを書きたいと思っていますが、興味のある方は先述の HTML5とか勉強会で僕がやったライブコーディング込みの講演のビデオが参考になると思います。15分程度ですのでぜひご覧頂ければと思います。

フィードバック求む!

リリース直前に手を入れた部分でいくつかバグが出ているようなのですが、まだ整理できていない状態です。バグを見つけた方はぜひ github に issue として登録して下さい。また、機能面でもフィードバックを頂けると嬉しいです。

Project Tab Manager で皆さんの生産性が少しでも上がればと思います。

Special Thanks to Shinsuke Okamoto for icon designs.

2012年5月5日土曜日

Sublime Text 2 のススメ

皆さんはコーディングの際、どのエディタを使っていますか?僕はもっぱらTerminalでvimゴリゴリ派だったのですが、人によってはEmacsだったり、MacのアプリだとCodaとかTextMateが人気でしょうか。最近だとWebStormとかKomodo Edit辺りも人気あると聞きます。手に馴染んだエディタがあると、なかなか変える気にならないですよね。そんな中で僕が最近本気で使い始めているのが、最近海外のフロント系エンジニアの間で人気が高まっている Sublime Text 2 というエディタです。今日はこの Sublime Text 2 ( 以下 ST2 ) を紹介してみます。

Sublime Text 2 の魅力

僕の場合、vimがすっかり手に馴染んでしまっていたので、乗り換える必要性を強くは感じていなかったのですが、やはりプロジェクト単位で作業する場合は、左側にプロジェクトのファイル一覧が表示されてたりすると便利ですよね ( NERD tree は試したのですが、なかなか使い方が覚えられず、断念してしまいました。) 。タブでファイルを複数開いておくとか、日本語も十分対応してくれてる必要があります。何よりもvimと同じ操作で使えることも、僕にとっては超重要でした。そんな条件でいくつか試していた中で、たまたま同僚がまとめて購入するからというので使い始めたのが、ST2 です。

ST2 のサイトに書いてあるウリはこんな感じ:
  • シンプルで高速なインターフェース
  • ミニマップで全体像を把握
  • テキストのマルチセレクトが可能
  • マクロを使った操作の自動化が可能
しかしながら、ぶっちゃけどれも僕には響きませんでした。そもそもウリの魅力が理解できないだけでなく、GUIで設定の変更もできないし、正直なところ何が人気の秘密なのかすぐには分からず、vimモードで使えてるからまあいいかー程度で使っていました。しかし Sublime Package Control を入れてから、段々これにハマり始めています。

Package Control を入れてできるようになったことは、例えば
  • LESSのコンパイル (?) がショートカットキーひとつでできるようになる (からやっと LESS を使い始めた)
  • git コマンドがエディタ内から打てるようになった
  • HTMLタグの補完をしてくれるようになった
  • CDNのURLを簡単に入力できるようになった
など。これだけで魅力的に感じる人もいるかもしれません。Package Control はエディタ内でレポジトリからプラグインを手軽にインストールできるプラグインで、TextMate 互換、かつ Python で書くことができます。

ST2 に魅力を感じた人は、早速インストールしてみましょう。お試しはもちろん無料で出来ますし ( 時間制限付き? )、購入する場合は $59 です。

Sublime Text 2 の便利な使い方

英語ですが、既に素敵なまとめ記事がありますので、そこから拝借 + ちょっと味付けして、僕がグッときた Tips をいくつか紹介しましょう。

コマンドパレット (Command Pallet) を使う

TextMate と同様、ST2 では Command + Shift + p でコマンドパレットを開くことができます。コマンドパレット上でタイプすると絞りこまれていくので、必要なコマンドを選択して実行できます。

Package Control をインストールする

何はともあれこれ。これを入れることで ST2 は比較にならないくらいパワーアップします。インストールするには Control + `、日本語キーボードの場合 Control + Shift + @ を押すと、画面下にコンソールが開きますので、下記のコマンドをコピペして入力します。
import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp) if not os.path.exists(ipp) else None;open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read())
実行後再起動すれば、Package Controlが使えるようになります。コマンドパレットを開き、install と入力すると、レポジトリからパッケージのリストが読みこまれ、好きなものをインストールできるようになります。

Vimモードを有効にする

メニューの Preferences から Settings - Default を選択すると Preferences.sublime-settings というファイルが開きますので、一番下の "ignored_packages": [“Vintage”] の部分を "ignored_packages": [] に変更して保存します。これでVim互換モードが利用できるようになります (あくまで互換なので、完璧ではないです。徐々に改善している模様) 。

スニペットを活用する

まだ自分でどうやって作るかなどまで掘り下げられてないですが、必要に応じて各種 Snippet のパッケージをインストールすることで、手軽に定型の文字列を入力することができるようになります。例えば li と入力してタブキーを押せば、
  • li
    と表示されて、タブを押すごとに必要な属性値を補完していくことができます。利用できるスニペットはコマンドパレットで snippet と入力することで確認できます。

    おすすめパッケージ

    僕が気に入って使ってるパッケージは以下の通り
    • LESS-build (要node.jsですが、Command + b だけで.lessのファイルを.cssにコンパイルしてくれます)
    • HTML5
    • Git
    • cdnjs
    • SFTP
    • Tag
    • SublimeCodeIntel
    • Nuttuts+Fetch (自分で作ったプロジェクトテンプレートセットをさくっと組み込んでコーディングが開始できます)
    • Terminal (今のディレクトリで Terminal を開いてくれます)
    他にもたくさんパッケージがあるので、チェックしてみてください。

    コミュニティ

    最後にこの ST2 ですが、日本ではまだまだユーザーが少ないようで、日本語の情報はあまり多くありません。Chrome の Google API Expert である @yoshikawa_t さんが Google Group を作ってくれていますので、興味のある方はぜひそちらで情報交換をしましょう。他にもいくつか有益なリンクを載せておきます。

    2012年5月2日水曜日

    HTML5Rocksが日本語に対応


    HTML5Rocks というサイトをご存知ですか?HTML5Rocks は、世界でも有数の HTML5 関連情報が集まったサイトで、チュートリアルやサンプル、スライド、動画などで構成されています。このサイトは僕が所属する Chrome Developer Relations チームが中心になって作っているのですが、これまで英語のみということで日本の方たちにはなかなかとっつきにくいものだったのではないかと思います。その HTML5Rocks が、ついに i18n ( internationalization = 国際化 ) を果たし 9 ヶ国語に対応、日本語のコンテンツも追加し始めました。

    今は人気のあるコンテンツから順に翻訳を行なっているため量はまだまだ多くありませんが、これまで英語を読むことに抵抗のあったディベロッパーの皆さんにも、まとまった情報源として利用して頂けるようになればと考えています。既に翻訳されている記事からいくつかご紹介しましょう。

    JavaScript で File API を使用してファイルを読み取る

    File / FileList / FileReader API を使用し、JavaScript でバイナリ ファイルの処理と読み取りを行うためのスタート ガイドです。

    ネイティブ HTML5 ドラッグ&ドロップ

    ドラッグ&ドロップも HTML5 の主要機能の 1 つです。この記事では、ネイティブ ドラッグ&ドロップ機能を追加してウェブ アプリケーションを強化する方法について説明します。

    File System API について知る

    File System API により、アプリケーションでは、ユーザーのローカル パソコン上の保護されサンドボックス化されたファイル システムに対してファイルやディレクトリの読み取り/書き込みを行うことができます。

    Contribution 受付中!

    この HTML5Rocks ですが、実はサイト自体がオープンソースで開発されているということをご存知でしたか?レポジトリは以下になります。

    http://code.google.com/p/html5rocks/

    サイトがオープンソースということで、実は内容もオープンソースの考え方に基いて作り上げています。もっと分かりやすく言うと、HTML5Rocks では皆さんからの投稿を受け付けています。チュートリアルでも、ケーススタディーでも構いません。もし HTML5 の最新テクノロジーを使った記事を書いて、それを英語化できるという方がいらっしゃったら、ぜひこちらの Contributors Guide をお読みになって、手順に従って patch をお送り下さい。

    また、(ここからが実は本題なのですが) 記事を日本語に翻訳してくれる方も募集しています。多国語に翻訳されるドキュメントでは一般的に言われることだと思うのですが、頻繁に更新されるドキュメントの翻訳を常に最新に保つのは、コスト面で考えて非常に難しいのが現実です。そこで HTML5Rocks では、誰でも contribute することができるという利点を生かし、翻訳についても投稿を受け付けることにしました。

    少しでもご興味を持たれた方は、まずは Localization Guide をお読み頂き、もし実際に翻訳をされた場合は、patch を送って頂ければと思います。何か質問などありましたら、Google+ や Twitter で気軽に話しかけて下さい。

    2012年3月14日水曜日

    HTML5開発者に便利なツール14個

    先日Google+でAddy Osmani氏が紹介していたオンラインツールが便利そうだったので紹介します。

    DocHub.io


    CSS, HTML, JavaScript, DOM, jQuery, PHP, PythonのAPIリファレンス。インクリメンタルサーチできるので、開発中は常に開いておきたい。

    Dillinger.io


    最近GitHub関連で使われるようになって流行り始めたMarkdown記法を、視覚的に確認しながら入力できるツール。DropboxやGitHubのアカウントで繋ぐと、アップロードできるようです。Mac用デスクトップアプリのMouというのも合わせて紹介されていました。

    HTML5Please


    今から使えるHTML5機能のリストとブラウザの対応状況に応じたアドバイス、そしてPollyfill(未対応ブラウザ向けに機能を補完するJSライブラリ)などを教えてくれる便利サイト。

    そしてそのAPI。ここで作ったウィジェットを自分のサイトに埋め込むことで、未対応の機能がある場合に教えてあげるUIを簡単に作れます。ブラウザの対応状況は caniuse.com を使うことで常に最新の状態だとか。

    CSS3Please


    このページに表示されているCSSをインラインで編集することで、表示内容を確認しつつコピペできる便利サイト。

    CSS3 Playground


    表示内容を確認しながらCSS3のプロパティをいじることができるプレイグラウンド。グラデーション、テキストプロパティ、トランスフォームなどに対応しています。

    Responsive


    ワンソースでスマートフォンからデスクトップまで幅広い閲覧環境に対応するレスポンシブウェブデザインというコンセプト。そんなレスポンシブウェブデザインを使って作られたサイトの表示内容をまとめて確認できるツール。

    CanIUse.com


    既にご存じの方も多いと思いますが、HTML5のブラウザごとの対応状況を調べるサイトといえばここです。

    HTML5 Readiness


    こちらもHTML5の対応状況を知るには有名なサイトですが、個別のAPIについて調べるためというよりも、HTML5の実装が進行していることをビジュアルで実感できることに主眼が置かれています。

    Browserstack


    新旧各種ブラウザのテストができる有料サービス。

    Grunt

    JavaScriptプロジェクト向けのコマンドラインビルドツール。ファイルの連結からバリデート、圧縮(難読化)、ユニットテストまでできます。まだベータ版だけどとてもパワフル。

    jsPerf


    様々なJavaScriptのテストケースを作成・共有できるサイト。既存のテストケースだけでも参考になります。Browserscope.orgを使ったブラウザごとの比較も。

    jsconsole


    JavaScriptコンソール兼デバッガのウェブアプリ。Adobe Shadowのようなツールが出てきた今どの程度役に立つのかは不明ですが、iOSやAndroidのブラウザに接続して使えるデバッガ機能が素敵です。

    Chrome DevTools AutoSave

    http://addyosmani.com/blog/autosave-changes-chrome-dev-tools/
    Chrome DevToolsの変更履歴管理機能と保存機能は便利ですが、この拡張機能を使うと自動で保存してくれるようになり、実質的にChrome DevTools上で開発を進めることが可能になります。Addy Osmaniがスクリーンキャストで分かりやすく説明してくれています。

    Codiqa


    jQuery Mobileサイトをビジュアルで構築できるウェブアプリ。

    2012年3月6日火曜日

    WebSocketのバイナリメッセージを試したら、ウェブの未来が垣間見えた

    長い記事なので、先に結論だけ書いておきます。WebSocketのバイナリメッセージ機能は、これまでのインターネットのあり方をひっくり返します。「そんなの知ってるよ」という方もいるとは思います。僕も理屈では分かってたつもりだけど、実際にアプリを作ってみて、具体的にそれを感じることができたので、ちょっと長いですがどういうことなのか説明してみます。

    WebSocketとは

    WebSocketは、HTML5関連の中でも特に注目を集めている技術の一つです。通常のHTTP通信であればクライアントからのリクエストなしにサーバーは応答しませんが、WebSocketを使うことでクライアントとサーバーの間で双方向の通信が可能となります。これを利用することで、今後様々なリアルタイム性の高いサービスを構築することが可能になるでしょう。
    そんなWebSocketですが、これまで波乱の道を歩んできました。数年前から様々なブラウザで利用可能な状態ではあったのですが、セキュリティ上の理由などで大幅な仕様の見直しが入り、昨年末ようやくひとつの完成形を見せ、複雑な仕様もひとまず落ち着いたところです。現在Google Chromeですべての仕様をサポートしていますが、まもなくFirefox11、Internet Explorer10でもそれらが利用できるようになると言われています。
    WebSocketが持つ機能の中で僕が最も注目しているのが、バイナリ送信機能です。これまではテキストしかやりとりできなかったのですが、最新の仕様ではバイナリのメッセージも送れるようになりました。従来からBase64などのエンコーディングを使うことで、テキストとして送ることはできましたが、バイナリをそのまま送れば、約30%のオーバーヘッドを節約できます。もちろんバイナリ送信機能の価値はそれだけではないのですが、それはこの記事を最後まで読めばもう少し分かると思います。

    Audio Stream Experiment

    ここで最近僕が作った、WebSocketのバイナリメッセージング機能を使ったデモをご紹介しましょう。このデモでは、ユーザーが手元に持っているオーディオファイルをリアルタイムにストリーミング配信することができます。ここからはアプリの作りの話をしますので、WebSocketでウェブがどう変わっていくのかだけに興味のある方は、「WebSocketのバイナリメッセージが意味するもの」まで読み飛ばしてしまっても構いません。

    このアプリで使われている技術に興味のある方は、何はともあれ、試してみて下さい(要Chrome)。ソースコードもgithubで公開しています。
    適当な名前を入れてconnect後、mp3, wav, m4aなどのオーディオファイルをデスクトップからドラッグドロップしたら、playボタンを押すことで、オーディオのストリーミング再生を開始できます。もしAttendeeリストに他に人がいなければ、自分で2つのウィンドウを開いて同じサイトにアクセスすることで、どのようにオーディオがストリーミングで配信されているか、試すことができます。

    アーキテクチャ

    ここで使っているオーディオ再生の仕組みは、Web Audio APIと呼ばれるものです。Googleのエンジニアが中心になって作っている仕様で、現在Chromeのみで利用できますが、いずれはSafariなど他のWebkit系ブラウザでも利用できるようになるでしょう。今も標準化の議論が進んでいますが、2012年3月現在、Webkit系以外で実装するという話は聞いていません。Firefoxにも同種のAudio Data APIと呼ばれるものがありますが、こちらは標準化の予定はないようです。Web Audio APIについて詳しい説明はここでは割愛しますが、以前HTML5とか勉強会で使った資料がありますので、よければそちらを参照して下さい。
    サーバーはnode.jsを使っています。ノンブロッキング・非同期入出力が特徴のnode.jsは、現在最も注目を集めているサーバー技術で、JavaScriptで記述することができます。2012年3月現在、どの言語の実装でもバイナリを扱えるWebSocketライブラリは数多くありませんが、node.js向けの中からwsというライブラリを選びました。
    node.jsのサーバーは、ファーストサーバー社の提供しているnode-ninja(node.jsの総本山とも言えるJoyentの開発したSmartMachinesという仮想サーバー使用)を使わせてもらいました。
    今回のデモでは、このnode.jsで構築されたサーバーから受け取ったオーディオデータをブロードキャストすることで、すべての接続しているユーザーに同じオーディオストリーミング環境を提供しています。

    各クライアントはPlayerとListenerと呼ばれる、合計2つのオーディオ再生機構を持ちます。デスクトップからドラッグドロップされたオーディオファイルは、Playerを使って再生されると同時に、node.jsのサーバーにWebSocketを使って転送されます。サーバーは受け取ったオーディオデータをすべてのクライアントに即時にブロードキャストします。各クライアントは、サーバーから受け取ったオーディオデータをListenerに流しこみ、音声を再生します。
    ちなみにデモには、オーディオストリーミングだけでなく、簡単なチャット機能も実装してあります。

    WebSocketの基本

    まずはWebSocketの基本的な使い方から。

    テキストメッセージのやりとり

    ブラウザで使えるWebSocketのAPIは非常にシンプルです。
    まずはソケットを開きます。
    var ws = new WebSocket(‘ws://localhost:3000’);
    サーバーでコネクションを受け付けると、openというイベントが返ってきます。
    ws.onopen = function() {
    ...
    }
    メッセージを送信する際は
    ws.send(message);
    とします。
    メッセージを受信する場合は、messageというイベントで受け取ります。
    ws.onmessage = function(msg) {
    ...
    }
    コネクションが閉じられた場合も同様にcloseというイベントが発生します。
    ws.onclose = function(event) {
    ...
    }
    WebSocketのAPI自体は非常にシンプルだということがことが分かりましたでしょうか?
    問題は、このシンプルさゆえの、その上に乗るプロトコルの重要性です。
    WebSocket APIにはSub Protocolという仕様が含まれていますが、これは標準化とサーバーへの実装が必要であるにも関わらず、実のところ2012年3月現在IANAにはSOAPしか登録されていませんし、実装しているサーバーもありませんので、実質的に使えるものではありません。つまり、WebSocketを使って複数種類の命令を送信したい場合は、何かしらの決まりを自分で作ってあげなければならないのです。
    例えばこのデモでは
    • セッションを開始するconnectメッセージ
    • 他のユーザーの参加状態を知らせるconnectionメッセージ
    • テキストメッセージを送受信するmessageメッセージ
    • コネクションを切らせないためのheartbeatメッセージ
    • 誰が音楽を再生し始めたのか知らせるためのstart_musicメッセージ
    これだけの種類のメッセージを扱っています。ここに、「誰が送信したのか」「どんなメッセージを送信したのか」「誰が今コネクションを張っているのか」などの付随情報を追加する必要がありますので、JSONなどの構造化されたメッセージを送ることが必須であることは言うまでもありません。

    バイナリメッセージのやりとり

    オーディオデータを送信する際はバイナリメッセージを使います。最初甘く見ていたのですが、バイナリメッセージの送受信は、テキスト以上に一筋縄では行きません。WebSocketでメッセージの構造化が必要なのはテキストだけでなく、バイナリの場合でも同様なのです。実はWebSocketは、テキストメッセージとバイナリメッセージを混ぜて送信することができません。バイナリはバイナリ、テキストはテキストとして、別々に送信する必要があるのです。つまり、バイナリメッセージに何か付随情報を追加したい場合は、何かしらの工夫をする必要があります。
    このデモを作る際、実際にバイナリメッセージに付随させたかったのは
    • オーディオを再生したユーザーのID
    • オーディオのチャンネル数
    • オーディオのバッファ長
    • 実際のオーディオバッファ×チャンネル数分
    これだけの情報を他のクライアントに送り届けなければならないのです。
    WebSocketの持つシンプルなAPIの制約から、これを実現するための方法としてパッと思いつくのは3つしかありません。
    • テキストメッセージとバイナリメッセージを一組にして送る
    • クライアントごとに別々のWebSocketコネクションを張り、テキスト+バイナリを送る
    • 付随情報をバイナリに埋め込んで送る
    まずは一つ目。これはクライアントからサーバーに送るだけなら、アリな方法です。サーバーは仕様上、誰が繋いでいるのか把握できていますので、1つ目のテキストメッセージを受け取ってから次に届くべきバイナリメッセージを待ち受けることができます。しかし、サーバーがこれを受け取った順にそのままブロードキャストする場合、このままでうまくいくでしょうか?クライアントに他に誰が繋いでいるかを把握させることは可能ですが、ランダムに届く2つ一組の情報を、順番を入れ替えずにクライアント側でマッチングさせるのは、簡単ではありません。うまく工夫すれば不可能ではないですが、それではnode.jsのノンブロッキングという最大の特徴を犠牲にせざるを得なくなってしまいます。
    2つ目のクライアントごとに別々のWebSocketコネクションを張り、テキストとバイナリを送る、という方法は、上記の問題を解決します。コネクション自体がユーザーを表す付随情報として扱える上、メッセージの組み合わせを保証できます。ただ、繋いでいるユーザーが増えれば増えるほど、消費されるリソースは指数的に増えていきます。Multiplexing Extensionが使えるようになればこれも解決できるかもしれませんが、使えない現時点では、あまり良い選択肢とは言えません。
    そして3つ目が、バイナリ自体を操作して付随情報を埋め込むという方法です。このやり方であれば、ひとつのメッセージに実際のデータと必要な情報を組み合わせて送信できるため、バイナリ操作の実装は面倒ですが、その他の部分がだいぶ楽になります。今回のデモではこの方法を採りました。

    JavaScriptで扱えるバイナリ

    JavaScriptにおけるバイナリの操作は従来から不可能ではありませんでした。しかしそのために必要なテクニックは複雑で、実行速度も犠牲にしてしまいます。しかし最近登場したバイナリを扱ういくつかの仕様によって、それは格段に楽になりました。新しくJavaScriptで利用できるようになったバイナリには大きく2種類あります。それがBlobArrayBufferです。

    Blob

    Blobはバイナリの塊ですが、中身はいわゆるファイルと思って差し支えありません。FileオブジェクトはBlobから継承されたものですので、input[type=”file”]で入力されたファイルや、ドラッグドロップされたファイルなどはこれと同様に扱うことができます。FileReader APIを使うことで、ArrayBufferやData URLに変換することもできます。
    今回のデモではドラッグドロップした時点でBlobのファイルを、FileReaderのreadAsArrayBuffer関数を使ってArrayBuffer化するのに使っています。
        updatePlayer: function(file, callback, playEndCallback) {
          var that = this;
          var reader = new FileReader();
          reader.onload = function(e) {
            ac.decodeAudioData(e.target.result, function(buffer) {
              that.audioReady = true;
              if (that.audioPlayer) that.audioPlayer.stop();
              that.visualizer.disconnect();
              that.audioPlayer = new AudioPlayer(that.audioMerger);
              if (playEndCallback) that.audioPlayer.onPlayEnd = playEndCallback;
              that.audioPlayer.load(buffer, that.websocket);
              that.visualizer.connect(that.audioMerger, ac.destination);
              callback();
            }, function() {
              throw 'failed to load audio.';
            });
          };
          reader.readAsArrayBuffer(file);
        },

    ArrayBuffer

    ArrayBufferもバイナリの塊ですが、こちらは型付き配列(TypedArray)を使って、配列として扱うことができるのが特徴です。型付き配列はArrayBufferから符号なし整数(Uint8Array)や浮動小数点数(Float32Array)などいくつかの「ビュー」を使って切り出すことができます。Web Audio APIではオーディオデータがFloat32Arrayをバッファ長分、チャンネルごとに格納されるので、これを扱うことになります。
    JavaScriptのいわゆる配列(array)とは違い、ArrayBufferには任意のバイトを必要に応じて追加・削除する機能がありません。つまり最初に必要なメモリ領域を確保して、任意の値を埋めていくというアプローチを取らなければなりません。また、異なる型のTypedArrayをArrayBufferに当てはめていくのは、ちょっとコツが必要です。

    Web Audio APIからオーディオデータを引っこ抜く

    先ほどのBlobのサンプルコードではdecodeAudioData関数を使ってWeb Audio APIのAudioBufferオブジェクトに変換しました。AudioBufferオブジェクトは、Float32Arrayのバイナリとしてオーディオデータを扱います。しかしこのFloat32Arrayをそのまま送ったのでは、ストリーミングではなくただのアップロードとダウンロードと変わりありません。このデータを細切れに送信するにはどうすればいいのでしょう?
    幸いWeb Audio APIには、JavaScriptAudioNodeという便利なものがあります。これをルーティングの途中に挿入することで、任意のバッファ長ごとにonaudioprocessイベントを発生させ、通り過ぎようとしているデータを切り出すことができます。ここではこれを使いましょう(ちなみにWeb Audio APIを作っているChris Rogersによると、JavaScriptAudioNodeは非推奨で廃止したいとのこと。同様のニーズを満たす方法は未確認です)(2012/3/14追記:Chris Rogersに再度確認したところ、JavaScriptAudioNodeを廃止する予定はないとのことでした)。
        this.js.onaudioprocess = function(event) {
          var buffers = [];
          for (var i = 0; i < that.audioBuffer.length; i++) {
            buffers.push(that.audioBuffer[i].shift() || new Float32Array(BUFFER_LENGTH));
          }
          if (that.type == 'Player') {
            if (that.audioBuffer[0].length == 0) {
              that.stop();
            } else {
              var msg = AudioMessage.createMessage({
                user_id:UserManager.getUserId(),
                buffer_length:BUFFER_LENGTH,
                buffer_array:buffers
              });
              that.socket.send(msg.buffer);
            } 
          }
          for (var i = 0; i < buffers.length; i++) {
            event.outputBuffer.getChannelData(i).set(buffers[i]);
          }
        };
    バッファ長(BUFFER_LENGTH)は2048を指定しています。既存のオーディオファイルを再生したいだけの場合、AudioBufferSourceNodeを使うのが通例ですが、ここではJavaScriptAudioNodeにバッファを直接挿し込むアプローチを採っています。その際、ついでにWebSocketに送信する準備をしています。

    バイナリを操作する

    取り出した2048のFloat32Arrayは2チャンネル分ですので、これを他の情報と組み合わせてバイナリに固めます。
          createMessage: function(msg_obj) {
            var bl = msg_obj.buffer_length;
            var ch_num = msg_obj.buffer_array.length;
            var ab = new ArrayBuffer(4 + 1 + 4 + (bl * ch_num * 4));
            var view = new DataView(ab);
            var offset = 0;
            view.setUint32(offset, msg_obj.user_id);
            offset += 4;
            view.setUint8(offset, ch_num);
            offset += 1;
            view.setUint32(offset, bl);
            offset += 4;
            for (var i = 0; i < ch_num; i++) {
              for (var j = 0; j < bl; j++) {
                view.setFloat32(offset, msg_obj.buffer_array[i][j]);
                offset += 4;
              }
            }
            return new Uint8Array(view.buffer);
          },
    バイナリに複数の型を含めたい場合、DataViewを使います。これにより、JSONオブジェクトを元にして、何バイト目からこの型でこの値を埋める、といった指定が可能になります。これで複数のデータを埋め込んだバイナリができあがりましたので、そのままWebSocketに乗せて送ります。node.jsは単純に受け取ったものをブロードキャストするだけですので、受け取ったクライアントはこれをパースして音を鳴らすだけ、ということになります。詳細はソースコードを読んで下さい。

    WebSocketのバイナリメッセージが意味するもの

    ここまで読んできて、「うぉーめんどい!」と思った方、その通りだと思います。でもこういうものは、きっと近いうちにライブラリが解決してくれるでしょうし、プロトコルも整備されれば、使う側は何も考えなくても良くなるはずです。それこそ(まだTypedArrayに対応してませんが)JSON Schemaとか、Protocol Bufferなんかは、僕がまっさきに思いついた、これらの諸問題を解決してくれるものです。
    例えばnode.jsでは、Socket.IOというライブラリが既に存在しています。まだバイナリメッセージに対応していませんが、v1.0では対応すると表明していますし、時間の問題でしょう。そういったライブラリを使えば、ディベロッパーはどんなプロトコルで通信しているのかすら意識することなく、データのやり取りが可能になります。そして、今回僕が垣間見た未来はここに存在しています。
    今後インターネットでスピードを追求していく上で、WebSocketはなくてはならない存在になるでしょう。リアルタイムなサービスを作る必要がなくても使われるテクノロジーになります。理由は大きく2つ。WebSocketの持つオーバーヘッドの削減と、データの圧縮という特徴です。
    例えば頻繁に通信を要するサービスでWebSocketを使ってるとしたら、別途Ajaxを利用する意義は存在するでしょうか?以前Google API Expertの小松さんがWebSocketとAjaxの通信速度を比較する興味深い記事を公開されています。これを見るだけでも、WebSocketのコネクションがもうあるなら、わざわざAjaxを別途やるメリットないよね、と思うはずです。突き詰めていけば、サーバーが一度ウェブページをレンダリングしたら、あとはWebSocketでコネクションを張ってすべての通信を制御し、Ajaxは全く行わない、というアーキテクチャは割と早い段階で登場してくると思います。
    それからデータの圧縮。バイナリ化することで、テキストを送る場合と比べて送るデータ量を小さくできることは、疑う余地もありません。それに加えてこれから登場するWebSocket Deflate Extensionが加われば、さらに圧縮され、データは小さくなるでしょう。
    加えてこの記事でも検証した通り、バイナリーを送るためにはバイナリーに付随情報を追加する必要があります。だったら、別途テキストデータを送る意義ってなんでしょう?最初から全部バイナリーで送ることでスピードをアピールするライブラリが登場するのは時間の問題です。僕はインターネット上でWebSocketを使って流れるデータが、将来的に全部バイナリーになる可能性すらあるのではないかと思っています。

    まとめ

    少し大げさに言うと、これはウェブにおけるパラダイムシフトになり得ます。ウェブで使われるプロトコルがHTTPからWebSocketに乗る何かしらのプロトコルに置き換わる可能性は、全くないとは言い切れないのではないでしょうか。