アーカイブ

VSCodeの画面をリアルタイムで共有できるサービスを作りました #vsshare

この記事はVisual Studio / Visual Studio Code Advent Calendar 2015の21日目の記事です。
12月20日担当のたなかさんの記事はこちらです。


いよいよAdvent Calendar最後の週に入りましたね。今年も多くのご参加ありがとうございます!

VSShare β

さて去年の私は、VS Advent Calendarでこんな記事を公開しました。

というわけで、今年はVisual Studio Codeにも対応した、マルチセッション可能な『リアルタイムコード共有サービス』を作りました。名前はVSShare βです。

さらに、この度、VSShare関連のすべてのソースコードをオープンソースとして公開しました。ソースコードはすべてGitHub上で管理しています。リポジトリなどはこちらからどうぞ

言葉だけだとわかりにくいと思いますので、実際に動作させた時のGIF画像を置いておきます。

  • 配信の様子
    配信の様子
  • マルチセッションの様子
    マルチセッションの様子

何ができるの

VSShareでできることを簡単にまとめておきます。

  • エディタが表示しているコードをリアルタイムに共有
    • コードを変更したら、もちろんすぐに変更が反映されます。
  • 現在のカーソル位置もリアルタイムに共有
    • カーソル追従ON/OFFも指定可能になりました。
  • マルチセッション対応
    • 複数のユーザーが1つのルームで同時にセッションを行うことが可能となりました。
  • 様々なエディタに対応
    • 今回、Visual Studioだけでなく、Visual Studio Codeとシェル画面の共有に対応しました。

今回、実装が間に合わなかったので、VSCode向けの拡張機能のみをリリースしています。Visual Studioとシェル向けの拡張機能のリリースは、もうしばらくお待ちください。
ちなみに、シェル画面の共有にはtmuxのpipe-paneあたりを使って実現しようかな、と考えています。試しに実装してみたものを置いておきます。

また、プロトコルを大きく変更したので、以前まで公開していたVSShareのVisual Studio向け拡張機能とは互換性がありませんので、ご注意ください。

何に使えるの

主に勉強会でのライブコーディングや小規模のペアプロなどで使えると考えています。

今回のリリースでカーソル追従機能を追加したので、『コードがどうなっているか』だけでなく『開発者がどんな操作をしているのか』がより分かりやすくなったかと思います。
またマルチセッションにも対応したので、例えば複数のコードをよく行き来する作業や、複数のユーザーによる同時配信がやりやすくなっています。
ライブコーディングバトルなどのお供にもいかがでしょうか。

どうやって実現してるの

原理は非常に単純で、エディタの拡張機能などを利用して各種データを取得し、SignalRを用いてサーバーと通信を行っています。 これによってサーバー側が受信したものを、別のSignalRのハブを用いてWebクライアントに配信しています。

SignalRは、非同期でクライアントとサーバーとが双方向通信を行うためのライブラリです。 配信の方法として、WebSocketだけでなくロングポーリングなどにも対応していますので、WebSocketに対応していない環境でも利用することができます。

また、去年リリースしたVSShareでは、拡張機能側でシンタックスハイライトなどの装飾情報を取得し、これらの情報をすべて含めてサーバーへ送信していましたが、VSShareβからはテキストと一部の装飾情報のみを送信するように変更しました。この理由は、キーワードに対する装飾情報を含めるとメッセージのサイズが大きくなりすぎて、SignalRでやり取りできるメッセージサイズの問題(maximum message size · Issue #1205 · SignalR/SignalR)にあたってしまうことや、VSCodeでキーワードに対する装飾情報を取得するAPIがないことが関係しています。

その代わり、クライアントサイドにAceを採用して、シンタックスハイライトや高機能な検索を提供しています。この辺りは、今回一緒にプロジェクトを進めてくれた@oboenikuiさんが、かなり頑張って実装してくれました。ありがとうございます。

どうやって使うの

今回はちゃんとドキュメントを用意しました。以下のリンクからどうぞ。

Visual Studio Code向けの拡張機能を作るときのポイント

VSShareのVSCode向け拡張機能を作るときに、いくつかハマったポイントがあったのでまとめておきます。参考になれば幸いです。(大したことは書いてないです)

コマンドの定義方法

本家のページにちゃんと書いてあります。Visual Studio Code API Reference
Visual Studio Advent Calendarでも、こちらの記事が非常に良くまとまってて分かりやすいです。

Visual Studio Codeのコマンドパレットから呼び出せるコマンドを定義するには、まずpackage.jsonにコマンド情報を定義します。VSShareはこんな感じです(抜粋)

あとは、ソース側でvscodeのcommandsをimportして、registerCommandメソッドを呼び出してあげます。

VSShareではEventEmitterを使っていたりしますが、基本的にやっている内容は同じです。

User Settings(コンフィギュレーション)の定義・読み込み方法

コマンドと同様に、package.jsonにコンフィギュレーション情報を定義します。各プロパティ名と、その説明、型、デフォルト値を定義する感じです。VSShareの例を示します。

すると、この拡張機能が有効になっているVisual Studio CodeのDefault Settingsには、以下の図のように定義した説明とデフォルト値を含むテンプレートが生成されています。

User Settingsの画面。Default Settingsがカスタマイズされている。

User Settingsの画面。Default Settingsがカスタマイズされている。

あとは、ソース側から定義したコンフィギュレーションを必要なときにロードしてあげます。

専用の出力パネルを作成する

タスクランナーの出力ウインドウみたいなのが簡単に作れます。

終わりに

Visual Studio Code向けの拡張機能、かなり作りやすいです。VSに比べると拡張機能で取得できる情報は限られますが、APIの見通しがよく、今回の拡張機能も簡単に作ることができました。

拡張機能のソースコードはVSShare / Extension-Codeで公開しておりますので、新しく拡張機能を作るときに何かの参考になれば幸いです。最後の方に大分突貫工事をしたので、汚い部分が多々ありますが、時間を見つけてリファクタリングしていこうと思います。

以上、Visual Studio / Visual Studio Code Advent Calendar 2015の21日目の記事でした!是非VSShareをよろしくお願いします!
(記事の質が低くて申し訳ございません!)