Category Archives: Html5

こんにちは。先日のブログで以下のような発言をしたイッシーです。(●´ω`●)

僕は生産設備を持っていませんので食料をはじめとした物流における支援は難しいのかもしれません。しかしながらシステムエンジニアとして間接的な支援や情報における支援はできます。僕は、天災における「破壊」を修復するのは人々の「生産」と考えるとともに、その「生産」の一部分を担う者として頑張っていきたいと思います。

有言実行ということで緊急地震速報をお知らせするChrome用の拡張機能を作ってみました。そこで今回は技術的な部分をまとめておきます。

■仕様

クライアント側

Web Notifications

お知らせを表示する小窓です。一番はじめのブログの題材にしました。

WebSocket

双方向通信の規格。これを使うとサーバ側から情報をプッシュできます。

Audio API

お知らせ音を鳴らす際に使用しました。

サーバ側

node.js

サーバサイドJavaScript。一言では表せない存在。同時接続ユーザ数が増えた場合のパフォーマンスがapacheと比べて非常に良いと思います。

■困ったこと1

node-websocket-serverの接続数が1024以上にならない。

解決策

node serverを立ち上げる前に以下のコマンドを実行することで解決しました。

ulimit -n 2048

デフォルトでファイルディスクリプタの数が1024になっているので、1プロセスあたり1024個の接続がリミットになっていたわけです。twitterで教えてくださった方に感謝です!

■困ったこと2

30分以上のスリープ状態から復帰すると接続が切れているが、イベントが発火せずプロパティにも特に変化がない。

解決策

以下のようなコードを使用することで回避しました。

var reload  = 600000;
var before = new Date();
setInterval(function(){
    var current = new Date();
    if((current - before) > (reload + 15000)){
        connect();// 再接続
    }
    before = current;
},reload);

タイマーを利用してスリープを検知しています。通常はcurrentとbeforeの差は殆どreloadと等しくなりますが、スリープした場合に差が大きくなります。それを利用して再接続をしているわけです。ヒラメキに感謝!

コードが美しくないのでhtml5-developers-jpに質問してみたところ、「NATやFireWallがあり通信が一定期間無い場合、リソース節約のためにそのセッションテーブルを切ってしまうため、readyStateなどは変化しない」とアドバイスを頂きました。教えてくださった方ありがとうございます!

■困ったこと3

千人くらい使ってくれるかなと考えていましたので、一万人を超えた時は正直焦りました。急激にトラフィックが制限に近づいてます。ソーシャルゲームとは違いユーザ間でデータの共有はしてませんので、サーバさえあれば分散は容易になってます。また、協力してくださる方もいますので協力してくださる方に感謝です!

■まとめ

当初、不具合がありまして多くの皆様に迷惑をかけたにもかかわらず、温かい言葉をかけてくださいまして大変励みになりました。また、個人で制作したものではありますが、サーバーなど会社のバックアップがあってこそ運営できているものです。改めて周囲の皆様に感謝し今後も頑張っていきたいと思うとともに、震災にあわれた地域のいち早い復興を願っております。

みなさんこんにちは。2月に入社した石本(通称:イッシー)です。会社ではスマートフォンのネイティブアプリを作ってます。\(^o^)/

さて、ご存知の方も多いと思いますが、Gmailに新しいオプションが付きました。「設定 > 全般」の項目の「デスクトップ通知」という項目です。この機能を”オン”にした場合、Google Chromeではデスクトップ右下(Macは右上)に、メール受信のお知らせが表示されるようになります。この通知機能によって、メールの受信に気づけるようになるわけです。

そこで本日は、スマートフォンのネイティブアプリには直接関係ないですが、Web Notifications(通知機能)について解説したいと思います。

サンプル

Google Chromeで以下のボタンを押すと、右下に小窓が表示されます。

※初回は「許可」を選択し、再度ボタンをクリックしてお試しください。

サンプルコード

以下のようにするとWeb Notificationsが使用できます。細かい解説はコードの中にコメントとして記述しました。

document.getElementById('button').addEventListener(
    'click',
    function(e){
        // 通知機能を実装していないブラウザを除外します
        if(typeof window.webkitNotifications == 'undefined'){return;}
       
        // 通知機能はユーザが許可したサイトでしか使うことができません。
        // そこでユーザのブラウザから許可を得ているかを取得します。
        var permission = webkitNotifications.checkPermission();
        switch(permission){
            case 0:// 許可されているとき
                var notification = webkitNotifications.createNotification(
                    '',                                   // アイコンの画像ファイル
                    '通知ですー',                           // 通知のタイトル
                    '(サンプル)お知らせが届きました!\(^o^)/'// 通知の内容
                );
                notification.show();// 通知の表示
                break;
            case 1:// 許可されていないとき
                webkitNotifications.requestPermission(function(){
                    // 「許可」もしくは「拒否」が押された後に呼ばれるコールバック関数。
                    //  但し、どちらが押されたかを取得することはできない。
                });
                break;
            case 2:// 拒否されているとき
                break;
        }
    },
    false
);

いかがでしょうか?意外と少ないコード量で実現することができました。上述の場合、通知機能は表示されたままですが、一定時間の表示後に消すこともできます。

        switch(permission){
            case 0:// 許可されているとき
                var notification = webkitNotifications.createNotification(
                    '',// アイコンの画像ファイル
                    '通知ですー',// 通知のタイトル
                    '(サンプル)お知らせが届きました!\(^o^)/'// 通知の内容
                );
                notification.ondisplay = function(){// 通知が表示されたときのイベント
                    setTimeout(
                        function(){
                            notification.cancel();// 通知を消す処理
                        },
                        2000// 2秒後
                    );
                };
                notification.show();
                break;
            case 1:// 許可されていないとき
                webkitNotifications.requestPermission(function(){});
                break;
            case 2:// 拒否されているとき
                break;
        }

その他のイベントハンドラやメソッドについては以下のようになってます。(参考:chromium Design Document

interface Notification : EventTarget {
 // メソッド
 void show();// 表示する
 void cancel();// 閉じる

 // イベントハンドラ
 attribute Function ondisplay;// 表示されたとき
 attribute Function onerror;
 attribute Function onclose;// 閉じたとき
}

以下のように、W3Cのthe Notification interfaceとは若干実装されているものが異なってるようですね。(参考:the Notification interface

interface Notification : EventTarget {
  void               show();
  void               cancel();
           attribute Function   onclick;
           attribute Function   onshow;
           attribute Function   onerror;
           attribute Function   onclose;
           attribute DOMString  replaceId;
           attribute DOMString  dir;
};

2011年2月現在では、Chromeと同じWebkitを採用しているSafariで、この機能を使用できませんでした。しかし、今後はSafariだけでなく、より多くのブラウザで今回解説した通知機能が使用できるようになるはずです。

参考

ちなみに去年のGoogle Developer Day 2010 Japanでも紹介されていました。