読者です 読者をやめる 読者になる 読者になる

しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

Visual Studio 2013 の新機能、ブラウザーリンクの仕組みを調べてみた

Build 2013 2 日目のキーノートで Scott Hanselman 氏が One ASP.NET 絡みのデモを行っていた中で、Visual Studio 2013 で追加されたブラウザーリンクという機能が、内部的に SignalR を使っていると言っていたので調べてみました。

その前にブラウザーリンクの機能をさらっと紹介。と言っても、キーノートで Scott Hanselman 氏が行っていたデモが素晴らしいので、そっちを参照する方が良いです。

15 分ぐらいから Hanselman 氏が登場します。デモのクオリティが高く、ライブコーディングなのに非常にスピーディーです。見習わないと。

簡単に説明しておくと、Visual Studio 2013 のツールバーにある以下のボタンです。

f:id:shiba-yan:20130629191027p:plain

このボタンを押すと、複数のブラウザーでプレビューしていても、一発でビューの更新などを反映できる優れものです。ブラウザーごとにどのページを見ているかも分かるのは面白いですね。

SignalR を使って作られているという話だったので、出力された HTML ソースを調べてみました。すると、ビューの最後に以下のような script タグを発見しました。

</body>
<script type="text/javascript">window.__vwd_mapping_data={"map":[{"sourceFile":"~/Views/_ViewStart.cshtml"},{"sourceFile":"~/Views/Home/Index.cshtml"},{"sourceFile":"~/Views/Shared/_Layout.cshtml"}]};</script>
<!-- Visual Studio Browser Link -->
<script type="text/javascript" src="/__vwd/js/artery"></script>
<!-- End Browser Link -->
</html>

__vwd は Visual Web Developer の略ですかねぇ。artery は動脈とか幹線と言う意味のようですが、おそらくこれはコードネームでしょう。

参照されている JavaScript を調べてみると、JSON2 や jQuery 1.8.2、SignalR 2.0.0 beta 1 の minify されたコードと、当然ですが artery の実装が含まれていました。

エントリポイント

あえて Hub API を使わずに PersistentConnection を使って実装が行われています。オーバーヘッド低いですし、Hub のような高度な機能が必要ない内部 API なので妥当ですね。

ちなみにセルフホストで実装されていて、PersistentConnection のエンドポイントは以下のようなフォーマットになっています。

http://localhost:1891/7fe74f1cd0b542a4a1ac89ca462323ca|

パスの部分はプロジェクトによって変わるのかは未検証ですが、おそらく変わるでしょう。

メッセージのフォーマット

JSON としてペイロードに格納されているデータは以下のキーと値を取ります。

msg navigate か refresh のみ
href navigate の場合、遷移先 URL がセットされる

つまり、ツールバーのブラウザーリンクボタンが押された時には refresh を使って、ページを強制的に GET で再読み込みするようにしているみたいですね。

サーバへの通知

ブラウザーリンクボタンのツールチップには、各ブラウザで表示しているビューのパスが表示されていますが、これは SignalR コネクションが確立されたタイミングで、サーバ側へ通知を行っています。

_vwd_mapping_data という値は、このために埋め込まれています。

まとめ

今回、Visual Studio 2013 のブラウザーリンクという機能で、SignalR の具体的な利用例と内部 API としての使う上のアドバンテージを証明してくれたと考えています。

PersistentConnection は使いどころが分からないという意見もちょいちょい見ますが、オーバーヘッドとどのくらい高度な機能を使うかで決めることが最適だと思います。ブラウザーリンクのように内部 API として完結させてしまう場合には、十分選択する理由となると思います。

ちなみに、セルフホストを使っているということは、きっと OWIN 使ってるんでしょうね。