2011年11月アーカイブ

この前作ったDTPの勉強会ツイートライブ実況専用サイトは、結果的にHTML5時代の材料でスマートフォン用のアプリケーションサイトを作ることになったのでした。

僕がいろいろ作っているのは、誰かにもっといいものを作ってほしいからですので、今回作った時の経験を記録として書いておけば、誰か真似して、もしくはさらにいいものを作ってくれることもあろうかと思います。

Webappmaking

昨日、近所の飲み屋行ったんです。飲み屋。
そしたらなんか子供がめちゃくちゃいっぱいでうるさいんです。
なんか親子連れとかもいるし。一家4人で忘年会か。おめでてーな。

ていうわけで、親どもは一生懸命飲むのに精が出て子供がほっぽり出しになっていたので、
お前らな、iPadで太鼓の達人やるからその席に落ち着けと。

ていうわけで子供たちは太鼓打ちに精を出すようになりました。

iPadで太鼓の達人やらせるには、事前に、アクセシビリティのズーム機能はOffにしておくことが必要ですね。太鼓の達人での連打がトリプルタッチに解釈されていきなり画面がズームします。

つうわけで、iPadに太鼓の達人入れとけば見ず知らずの子供をあやせるよ、ていうお話でしたとさ。

技評から出ている「WEB+DB PRESS総集編Vol.1~60」を買ったよ。

昔は本屋でWEB+DB PRESSを手にとって役立ちそうな記事があったら買ってたのだけれども、最近はあまり本屋に行くことも少なくなってきていたので、何が載っているか分かんない状態だったのですけれども、今ちょうどPerlでAnyEvent使っていろいろやっている関係で、過去にWEB+DB PRESSでAnyEventの特集があったらしいで、ということを知ったので買ってみたよ。

こうやって再録版が簡単に出せるってことは著者さんとの契約がそれがしやすいようになっているんだろうなーとか思いました。

AnyEvent::Twitter::Streamの再接続の件をずうっと考えていたのですが、当初参考にしていた、

hidekiy blog: [perl] AnyEvent::Twitter::Streamで自動再接続処理 [blog.hidekiy.com]

のとおりにすると、通常のAnyEventでの組み方の時はよさそうなのですが、Mojoliciousと同時に使用するなど、イベントループを共有する場合は、while(1){} のせいで、Mojoliciousのイベントループ開始までプログラムが進行できず、かといって、AnyEvent::Twitter::Streamの再接続の処理をMojoliciousに担当させるというのは難しそうなので、ここは、「Twitterのウォッチャー」と、「〔Twitteのウォッチャー〕のウォッチャー」の二つのウォッチャーを作り、お互いにウォッチャーの再生成をさせることで、結果的にAnyEvent::Twitter::Streamの再接続が実現できるようにしてみました。

今動かしているMojolicious::LiteでWebSocketでクライアントに表示するやつなんですけれども、Mojoliciousのバージョン1/2の両用で動くようにしていたのですが、本番のMojolicious 2の環境では、WebSocketクローズのイベントが取得できない状態になっていました。よって、こんな感じにしてみました。

  # WebSocketコネクション切断時処理(共通)
  my $on_finish = sub {
    # ログに切断記録
    app->log->debug('Client disconnected');
    # $clientsからWebSocketクライアントを削除
    delete $clients->{$id};
  };
  
  # WebSocketイベント設定
  if ( $Mojolicious::VERSION < qv("v2.0") ) {
    # Mojolicious 1.xの時の処理
    $self->on_message();
    $self->on_finish( $on_finish );
  }
  else {
    # Mojolicious 2.xの時の処理
    $self->on(
      message => sub {},
    );
    $self->on(
      frame => sub {
        my ($ws, $frame) = @_;
        if ( $frame->[1] == 8 ) { # opcode=8: close
          $on_finish->();
        }
      },
    );
  }

これを見ると、どうも frame-opcode = 9(ping)、frame-opcode=10(pong)も$ws->on(frame=>sub{}); の中で対応しなくちゃいけないのかなーとか思っていますが、調べ中……

ここを参考にした:
WebSocket(hybi-07)でechoサーバを作ってみた - いろいろな何か [d.hatena.ne.jp]

昨日公開したサイトでは、公開直前まで昨日ボタンをspan要素で作っていたのですが、span要素でボタン作るとなんだかヤバそうな感じの書き込みをどっかで見たのですぐに、button要素に書き換えたのですけれども、button要素をspan要素のように見せなくてはならないわけです。

