Skip to content

Instantly share code, notes, and snippets.

@flada-auxv
Created November 23, 2012 12:11
Show Gist options
  • Save flada-auxv/4135345 to your computer and use it in GitHub Desktop.
Save flada-auxv/4135345 to your computer and use it in GitHub Desktop.
Node.js道場(第一回目)の課題
var http = require('http');
server = http.createServer(function (req, res) {
console.log(req.url);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
req.on('end', function() {
req.connection.end();
});
});
server.on('connection', function() {
server.close();
});
server.listen(8080, 0, function () {
console.log('Server running at http://localhost:8080/');
});

カンニングしました!
リクエストが複数飛んでいる事までは確認できたのですが、対処方法が上手くいかず。。。

一応、勉強した事のまとめと言う事で提出しておきます。
用語とかブレているかもしれませんが、駆け出しなのでご容赦下さいまし!

課題1への回答

Not running at Server.closeというエラーメッセージから、サーバーが終了した後にもう一度Server.close()を呼び出しているであろう事が分かります。

実際に、console.log(req.url)としてリクエストのURLを確認してみると、"/"へのアクセスの後、"/favicon.ico"へのアクセスが発生している様です。
これはServer.close()が、公式ドキュメントにて、

サーバが新しい接続を受け付けるのを終了しますが、既存の接続は維持します。

と説明されている動作を取る事に起因します。

つまり、"/"へのアクセスで得た接続はServer.close()した後も生きており、それを利用して"/favicon.ico"へのアクセスが行われ、その際にもう一度呼び出されてしまっているという事です。

また、二度目のServer.close()が問題になるのは、エラーメッセージにある通りnode/lib/net.jsの1064行目あたりを覗いてみると、

> node/lib/net.js
Server.prototype.close = function(cb) {
  if (!this._handle) {
    // Throw error. Follows net_legacy behaviour.
    throw new Error('Not running');
  }
 
  if (cb) {
    this.once('close', cb);
  }
  this._handle.close();
  this._handle = null;
  this._emitCloseIfDrained();

とある事から、最初の"/"への呼び出しでthis._handleがnullにセットされていた為だと分かります。

課題2への回答(コードはanswer.js)

http.Serverの'connection'イベントにてServer.close()しておく事で、以降新しい接続を受け付けなくする。
さらに、http.ServerRequestの'end'イベントにて、既存の接続を終了させる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment