らんきん5!に他サイト埋め込み機能をつけてみた
YouTubeとかでFlashサイトとかでEmbedタグとかを吐いてくれる感じのやつ。
らんきん5!の場合はHTMLコンテンツなんで、iframeで埋め込むんだろうなーということで、ひとまずiframeで埋め込むコードを書いてみた。
うーん、iframeのサイズを指定しないと不格好だ。
じゃあ、javascriptでiframeをリサイズしてみるか。
と思ったけど、iframe内のコンテンツにはクロスドメインアクセスの制限がかかるから、iframe内のjavascriptでコンテンツサイズを取得しても、iframeタグを持つ外側DOMとは直接やりとりできない(他サイト貼り付けだから、基本iframe内外は別ドメイン)。
iframeのスクロールバーの状態とか見て、スクロールが必要かどうかを取得して、そこからiframe内コンテンツのサイズを逆算してみようとか思ったんだけど、スクロールバーとかも基本はiframe内扱いっぽいね。
じゃあ、外側HTMLの方でjavascriptでiframeタグをはき出しつつ、サイズ情報を動的に追加すればいいんじゃないか、とか考えたんだけど、コンテンツ表示サイズ情報がiframe内にあるんだから、サイズ変更JavaScriptコードが内外どちらにあろうと、クロスドメインの壁を越える何らかの方法がないとどうともならないのね。
じゃあクロスドメインとは関係ない、サーバーAPIとしてコンテンツのサイズ情報を取得できるものを用意して、JSONPとかで情報を取得すればいいんじゃね。
と思ったけれども、よく考えたらHTMLコンテンツの表示サイズなんて、ブラウザ側の仕様・設定によって違ってくるから、サーバーサイドAPIとしてコンテンツ表示サイズなんて取得できるわけないよね。まあ雰囲気だけの情報なら取得できなくもないけどさ。
困ったなーと思ってググってみたところ、クロスドメイン通信できるwindow.postMessageというのがあるらしい。それを使ってiframe内の別ドメインから通知を受けて、iframe外でサイズ変更している例があった。
最初window.postMessageで送るデータは、javascriptオブジェクトにしていたんだけど、chrome、firefox、safariとかはそれでも通るのに、IE9だとstringしか通してくれなかったんで、JSONで送って受信側でobjectに戻すようにした。
あと、最初は$(document).readyでのみメッセージを通知していたけど、iframeをwidth: 100%で生成しているんで、ブラウザウィンドウのリサイズによって、HTMLコンテンツの表示サイズは変わりうるから、$(window).resizeでもメッセージ通知した方がいいんだよね。
ってことで、主要なブラウザではだいたい動くようになった。
貼り付けができるのは、質問と回答。たとえば、最近好きなマンガは?という質問ページに行くと、「貼り付け!」というボタンがあるのでそれをクリックすると、以下のような貼り付け用JavaScriptコードが表示される。
<script type="text/javascript" src="http://rankin5.com/js/embed.js"></script>
<script type="text/javascript">
// <![CDATA[
Rankin5EmbedInit('Rankin5EmbedQuestion4', 'http://rankin5.com/questions/4/embed');
// ]]>
</script>
このコードをHTMLとして埋め込むと、以下のように表示される。
回答の場合も同様に、「貼り付け!」ボタンを押すと、
<script type="text/javascript" src="http://rankin5.com/js/embed.js"></script>
<script type="text/javascript">
// <![CDATA[
Rankin5EmbedInit('Rankin5EmbedAnswer14', 'http://rankin5.com/answers/14/embed');
// ]]>
</script>
というコードが表示されるんで、それを貼り付けると以下のように表示される。
ここ数年、スパムまみれになった1470.netの惨状をメンテする気になれずに、個人でWebサービスを構築したりするのをほとんどやらないでいた。
その間いろんな新しい技術に対しては、一応ドキュメントなんかは眺めて、雰囲気はだいたいつかんでみてはいるものの、まじめに使ってみるようなことはほとんどせず、実際に自分の手を動かしたらいろんな発見があるものだよね、ってことをすっかり忘れてしまっていた。
今回のたったこれだけのことでも、実際に手を動かすとやっぱりいろいろと発見があるし、特にサンプルコードレベル以上の一通りの機能がそろったサイトを構築してみると、さらにいろんな発見があったりする。
やっぱりいろんな技術に対しては、何となくドキュメントをながめて理解した気分になるだけでなく、実際にそれを使ったミニサービスくらいは作ってみた方がいいね。
というわけで、らんきん5!にはここ数年の遅れを取り戻すために、思いついたことはいろいろ試して盛り込んでいくつもり。
らんきん5! のシステム構成
らんきん5! は永遠のベータ版なので、今後どんどん変わっていくかもしれないけれども、ひとまず現バージョンにおいての話。
サーバーはもともと利用していたさくらのVPS 512が3台。昔はさくらの専用サーバーを3台(10000円×3)借りていたことを考えると、さくらのVPS 512が3台(1000円×3)なんて安くなったものだなー。
ひとまずスモールスタートなので、さくらのVPS 512が1台で始めようと思っていたんだけど、どうせならばスケールアウトのテストもかねて無駄に3台使った構成から始めてみた。内容的には1台でも十分まかなえる。
WebサーバーはApache 2.2.3。スタティックドキュメント配信、アプリケーションサーバー、リバースプロキシー&ロードバランサーとして利用。3台とも同一構成で並べつつ、1台にはmod_proxy_balancerを入れて、そこでいったんリクエストを受け付けてからstickysessionで3台に回している。
サーバーサイドスクリプトエンジンはPHP 5.3.8/mod_php/APC。フレームワークはZend Framework 1.11.11。ごくごく標準的なZend FrameworkのWebアプリケーション構成にしてある。
クライアントサイドJavaScriptフレームワークはjQuery。PC版もモバイル版も同じ。最初モバイル版はjQuery Mobileで作ろうとしていろいろいじってみたんだけど、このサイトではあまり手間対効果のバランスが良くなかったんでやめた。現状のスマートフォン版はレイアウトHTMLを別物に差し替えて、CSSレベルで見た目を調整しているだけ。
DBサーバーはMySQL 5.5.17+mroonga。3台それぞれに同一構成でインストールしつつ、1台をマスター、残り2台をスレーブにしている。Zend_Db_Table/Zend_Db_Table_RowからDBアクセスを分散させる方法は、結構悩みどころだね。今回実装した方法がどのくらい使えるかはしばらく検証してみないと。
日本語全文検索エンジンは、最近はずっとtritonnを使ってきたんだけど、さすがにそろそろmroongaに乗り換えるべきだろうと、初めて使ってみた。ただ、最低限の日本語全文検索エンジンとしてしか使っていないんで、groongaらしい機能は全然触っていない。
memcachedを各サーバーに入れて、それぞれ用のセッションサーバーとして利用しているけれども、さくらのVPS 512だとメモリがもったいないんで、ファイルベースのセッションに戻しちゃうかも。
それぞれの詳しい内容については、またあとで。
らんきん5! を作りました
らんきん5! (http://rankin5.com) という新しい個人Webサービスを作りました。
どういうものかというと、ランキング形式でトップ5を回答するQ&Aサイトです。
Twitterアカウントでログインするだけで利用できます。特にユーザー登録は必要ありません。
上記URLからサイトに行き、興味がある質問を見つけたら「この質問に答える!」をクリックすると、自分の答えを登録することができます。
何か人に聞いてみたいことがある場合は、「質問する!」をクリックすると、新しい質問を登録することができます。
最初は1件しか質問できませんが、いくつかの質問に回答することでまた新しい質問を登録することができるようになります。
質問や回答には、Twitterへ投稿するためのリンクが用意されているので、そちらを利用してTwitterと連携させることができます。
スマートフォンから利用する場合は、右上辺りに「モバイル版」というリンクがあると思うので、それをクリックするとスマートフォン向け画面に切り替わります。
基本的な機能についてはだいたいできあがったので、興味を持った方は是非使ってみてください。
永遠のベータ版方式で、つかいながらいろいろ機能を増やしたり削ったりデザインを変えたりしていきたいと思っています。
今年の正月休みはどこにも出かけなかったので、その間に一気に作ってしまおうと思ったのですが、酒を飲んだり酒を飲んだり酒を飲んだりしてしまったため、結局休み明けまで引っ張ってしまいました。
多言語(英語と日本語)対応にしてみたり、スマートフォン対応にしてみたり、非同期更新+UIアニメーションを使ってみたり、いろいろいまどきっぽく作ってみました。
動作環境を構築するために、1470.netをだましだまし動かしていたサーバーの各種モジュールをいろいろアップデートしたところ、古いライブラリ(主にZend Frameworkの初期バージョン+オレオレ拡張)をだましきれなくなってしまい、Webアプリ側が動かなくなってしまったため、1470.netフロントエンドは閉鎖してしまいました。バックエンドとデータは生きているので、新着URL情報などは一応Twitterに流し続けています。
といった感じで、よろしくお願いします。