で、CSSで、border: 0px; background-color: transparent; を指定すると、ボタンのデフォルトスタイルの灰色の部分が消える、というものなのですけれども、

Android版Firefox 8だと、まだグラデーション状の色がbutton要素に付いているのです。

Android版Firefox 8だと、更に、background-image: none; を指定しないといかんのです。ボタンのあの立体感を出すグラデ、画像だったのかよ! とか、ビックリしましたとさ。

HTML5アプリって難しいですね......

2011年11月26日のDTPの勉強会第5回に参加できないので、その勉強会に参加した人のツイートを表示できるウェブサイトを作りました。

ネーミング決めてないのと、勉強会終わってから1週間ぐらいでサブドメイン消すつもりなので、URLでどうぞ。

http://20111126.dtpwiki.jp/

Dtpstudyrealtime2
▲Windows版Google Chrome 15での表示

Dtpstudyrealtime
▲Android版Mozilla Firefox 8での表示

何をするサイトなの?

  • DTPの勉強会#5が開催される前後1週間ぐらいで、Twitterにて「dtpstudy」「dtpstudy05」を含む発言をした日本語設定のユーザーのツイートを記録します。
  • サイトにつなぐと、WebSocketをサポートしている特定のブラウザであれば、リアルタイムに発言が表示されます(従来のウェブサイトだとちょっと難しかったところです)。

どういう仕組みなの?

  • Amazonのサーバを借りて、そこでTwitterの発言を監視し、記録するとともにリアルタイムに配信するサーバと、記録された発言を配信するするサーバが動いています。
  • Twitterの発言を監視するものは、「dtpstudy」「dtpstudy05」を含むツイートがあると、DBに記録すると同時に、その時にサイトに接続されているブラウザにツイート内容を配信します。
  • 閲覧ユーザーのブラウザには、サーバーに記録されたツイートと、リアルタイムに発言されたツイートが表示されます。
  • 閲覧ユーザーのTwitterアカウント情報は一切使用しません(開発者のアカウント情報で取得して、ほかの方に見せているという状態です)。
  • 閲覧ユーザーの情報は、Google Analyticsで取得できる情報以上のものは取得いたしません。

動作確認ブラウザ

  • Mozilla Firefox 7以上
  • Google Chrome 14以上

警告を無視すれば、非対応ブラウザでも過去ログ表示だけはできるんじゃないかな……?

想定される質問と回答


このサイトからツイートできないの?

閲覧者のTwitterアカウント情報を使わない設計なので……

iPhoneに対応しないの?

申し訳ありません。Safariに対応できませんでした。

なんか裏技ないの?

キーボードショートカットがいくつかあります。

主催者にコンタクトとった?

連絡済みですー

クソ使いにくい。

Twitterでフィードバック求めていたときに言ってくだされば……

なんで期間限定なの?

Amazon EC2はタイムフィー制なので、いつまでも稼働させておくと僕のお財布が軽くなるからです。

         し!     _  -── ‐-   、  , -─-、 -‐─_ノ
  小 学    // ̄> ´  ̄    ̄  `ヽ  Y  ,  ´     )   学 え
  学 参    L_ /                /        ヽ  参  |
  生 が    / '                '           i  !? マ
  ま 許    /                 /           く    ジ
  で さ    l           ,ィ/!    /    /l/!,l     /厶,
  だ れ   i   ,.lrH‐|'|     /‐!-Lハ_  l    /-!'|/l   /`'メ、_iヽ
  よ る   l  | |_|_|_|/|    / /__!__ |/!トi   i/-- 、 レ!/   / ,-- レ、⌒Y⌒ヽ
  ね の   _ゝ|/'/⌒ヽ ヽト、|/ '/ ̄`ヾ 、ヽト、N'/⌒ヾ      ,イ ̄`ヾ,ノ!
   l は  「  l ′ 「1       /てヽ′| | |  「L!     ' i'ひ}   リ
        ヽ  | ヽ__U,      、ヽ シノ ノ! ! |ヽ_、ソ,      ヾシ _ノ _ノ
-┐    ,√   !            ̄   リ l   !  ̄        ̄   7/
  レ'⌒ヽ/ !    |   〈       _人__人ノ_  i  く            //!
