2012年09月29日

chrome上で、Webサーバーを動かしてみた



Chrome Apps v2's socket api

Chrome の Web appsが manifest v2 に変わり、その機能、特に Packaged Apps が大幅に変わっています。

その中で僕が特に注目しているのが、socket api。ChromeのPackaged Appsから、生のソケットコーディングが出来るようになります。

この socket api ですが、これまで tcp ソケットでサーバーを立てることができなかった(listenとかacceptのメソッドが無かった)のですが、昨日 Google API Expert MTGで 吉川さんから、「昨晩Chromiumで実装されたみたい」との情報が。ということで、早速簡単なWebサーバーを動かしてみました・・・というのが今日のEntryです。(執筆時点では、すでに、canary buildでも動いています)

ということで、早速コードを紹介します。(Chromeの最新canary build 24.0.1280.0 で確認しています。なお、chrome://flagsで、「試験運用版の拡張機能 API 」を有効にするのをお忘れなく)

サンプルコード

manifest.json

{
  "manifest_version": 2,
  "name": "simple HTTP server",
  "description": "something what ridiculous simple web server",
  "version": "0.1",
  "minimum_chrome_version": "24",
  "app": {
    "background": {
      "scripts": ["httpserver.js"]
    }
  },
  "permissions": [
    "experimental",
    {"socket": [
      "tcp-listen"
    ]}
  ]
}

permissionsで、tcp-listenを指定するのがミソです。

httpserver.js

function t2ab(str /* String */) {
    var buffer = new ArrayBuffer(str.length);
    var view = new DataView(buffer);
    for(var i = 0, l = str.length; i < l; i++) {
      view.setInt8(i, str.charAt(i).charCodeAt());
    }
    return buffer;
}

function ab2t(buffer /* ArrayBuffer */) {
  var arr = new Int8Array(buffer);
  var str = "";
  for(var i = 0, l = arr.length; i < l; i++) {
    str += String.fromCharCode.call(this, arr[i]);
  }
  return str;
}


var RESPHEAD = [
  "HTTP/1.1 200 OK",
  "Server: chrome24",
  "Content-Length: {%len%}",
  "Connection: Close",
  "Content-Type: text/html"
]

RESPHEAD = RESPHEAD.join("\r\n")+"\r\n\r\n";

var RESP = [
  "<!doctype html>",
  "<html>",
  "<head>",
  "</head>",
  "<body>",
  "<h1>Welcome!!</h1>",
  "<p>this web server is built w/ chrome's packaged apps v2 feature</p>",
  "</body>",
  "</html>"
]
RESP = RESP.join("\r\n");

var response = function(str){
  var len = str.length;
  return RESPHEAD.replace("{%len%}", len)+str;
}


var rtw = function(sid) {
  // [TODO]
  // call recursive for keep-alive features
  // currently, I haven't tested.
  chrome.socket.read(sid, 65535, function(e){
    console.log(ab2t(e.data));
    if(e.resultCode < 0) {
      chrome.socket.destroy(sid);
      return;
    }
    chrome.socket.write(sid, t2ab(response(RESP)), function(e){
      // [TODO] check datasize
      console.dir(e);
      rtw(sid);
    });
  });
}

chrome.socket.create('tcp', {}, function(e){
  var s = e;

  chrome.socket.listen(s.socketId, "0.0.0.0", 0, 10, function(e){
    chrome.socket.getInfo(s.socketId, function(e){
      console.log("Local web server's URL => http://localhost:"+e.localPort+"/"); // you can check listen port :)
    });
    var accept_ = function(sid){
      chrome.socket.accept(sid, function(e){
        rtw(e.socketId);
        accept_(s.socketId);
      });
    }
    accept_(s.socketId);
  });
});

tcpをacceptしたあと、再度acceptを呼ばないと、2回目以降のtcp接続がハンドルできないため(この動作正しいのかなぁ・・・)、とりあえず簡単なやり方ということで、再帰で書いています(この書き方だと、メモリがちと心配)

動作確認

上記コードは githubに置いておきました。chrome://extensions でこれをインストールすると(「デベロッパーモード」にチェックを入れ、「パッケージ化されていない拡張機能を読み込む」で、該当のフォルダーを指定)、バックグラウンドプロセスとしてWebサーバーが起動します。

ここで、simple HTTP serverの「ビューを調査: _generated_background_page.html」をクリックすると dev tools が起動します。ここで、コンソールのタブをクリックすると、WebサーバーのURLが表示されています。
0929-0

そのURLにブラウザでアクセスすると、以下の画面が表示されます。(Webサーバーで動いているため、ブラウザであればなんでも、アクセス可能です。以下のスクリーンショットは FireFoxとSafariからアクセスした場合)
0929-1

どんなリクエストに対しても、同一リソースしか返さない超シンプルなWebサーバーが起動しましたw

まとめ

今回のポストでは、Chrome apps v2の目玉機能の一つ socket api について、

  • 昨日ついに実装された tcpサーバーのAPI
  • サンプルとしてWebサーバーのコード
を紹介しました。ブラウザでtcpサーバーが起動できると、Web アプリケーションの幅は大きく広がります。これからのWebがますます楽しくなってきましたw



人気ブログランキングへ
kotesaki at 02:52│Comments(16)TrackBack(0)clip!

トラックバックURL

この記事へのコメント

1. Posted by サッカー用品専門店   2012年11月07日 11:28
5 はるきゃん、、かわいい(>_<) koheisoccer.com
2. Posted by ciel   2012年12月13日 15:32
知り合いのGoogleエンジニアに訊いたところ、コールバックが呼ばれるたびに別のスタックができるそうです。なので再帰は問題無さそうです。
なので、お借りさせていただきました。ありがとうございます。
http://code.google.com/p/ctouch/source/browse/ctouch_chromesocket/ctouch_chromesocket.js
POSTなら内容をatobしてjsonとして保存、GETならjsonを直接返すだけのアプリです(実際にはcontent scriptがXHRで読みだすのですが…)。
3. Posted by エアジョーダン 激安販売   2012年12月29日 11:14
5 なんか軍部が力持ってきてる感じがするな。http://www.lottejordan.com/
4. Posted by RS Gold   2013年02月26日 15:12
POSTなら内容をatobしてjsonとして保存、GETならjsonを直接返すだけのアプリです(実際にはcontent scriptがXHRで読みだすのですが…)。
5. Posted by http://blog.alrazaak.com/low-back-pain-treatment   2013年03月07日 19:56
をatobしてjsonとして保存、GETならjsonを直接返すだけのアプリです(実際にはcontent scriptがXHRで読みだすのですが…)。
6. Posted by Diablo 3 Gold kaufen   2013年03月22日 22:18
同一リソースしか返さない超シンプルなWebサーバーが起動しましたw
7. Posted by GW2 Gold   2013年04月06日 22:48
なので、お借りさせていただきました。ありがとうございます。
8. Posted by henna patterns   2013年04月13日 02:39
借りさせていただきました。ありがとうございます。
9. Posted by HAMAL SA LARKA   2013年05月01日 03:11
させていただきました。ありがとうございます。
10. Posted by wow gold   2013年05月04日 19:09
同一リソースしか返さない超シンプルなWebサーバーが起動しましたw
11. Posted by guild wars 2 gold   2013年05月14日 12:32
今回のポストでは、Chrome apps v2の目玉機能の一つ socket api について、

昨日ついに実装された tcpサーバーのAPI
サンプルとしてWebサーバーのコード

を紹介しました。ブラウザでtcpサーバーが起動できると、Web アプリケーションの幅は大きく広がります。これからのWebがますます楽しくなってきましたw
12. Posted by コピーブランド 激安   2014年05月14日 00:15
ファスナー小銭入れ×1
13. Posted by シャネル 時計 激安   2014年07月23日 22:32
【素材】カーフレザー×スエード
14. Posted by Teletubbies Mascot Adult Costume   2014年09月04日 14:58
Hi! There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game. Both boys and girls feel the impact of just a moment’s pleasure, for the rest of their lives.
15. Posted by クリスチャンルブタン スニーカー   2014年09月18日 01:39
デザインも素晴らしいので売り切れ確実です。
16. Posted by creditos rapidos con asnef   2016年01月19日 03:27

もう一度あなたのブログを訪問することがニース、それは私のために数ヶ月-てきました。私はあまりにも長い間待っていたしてきたさて、この記事。私は大学で私の割り当てを完了するために、この記事を必要とし、それはあなたの記事と同じ話題を持っています。おかげで、大きなシェア。

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