Author Archive

    はてなブックマーク - Node.js(Socket.IO)を使ってzenpreのリアルタイム配信基盤を作る
    このエントリーをはてなブックマークに追加

    zenpreチームの小山です。
    昨日食べた先輩のカレーがとてもおいしかったです。量が少なかったので次回大盛りを希望しました。

    zenpreリニューアル!!

    “ZENPRE”は6月11日に”zenpre”としてリニューアルしました。
    主な改善内容はリリース文章にお任せするとして、
    今回は技術的な側面から紹介できればと思います。

    大文字から小文字になっただけではないのです。

    リアルタイムプレゼンテーション配信を支える技術の刷新

    zenpreは「リアルタイムなプレゼンテーション配信」と「プレゼンテーションの共有(スライド+動画のコンテンツ作成)」の2つを軸にしてサービスを提供していますが、
    この「リアルタイムなプレゼンテーション配信」、つまり

    スピーカーがスライドを切り替えたら、同時に他の視聴者の画面のスライドも切り替わる

    という機能は、当然ながらブラウザ間のリアルタイム連携がポイントになってきます。

    ZENPREではこの部分は元々Rubyで書かれていたのですが、今回のリニューアルを機に全てNode.js(Socket.IO)で書き換えました。

    なぜわざわざNode.jsで書き換えたのか?

    実は「ベンチマーク結果でNode.jsのほうがずばぬけて優秀だった」とか、「Rubyでの実装に問題があった」とかいう皆さんが期待するような理由は、実はありません。

    強いてあげるとすれば、「zenpreをただリニューアルするのではなく、新規技術採用の起点としたい」というのと「JavaScriptがチームの共通言語だったから」というのが一番大きいです。

    現在は私がメインで開発していますが、近い日にチーム全体で改良を加えられる体制を目指しています。

    また、以前はZENPREではプレゼンテーションのプレイヤーをFlash(スライド+USTREAM)で構築していましたが、
    今回のリニューアルで、機能に占めるFlashの割合を小さくしました。
    その際に代わりに割合が大きくなったのがJavaScriptで、Nodeは当然ながら(ブラウザ上の)JavaScriptと親和性が高かったというのもあります。

    同期通信は、ZENPREではRuby<->Flash(スライド+USTREAM)で行っていたところを、zenpreではNode.js<->JavaScript(連系用ライブラリ)<->JavaScript(スライド)+Flash(USTREAM)という形で作り変えています。

    リアルタイム同期機能の別アプリケーション化

    Node.js(Socket.IO)のサンプルアプリケーションでは、よく「チャットアプリケーション」がありますが、zenpre自体のNodeの利用方法もそれと大差ありません。

    スケールの方法についても一応方策にあたりをつけていますが、現在は1プロセスで十分機能しています。

    一つ特殊なことをしているとすれば、「リアルタイム同期機能」自体を別アプリケーションとして構築しているということです(つまり、Node.jsでは全く特殊ことはしていないということですね)。

    もっと言うと、

    zenpreはリアルタイム同期機能を自身で持っておらず、別のサービスと契約して実現している

    ということを社内でしているイメージです。

    その別アプリケーションは、今は”Sync.IO“という名前でよんでいます。

    なぜわざわざ別アプリケーションにしたのか?⇒Webアプリケーションに求められる要望の多様化に備えてみた

    プログラムでは、よく「汎用的に使うものはライブラリ化して分離する」ことがありますが、そのアプリケーション版の考え方です。(「汎用的に使うものはアプリケーション化して分離する」)

    弊社では受託開発も多くやらせていただいていますが、

    Webアプリケーション(社内業務システムなど)だけで考えても、

    クライアントから求められていたり、逆にこちらからアピールする価値は
    「ブラウザから操作できますよ」という初期の単純なものから、

    • 帳票も出力できます(Excel、PDF連携)
    • 画面遷移をせずに登録できます(Ajax)
    • 1日に一度統計を表示します(グラフ、バッチ処理)
    • サーバの負荷に応じてスケールアウトします(AWS)
    • データはクラウド上に保存しまう(AWS)

    など、どんどん変わってきています。

    そして、「リアルタイムに複数ブラウザで連携する」という機能が、今後、

    「『普通の』Webアプリケーションに求められることもあるのではないか?」

    と考えて、汎用的に利用できるリアルタイム連携の基盤としてSync.IOを作ってみた、という感じです。

    Sync.IOは何ができるのか?

    Sync.IOに似ている(?)サービスとしては、例えばFirebaseなどがありますが、Sync.IOはもっともっとシンプルです(そこまで機能がないとも言えます。)。

    Sync.IOが提供している機能は2つだけです。

    • Socket.IOによるブラウザ間のリアルタイム連携の基盤
    • 連携ログの保持

    チャットアプリケーションを例にとると、
    「チャットができる」「閉じたチャットルームを作ることができる」「権限のある人だけチャットで全員に発言できるように制限できる」「チャットのログをとれる」というような機能の基盤をSync.IOは提供します。

    もし、1からPHPでチャットアプリケーションを作りたいときは、

    • チャットアプリケーション自身のユーザ認証基盤の作成(PHP)
    • 認証されたユーザだけが見れるチャットページの作成(PHP)
    • Sync.IOへアプリケーション登録
    • Sync.IOのAPIと連携するサーバサイド(PHP)
    • Sync.IOのSocket.IOと連携するJavaScript部分

    だけ(?)で「リアルタイムチャット機能」が作れます。リアルタイムなNodeアプリケーションの構築も、クローズドなチャットルームの実現方法も、連携ログの保持方法も考える必要がないですね。

    ちなみに社内技術発表のときの資料にSync.IOの仕組みが少し載っていますので、よろしければご覧ください。

    Sync.IOの今後

    Sync.IOは今のところzenpreのバックエンドという立ち位置で、それで十分なのですが、実は今すぐにでも他のアプリケーションで利用できます。
    (ユーザ登録やFacebookのようにアプリケーション登録の仕組みも既に持っています。zenpreもただの1アプリケーションとして登録されています)

    まずは、zenpreでない他のアプケーションに組み込む機会を得て、zenpreだけではわからないSync.IOの課題点を探ってみたいと思います。

    まとめ

    zenpreがリニューアルしました!

    是非使ってみてご意見ご感想をいただければと思います!

      はてなブックマーク - CSVファイル変換サービス「CSVHub」をリリースしました
      このエントリーをはてなブックマークに追加

      最近、screenから無事tmuxに切り替えた小山です。
      「Ubuntu > terminal > screen > Emacs」で一部文字崩れを起こしていたのが解消されて、ストレスフリーになりました。

      本日、CSVファイル変換サービス「CSVHub」をリリースしましたので、少し紹介させてもらいたいと思います。
      (ニュースリリース)

      CSVHubとは

      CSVHubは、その名に「CSV」を冠しているように、CSVを変換するサービスです。本当にそれだけのサービスです。

      よくでてくるCSV

      弊社では、受託案件や自社サービスも含め、CSVを出力したり取り込んだりする機能をつくることが多くあります。
      それだけ、「業務システム」にCSVという形式が使われているということなのでしょう。

      そのような中でお客様のご要望として、よくいただく声の一つに「CSVファイルを変換したい」というものがあります。

      その内容は「本当にちょっとしたこと」で、

      • 「CSVの列の順番を入れ替えたい」とか
      • 「セルとセルを足し合わせたい」とか
      • 「値の桁揃えをしたい」とか
      • 「先頭に固定文字を付与したい」とか
      • 「1行で1セットのデータを2行で1データにしたい」とか

      本当に「ちょっとしたこと」です。
      ただこれは、
      プログラマにとっては「ちょっとしたこと」なのですが、普通のお客様にとっては「ちょっとしたこと」ではありません

      Excelを使うことができればなんとかできるかもしれません。
      ただ、「あとちょっとでできない」ということもあるかもしれません。
      CSVの操作は基本的にお客様にやさしくないのかもしれません。

      CSVをプログラマでない人にも

      CSVHubは、

      「プログラマの手を煩わせずにCSVを操作できないのだろうか」

      そう思ってプロトタイプ的に作成したWebサービスです。
      (名前の由来は『「あるCSV」から「自分の欲しいCSV」へのハブ(Hub)となるサービス』というイメージです)

      CSVHubでできること/利用方法

      CSVHubでは、例えば以下のようなことができます。

      • セルの入れ替え/削除
      • セルとセルの四則演算/文字列結合
      • パディング
      • 桁揃え
      • 半角全角変換
      • 四捨五入/切り捨て/切り上げ
      • 列追加

      など。

      利用方法はたった3ステップだけです。

      • 1. CSVファイルをアップロードします。
      • 2. セルの並び替えや変換を、マウス操作で設定します。
      • 3. 最後に、ダウンロードするだけです。

      これだけです。

      セルの入れ替えなどはマウスで直感的にできますし、その他の操作も基本的に「新しいセル」を追加するときに考えればOKです。

      CSVHubのこれから

      リリースしたばかりのCSVHubですが、(社内リリースした時点で)既にいろいろ要望や課題が上がっています。
      例えば、

      • 変換設定を保存したい
      • 「個人情報を含むCSV」に対応できるようにセキュアな環境で提供できるようにしたい
      • APIを提供したい
      • もっと込み入った変換をしたい
      • もっとわかりやすいようにしたい

      などです。

      CSVHubは、ちょっとしたアイデアを実現しただけの簡単なWebサービスです。

      簡単なWebサービスですが、CSVHubを通してCSVの操作が「プログラマでない人」にも簡単にできるようになれば幸いです。

        はてなブックマーク - Filebinder pluginの今 #cakeadvent2012 Day25
        このエントリーをはてなブックマークに追加

        CakePHP Advent Calendar 2012 25日目の記事です。

        24日は@takahashiyuyaさんの「Cakephp h()メソッドから php を学ぶ」です。

        h()が意外に配列にも対応しているというのはソースを見ないと気づかないですよね。

        さて、ラストは今年のPHPMatsuriで「変態」と言われ続けたFusicよりお送りいたします。

        非常に心外ですので、
        本エントリで「Fusicは変態」という汚名を払拭したいと思います。

        Filebinder Pluginとは

        弊社がGitHubリポジトリで提供しているCakePHP Pluginに「Filebinder」というものがあります。

        fusic/filebinder

        簡単にいうとCakePHPのファイルアップロード機能を簡単に実装するためのプラグインです。

        最初のリリースはCakePHP1.3の頃で、そこから継続的にメンテナンスしています。
        現在はmasterブランチではなく2.0ブランチのみの開発を続けていますので、そのうちブランチ名を切り替えるかもしれません。

        弊社では未だにデファクトのライブラリなのですが、一部では「過去のライブラリ」となってしまっていそうなので、そうならないように「あれからFilebinderはどうなっているのか」について紹介したいと思います。

        CakePHP2.x対応

        弊社では現在CakePHPの主流は2.x系です。

        意外に知られていませんが、FilebinderもCakePHP2.x対応をしています(2.0ブランチ)。
        ブランチ名については後悔しています。。

        使い勝手も変えていませんので是非確認してみてください。

        UnitテストをTravis CIで管理

        弊社では良く使う重要なライブラリですので、少ないですが必要最低限のテストを書いています。

        最初は、開発者である私の環境でテストを回した後にpushをしていたのですが、
        ふと思うことがあってTravis CIの力を借りてテストを回しています

        README.mdにグリーンアイコンがでるのは、使う側としても安心ですよね。

        1.3系2.x系両方でTravis CIを回しているので、CakePHP PluginのテストをTravis CIに任せてみたい人には参考になるかもしれません。

        AmazonS3に対応

        おそらく、かつてから最も変わった部分ではないでしょうか。

        弊社にもご多分に漏れずAWSな波がきておりまして、FilebinderもAmazonS3に対応させていたりします。

        簡単にいうと、ファイルをアップロードするとS3に(も)転送する機能が簡単な設定だけで利用できます(Amazonから提供されているSDKを利用しています)。
        データベースと同様に、S3のデータからローカルのデータを復活させるようなことも可能です。

        README.mdに書くのをサボっていたので(ちょっと書きました)、テストケースを読むような人でない限り気づかなかったとは思いますが、便利です。S3に保存できると安心感が違います。

        現在開発中のzenpreでもスライドデータなどをS3、さらにはCloudFrontに任せることで負荷を軽減させています。

        実はCDP:Rename Distributionパターンを構築しやすい

        Filebinderはファイルの保存先をModel::transferTo()を上書きすることで変更できるのですが、それを活用してCDP:Rename Distributionパターン(リンク参照)をものすごく容易に実装できます。

        例えば以下のようにすれば、タイムスタンプごとにディレクトリを切ってファイルを保存できます。

        /**
        * transferTo
        * Filebinder BindableBehavior::transferToをオーバーライド
        * CDP:Rename Distributionパターン
        *
        * @param $data
        */
        public function transferTo($data){
        $time = preg_replace('/[\s:-]/','', $data['modified']);
        return $this->alias . DS . $data['model_id'] . DS . $time . DS . $data['field_name'] . DS . $data['file_name'];
        }

        Filebinderの機能でそのままS3にアップロードし、CloudFrontと連携させればもう完成です。楽ですね。
        上記機能は実は弊社ではなく、@jyokyokuさんが追加した実装です。OSSの醍醐味ですね。この場をかりてお礼を言いたいと思います。ありがとうございます!

        というわけで

        「Filebinder pluginの今」の紹介でした。慣れれば使いやすく拡張しやすいと思いますので、是非使ってみてください。

        Fusicの汚名も無事払拭できたかと思います。

        CakePHP Advent Calendar 2012も無事完走いたしました(誰かが走り続ける可能性もありますが)。皆さんお疲れ様でした。

        あ、4回目です。すみません。