人_,、ノL_,iノ!  /! ヽ   r─‐- 、   「      L_ヽ   r─‐- 、   u  ノ/
      /  / lト、 \ ヽ, -‐┤  ノ  キ    了\  ヽ, -‐┤     //
ハ キ  {  /   ヽ,ト、ヽ/!`hノ  )  モ    |/! 「ヽ, `ー /)   _ ‐'
ハ ャ   ヽ/   r-、‐' // / |-‐ く    |     > / / `'//-‐、    /
ハ ハ    > /\\// / /ヽ_  !   イ    (  / / //  / `ァ-‐ '
ハ ハ   / /!   ヽ    レ'/ ノ        >  ' ∠  -‐  ̄ノヽ   /
       {  i l    !    /  フ       /     -‐ / ̄/〉 〈 \ /!

今日やらかしてしまったのですが、とある診断サービスを運営していて、ファイルをアップロードする必要があり、アップロードの進捗をブラウザに伝える必要があったものでアップロードファイルのテンポラリディレクトリを/tmpから別のディレクトリに変更している状況で、更にテンポラリディレクトリを消していない状況だったのですが、この度めでたくテンポラリディレクトリが31998個になり、アップロードに失敗するようになっていました。

ext3ファイルシステムは、そんなに古くはないファイルシステムなのに、1ディレクトリ内のディレクトリエントリが32000エントリ(内、.と..で2つ消費するので、意味のあるエントリは31998エントリ)になると、それ以上ファイルやディレクトリが作れなくなるのでした。

早くext4ファイルシステムが使いたーい!(テンポラリ消せよ)

ネットの噂によると、数年前にある活動家がIE6を破壊しようとしたそうです。でもその活動家がどうなったのか誰も知りません。

(略)

今日、J君から、<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">のメタタグをもらった。

なんでも、ブラウザにIEを使っていても、Google Chromeを使ったレンダリングをするプラグイン、Google Chrome Frameに、「動いてもいい」と指示を出すメタタグらしい。

Google Chrome Frame: サイト管理者向けガイド - terkel.jp [terkel.jp]

メガシ屋では見たことのないメタタグだったけど、巷では出回っているみたい。ネットの海は広大だわ。

(電脳コイル風のつもりが攻殻機動隊になってしもた……)

まだまだTwitter Streaming APIをWebSocketでリアルタイムで流すサイトを作っているのですが、過去の分もDBに記録されている分を表示するようにしているため、WebSocket接続時に過去分を送信するようにしていましたが、ここをAJAXに置き換えればいいと思って、今日実装してみました。

その結果……過去のツイートに関しては、別にWebSocketが使えないブラウザであっても表示できるようになってしまいました……

どんどん深みにはまっていくなあ。

Twitter Streaming APIで特定のワードをリアルタイムで流し、それをリアルタイムでブラウザに表示するサイトを作っているのですが、今日、ちょうどDTPの勉強会があるというので、その勉強会のハッシュタグを設定し、流れを見ていましたが、ツイートの間隔がかなり間延びする関係上、WebSocketのタイムアウトに引っ掛かって、ストリームが流れてこなくなるという現象が発現しました。

PCのブラウザでは300秒だったのですが、Androidのブラウザだと、300秒の前にタイムアウトになっているようでした。雰囲気的には120秒ぐらい。

つまり、勉強会に参加している人が講義に集中して、ハッシュタグ付きツイートが3分ぐらい途絶えると、途端にだんまりになります。これは困った!

そうやってだんまりになるたびにリロードをすること10数回、ついに、「こりゃ、Keep-Aliveを実装しなくちゃなるめえ」と思って、重い腰を上げたのでした。

いつぞやのコードにこんなのを追加した。

my $ka = AnyEvent->timer(
  after => 60,
  interval => 60,
  cb => sub {
    for (keys %$clients) {
      my $res = { mode => 'keep-alive', };
        # JSON文字列に変換
        my $json = $mj->encode($res);
        # Mojo::JSONするとutf8 fragged落ちるのでutf8 fraggedにする
        utf8::decode( $json );
        # Mojoliciousサーバに接続中の全てのクライアントに送信
      $clients->{$_}->send_message( $json );
    }
  }
);

つまり60秒ごとに意味のないデータを送信するっていうことにしてみました。

やってみたら効果覿面! 10分ツイート間隔が空いてもちゃんと接続が維持されるようになりました!

問題は、keep-aliveするのに一斉にデータを送信しているっていうことだと思います。一斉は意味がない。つうわけで、後で、ブラウザ側のタイマーで意味のない通信をすることでKeep-Aliveが実現できるかどうか試してみたいと思います。

まだまだ作っているオリジナルTwitterクライアントなのですが、そもそも、11月26日に行われるDTPの勉強会のツイートを集約する、ていう目的で作るものなので、1週間前だし、多少の問題は抱えていますが、この解決を自力で出来なさそうなのでヘルプを募ってみたが声は届かないみたいだし、とはいっても、サーバが止まらないように人力で監視すればいいだけなので、そろそろ固めてしまって公開しようかなーとかとも思ったのですが、よーく考えてみると、このクライアント、過去に発言された部分をDBに記録していて、接続時にブラウザへ送信しているのですが、現在はその転送にもWebSocketを使っている関係上、一気に大量のツイートを転送できないという問題があることが発覚しました。

これは、プログラムを見直さなければならない。

で、よく考えたんですけれども、最初の、つないだ時点からだらだら表示させるだけのクライアントだったら、サーバから流れてくるデータをブラウザ側でWebSocketでだらだら受け取ればいいのですが、過去のツイートを表示させる、というところで話が変わってきた。過去のツイートというのは、ストックで、今流れてきているのが、フローだとすると、これらにはタイムライン上で明確な分水嶺があるわけです。

図にするとこんな感じ。

Twitterclientstockflow
▲ストックとフロー

このように、性格が違うものが1つのタイムラインに並んでいるわけです。ならば、それぞれの領域でデータの取得方法をそれぞれに合ったものにすればいいと気付きました。

フローのほうは、ブラウザ側からするといつデータが飛んでくるかわからないのですから、明らかにWebSocketで少量のデータをその都度サーバからもらう方が効率がいいですよね。

一方、ストックのほうは、ブラウザ側の操作によってDBに問い合わせをして、出てきた分をデータを待ち構えているブラウザにぶっこんでやる方がいいので、AJAXでやればいい。

というわけで、この期に及んで、2つの方式をくっつけるハイブリッド式のクライアントを作る必要が出てきてしまいました。

来週までに間に合うのかな……

Windowsのリモートデスクトップってあるじゃないですか。あれを使えば、例えば会社に置いてあるPCを外出先で操作できるので素敵だね、ていうやつです。鳥インフルエンザ由来の新型インフルエンザが人間界でパンデミックしそうだといわれていた数年前、もし実際にパンデミックが発生して出社できない状況になっても、自宅から会社のPCにアクセスできれば業務はなんとかこなせるよねーという感じだと思います。

また、リモートログインの方法さえ覚えれば、後はいつもの会社で使っているPCと同じ操作ができるので、モバイルマシンやタブレット端末を使わせるよりも、教育コストが驚くほど低い、というのも特徴でした。

でも、よく考えると、外出先や、自宅の回線ってそんなにいい回線なのか、という問題があると思いました。そもそも、WindowsのリモートデスクトップはGUIなので、割と通信の帯域を食っているのだと思いますが、そんな状況で回線品質が保てないとしたら……

例えばモバイルPCから、リモートデスクトップでメールを入力している途中で、回線品質のせいでリモートデスクトップが切れがちで、全然仕事にならない、ていうこと起きているんじゃないかなーとか思います。

メールを打つ業務をするのであれば、モバイルPCで下書きをしたものを、リモート側に持って行って改めてメール送信するとか、そもそもメール送信自体をモバイルPCで行えば、済んでしまうんじゃないかなーとか思います。そこには、「新たに教育するコスト」が発生するのだけれども、ロバスト性を確保するんだったら、教育コストは掛けるべきではないかと思います。

以上、指導がくどすぎていらないことまで教えているという評価が付いてる人間からの意見でした。悪気があってやっているんじゃないんだぞ。

スマートフォンサイトでTwitterツイート表示サイトをHTML5で作ろうとすると、Android版TwitterクライアントのTwiccaのUIってうまく作ってんなーとか思います。

動画内でも言っていますが、サイト自体は技術的な壁にぶち当たっていて、協力者もなかなかあらわれてくれない状態です。

11月26日当日は、ターミナルにつきっきりでコネクション監視さえすればサービスの提供はできそうですが、そもそも利用者がいるかどうかわからないサービスになりそうですよね……

撲滅できたと思った出力エラーがまた発生することってあるんですね。というのも、2年前はPDFワークフローっていうやつを使っていたので、データの作り方が悪いのであればプリンタ出力も刷版出力も同時にダメになる、という保証がある環境作りがされていたのですが、今は昔ながらの出力機がCPSI的な環境にいたりします。

で、Illustrator 8データのCS3開きで先方使用の和文フォントがない状態で全角スペースだけがぽつんと打たれたデータを開き、なんの処理なしでPDF保存すると、Adobe Reader上では和文フォントの代替表示を和文フォント(小塚書体など)でするので全角空白のまま問題ないのだけれども、CPSIにかかると、フォントなしの代替フォントがCourierなので文字化けしてゴミが出てしまい、久方ぶりの印刷事故と相成りました。

現象が全部わかっているのだけれども現場の人にどう説明すればいいのかわからん……

プログラムの世界では、プログラムにバグを追加してしまうことを「エンバグ」というのですが、今回の事件はなんと呼べばいいんだろう……

土曜日の日、外で飲んできてうちに帰ってきたら眼鏡つけたまま寝てしまったらしく眼鏡が変形してしまったので、日曜日はコンタクトレンズでやり過ごし、月曜日の今日仕事終わってからメガネ屋さんに行ってきました。

眼鏡市場で修理をしてもらいながら雑談していたのですが、その時、「パソコン専用デジタルガードレンズ」っていうのを勧められました。パソコンのモニタ画面から出る青色光を減らして、目の疲れを減らしてくれる度付きレンズです。

そういえば、最近はてなでパソコン用眼鏡JINS PCのプロモーションがやられていたりする [b.hatena.ne.jp] ので、もしかしたらはやっているのかな?

んで、店員さんは実はうちの会社にいたことがある人なので、ぶっちゃけ話「印刷屋として色見る時ってどうよ?」と聞いたのですが、「青色の光を減らして目が疲れにくくするレンズなので、シビアに色を見る仕事の場合はお勧めできないですね。」ということでした。

レンズの色を見ると確かに青色を減らすために補色の黄色っぽい色がうっすら見えます。

もし、PCの仕事に張り付いていて、シビアに色を見る仕事でない人ならば、そういうレンズにすると目の健康を保てるかもしれませんね。僕は、1日18時間液晶画面を見ていても全然目が疲れないのでとりあえずパスです。

CGI::Application時代、CGIやmod_perl環境でスクリプトが稼働しているディレクトリを取得するのに、以下のようにしていました。

use File::Spec;
use FindBin::Real;
 
my $script_dir = FindBin::Real::Bin();
my $db_path = File::Spec->catdir ( $script_dir, 'past.db' );
my $pastlog = File::Spec->catdir ( $script_dir, 'pastlog')

それで、Mojolicious::Liteの場合は、このように書けます。

use Mojolicious::Lite;
my $db_path = app->home->rel_file('past.db');
my $pastlog = app->home->rel_dir('pastlog')

Mojolicious::Liteにスクリプト実行のカレントディレクトリ取得は既に組み込まれているのですね。

みんな大好きモザイク表現を、Mojoliciousと、Imagerを使って作ってみました。

Filename: mosaic.pl

#!/usr/bin/perl
 
use Imager;
use Mojolicious::Lite;
 
get '/mosaic/(*url)' => sub {
  my $self = shift;
  my $img = Imager->new;
  my $url = $self->stash('url');
  my $data = $self->ua->get($url)->res->body;
  $img->read( data => $data, ) or die $img->errstr;
  # $img = $img->scale( xpixels => 48, ypixels => 48,); # お好みで
  $img->filter(type=>"mosaic", size=>6);
  my $newdata;
  $img->write( data => \$newdata, type => 'png' ) or die $img->errstr;
  $self->render_data( $newdata, format => 'png' );
};
 
app->start;

これを perl mosaic.pl daemon で起動すると、http://example.com:3000/mosaic/http://hoge.com/gazou.jpg とかで http://hoge.com/gazou.jpg の画像にモザイクがかった画像が得られます。

前、別の書き方で書いたけれども、今回はより互換性がある形で。

    <script type="text/javascript">
    // WebSocketの書き方の違いを吸収するオブジェクト
    if (typeof WebSocket == 'undefined' ) {
      if (typeof MozWebSocket != 'undefined' ) {
        WebSocket = MozWebSocket;
      }
    }
    </script>
  • WebSocketオブジェクトがある場合は、何もしません。
  • WebSocketオブジェクトがなく、MozWebSocketオブジェクトが場合は、WebSocketオブジェクトを作り、MozWebSocketオブジェクトと同じにします。
  • WebSocketオブジェクトがなく、MozWebSocketオブジェクトもないは、何もしません。

これによって、Firefoxなど、MozWebSocketオブジェクトがあるがWebSocketオブジェクトがないブラウザでも、いつも通り var ws = new WebSocket('ws://example.com/ws'); でWebSocketが使えるようになります。

また、Firefox 7は、Google Chrome 14と同じ、WebSocketプロトコルがdraft hybi-10となっているので、Google ChromeでWebSocket接続ができるサーバであれば、Firefox 7でも接続できる可能性が高いです。

アドビがCreative Suite製品のアップグレードポリシーを変更と、月額5,250円(個人)の年間契約でMaster Collection使い放題プラン、Adobe Creative Cloudの発表があったのだけれども、その後僕が作っているTwitter Streaming APIを使ったシステムで、adobeというキーワードを設定したら、2時間程度で5000ツイート集まりました。

ちょうど、モバイル版Flash開発中止とそれに関する考察記事が出ているので、それのツイートもそこそこあるのですが、クリエイターにとっては、お金にチョクセツ関わるという点から、アップグレードポリシー変更とAdobe Creative Cloudの関心が高いようです。

特に、「今まで計画的にアップグレード購入してきたのに、急に方針変えやがって困る……」というのと、「アドビのソフトが5,250円で使い放題ってすげえ安いじゃん?」ていうのが多いですね。

僕としては、DTP的用途において、アプリのバージョン違いでデータの再現性が異なるソフトをわざと作っているんだから、古いバージョンのソフトも動かせるライセンスにすれば割と納得いくと思います。

かくいう我が家もCSとCS2とCS3とCS4がありますので、これ全部CS6にアップグレードできないわけですよね。CS3で10年戦えばいいんじゃね、出力はPDFでなんとか。ていう気がしています。

Perl 5.8・Mojolicious 1.97/Perl 5.10・Mojolicious 2.19のクロス環境で開発しているのですが、Mojoliciousに日付を扱うモジュールMojo::Dateがあるので、ブラウザのJavaScriptで取り扱わせる日付をPerl側で用意するときに使えるよ、というお話。

use strict;
use warnings;
use YAML;
 
use Date::Parse;
use DateTime;
use DateTime::Format::Mail;
use Mojo::Date;
 
my $date_twitter = 'Tue Jan 05 13:16:29 +0000 2010'; # ctimeの形式
 
my $date;
 
$date->{DateTime} =
  DateTime::Format::Mail->format_datetime(
    DateTime->from_epoch(
      epoch => str2time( $date_twitter )
    )
  );
 
$date->{'Mojo::Date'} =
  Mojo::Date->new( str2time( $date_twitter ) )
            ->to_string;
 
print Dump $date;
exit;
 
__END__
$ perl test.pl
---
DateTime: 'Tue, 05 Jan 2010 13:16:29 -0000'
Mojo::Date: 'Tue, 05 Jan 2010 13:16:29 GMT'

出てきた書式は違いますが、どっちでもJavaScript側では同じ時刻としてちゃんと処理されます(Internet ExplorerでもOK)。

DateTimeモジュールというとてもでかいモジュールを使わなくてもいいのは利点かなあと思います。

(2013.3.6 13.38 変更)

このエントリのタイトルを、
旧)Mojolicious::LiteのWebSocketのタイムアウトは300秒
新)Mojolicious::LiteのWebSocketのタイムアウトは15秒

に直しました。

〜〜〜

2011年11月26日のイベントに合わせて、自発的にWebSocketを使ったサイトを作ろうと思っており、本番に合わせて、ハッシュタグを設定してテストを行っているのですが、流量が少ないせいで、WebSocket接続がタイムアウトになることが判明。これはあかん。

Mojolicious::Liteを使っている時は、

my $timeout = app->ua->websocket_timeout;

でタイムアウトの時間が得られ、300秒となっとる。

これを、

app->ua->websocket_timeout(30);

とかに設定してテストをするも、相変わらず300秒で切れる。

というわけで、どこでタイムアウトを設定するかがわからん状況です。また調べなおししないと......


(2013-03-06 13:28追記)

更新終了のブログに追記っていうのもなんですが、今の時点で使っているMojolicious 3.50あたりだと、デフォルトのタイムアウトが15秒になっていまして、これを変更するには、

Mojolicious::Lite で WebSocketのタイムアウトの時間を修正する - 僕の車輪の再発明 [kazuph.hateblo.jp]

にあるように、

my $clients = {};
websocket '/echo' => sub {
    my $self = shift;
 
    # デフォルトだとタイムアウトが15秒なのを300秒に修正
    Mojo::IOLoop->stream($self->tx->connection)->timeout(300);
     
   ...
 
}

でいけます。

夜勤です

| コメント(0) | トラックバック(0)

今日から1週間午後4時から午前1時までの夜勤に入ります。

この間、通常している業務をペンディングにしたり別のところに頼んだりして、機械オペレータの補助に回るという次第。

これに合わせて睡眠をとったため2日間を3日分として活用できたのでプログラムするのがすごく捗った!

そもそも、午後4時出社でいいかどうか不安なわけだが。普段夜勤していないとそういうことってありますよね。

夜勤終わったら詰みあがっている仕事量が不安……

Javaを使ったゲームとして有名なスーパー正男のAndroid版アプリが出ていましたので、LifeTouch NOTEにインストールしてみました。

スーパー正男 - Android マーケット [market.android.com]

ぶっちゃけ、スーパーマ○オなので、走りながらジャンプせないかんのですが、液晶画面上に表示されるコントローラーとジャンプボタンを同時に押すとジャンプしません。

「あ、この端末マルチタッチ対応じゃないや。」

ちゃんと、121wareのスペックページにも※7に書いてある。

121ware.com > 製品情報 > LifeTouch NOTE [121ware.com]

キーボード付き端末なんだから、タッチ必要なゲームすんなよ、ていうのはごもっともでございます。NP2とかならいいんじゃないかなーとか思います。

Twitter Streaming API接続を使い、ニコニコ動画風にブラウザ上で字幕を流すMojoliciousウェブアプリケーションの最新版です。

なにかイベントあった時にサクッとAmazon EC2を立ち上げて、ソースをコピー&ペーストしてすぐ設置できるぐらいのカジュアルさを目指しました。

■動作確認環境

  • CentOS 5.6 / Perl 5.8.8 / Mojolicious 1.97
  • Amazon Linux AMI / Perl 5.10.1 /Mojolicious 2.19(2.20~2.24は不可)

~~~

起動するには、事前に取得しておいたconsumer keyをconsumer_keys.yamlに、access tokenを~/.pit/defalt.yamlに設定しておき、

perl twitter-jimaku.pl daemon -listen http://*:3000

とサーバで実行したあと、ウェブブラウザ(Firefox7、Google Chrome 15)で

http://www.example.com:3000

に接続すると画面に字幕が流れる、というものになります。

~~~

現状わかっている不具合として、

「Twitter Streaming APIの接続が切れた時の再接続ができない」

というものがあります。いろいろ調べて、AnyEventのイベントループだけで廻っている場合は策があるのですが、Mojoliciousのイベントループとの複合技になると途端に制御が難しくなってしまいます。だれか、解決策をご存じの方にご指南をいただきたく、現状のソースを公開します。

事情はいろいろ言えませんが来週夕方出勤で夜勤になりました。

よーく考えてみると、このブログ始めたころも夜勤をやっていたんだなーと、過去のエントリを検索して思いました。

DELLが来ていたみたい。予定より早いよ! 05/01/21 [blog.dtpwiki.jp]

たしか、会社に入った型と同じサーバを買って勉強したんですよね。当時はお金持でしたね……

鳴らない電話 05/03/24 [blog.dtpwiki.jp]

定番のアドビいびり。こーいうところで信用をなくす(お互いに)。

Acrobat 7 入手 05/01/21 [blog.dtpwiki.jp]

おこずかいで買ったAcrobat 7。PDFの破線問題なんて懐かしいネタが書いてありますね。

2011年11月3日時点で最新のMojolicious 2.21では、AnyEvent::Twitter::StreamをuseしただけでWebSocket接続ができなくなります。

テストコード:

http://search.cpan.org/~sri/Mojolicious-2.21/lib/Mojolicious/Guides/Cookbook.pod#WebSocket [search.cpan.org]

のコードの頭に、use AnyEvent::Twitter::Stream をくっつけるだけで、Google Chromeではエラーになってしまいます。

Googlechromewebsocketerror

ソースを少し改造して、Firefox用のPrefixをつけてやると、Firefoxでも動くはずなのですが、use AnyEvent::Twitter::Stream をくっつけると、やっぱりエラーになります。

Mozillafirefoxwebsocketerror

テスト環境は、Basic 64-bit Amazon Linux AMI 2011.09 (AMI Id: ami-0a44f00b)をmicroインスタンスで起動して、

mkdir bin
cd bin
curl -LOk http://xrl.us/cpanm
chmod +x cpanm
cd
sudo passwd root
su
yum install perl-devel
yum install gcc
yum install make
yum install openssl-devel
cpanm EV
cpanm Time::HiRes
cpanm Mojolicious
cpanm AnyEvent::Twitter::Stream
exit

までした状態で、上記のテストコードを

perl test.pl daemon

で実行しました。

回避方法としては、Mojolicious 2.19まで落とす、というのが一応有効です。今まで動いていたコードでWebSocket接続できなくなった時は疑ってみるといいかもです。

var Hoge = function() {};
Hoge.prototype = {
  hoge: function() {
  },
  do: function() {
    alert('do!');
  }
};
var fuga = new Hoge;
fuga.do();

ていうコードをFirefoxで動かすと通るが、Windows版Safari 5.0.5で動かすと、「Syntax Error: Parse error」が出る。

doを、dodoとかに書き換えると、エラーはなくなる。

メソッド名じゃなくてプロパティ名としてならどうなのかーと思って、

var Hoge = function() {};
Hoge.prototype = {
  hoge: function() {
    alert(this.do);
  },
  do: 1
};
var fuga = new Hoge;
fuga.hoge();

とやると、やっぱりSafariだとだめ。

いっそのこと、

var Hoge = {};
Hoge.do = 1;

というのはどうだ、と思ったらこれすらだめ。

Safariだと、doって予約されているのかな?


(2011-11-02 23:31追記)

Mac版Safari 5.0.6と、Windows版Safari 5.1.1で試したら、問題がありませんでした。それを受けてタイトルを修正しました。

あまりWebのことに詳しくないDTP系の方へのURLに関するいくつかのヒント - DTP Transit

「年」を入れましょう

Webのコンテンツはすぐに陳腐化します。「●月●日」だけの情報では、その翌年に、どの年のことか分からなくなってしまいます。

ブログのように、記事が執筆された年月日が記入されているものでさえ、日付が書いてある箇所はマチマチですから、「この記事って、いつのこと?」と迷ってしまいます。

たとえば、ブログなど他のサイトに貼っていただくことを前提とするバナーはなおさらです。

というのですが、サイトの見栄えを判断する人は、「情報が切り取られて判断される」という実感がないことがあって、「どうせ自サイトに掲載するんだから、わかるだろ」という理由から、「いつ・どこで・だれが・なにを・どうした・なぜ」の5W1Hを入れるのを嫌うことがあります。

つまり、「2011年に書いたことをすぐに読むのだから必然的に2011年のことだとわかるだろ、冗長だ。」とかいうわけです。なるほど、確かにそれも読み手のことを考えているともいえる。しかも、いるかどうかわからない未来の読み手のことよりも、そこに確実にいる今の読み手のことを考えて読みやすい文章を作るべきだ。……文章を読む立場、読みやすさの評価軸が違うから、日付に年を入れる論争はここから平行線です。

(個人的には、Print-Betterという、年を入れたがらないサイトのスクレーピングをして、コンテンツの日付に年がないことの不便さを実感しています。)

というわけで、そういう評価をされるサイトでは、僕は、たとえば2011年11月1日の、「2011年」の部分をspan要素で囲ってしまい、class名hiddenとかをつけておいて、CSSでそのサイト上では表示されないようにしていたりします。

こんなことしなくてもちゃんと説得すればいいのですが、僕は説得が通ったことがないので、こんな変なことに……

月別 アーカイブ

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.2.7

このアーカイブについて

このページには、2011年11月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2011年10月です。

次のアーカイブは2011年12月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。