Skip to content

Instantly share code, notes, and snippets.

@hitsujiwool
Forked from shigeki/hello.js
Created December 2, 2012 16:01
Show Gist options
  • Save hitsujiwool/4189468 to your computer and use it in GitHub Desktop.
Save hitsujiwool/4189468 to your computer and use it in GitHub Desktop.
第1回Node.js入門勉強会 レポート課題
var http = require('http');
server = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
server.close();
});
server.listen(8080, 0, function () {
console.log('Server running at http://localhost:8080/');
});

課題1

ブラウザからアクセスすると、同一のTCPコネクションの中で、//favicon.icoへ、合わせて2回のHTTPリクエストが発生し、対応するコールバックも2回呼ばれる。ところが、1回目のコールバックですでにserver.close()が実行されているため、次のリクエストでserver.close()がもう一度実行されたときにエラーが生じる。

課題2

var http = require('http');

server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
  req.socket.end(); // ここでTCPのコネクションを切る
});

server.on('connection', function() {
  server.close();
});

server.listen(8080, 0, function () {
  console.log('Server running at http://localhost:8080/');
});

はじめは、2回目のリクエスト後にserver.close()すればよいと考えて以下のコードを書いたのですが、req.socket.end()を実行しているのにTCPのコネクションが切断されず、keep-aliveの分だけ接続が残ってしまいます。どうしてなのでしょうか……

var http = require('http'),
    sockets = {};

server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
  var key = req.socket.remoteAddress + ':' + req.socket.remotePort;
  if (key in sockets) {      
    server.close();
    req.socket.end();
  } else {
    sockets[key] = true;
  }
});

server.listen(8080, 0, function () {
  console.log('Server running at http://localhost:8080/');
});

第1回の勉強会で重要だった点の一つは server.close() の挙動でした。 今回は、この server.close() の挙動についての課題です。

課題

A君は、ブラウザで1回閲覧したら HelloWorld のWebサーバが終了するプログラムを作ろうと hello.js を作りました。 だけど Chrome でアクセスすると下のようなエラーになってしまい、プログラムが正常に終了しません。

課題1

なぜエラーが発生したのかその理由を記述しなさい。

課題2

このプログラムを修正してエラーが発生せずA君がやりたかったプログラムを作りなさい。

提出方法

gist か ブログかに記載して、URLをメーリングリストに連絡してください。

##提出期限

次回勉強会開催まで。(その前に出そろえば答え合わせでもしましょうか)

> node hello.js
Server running at http://localhost:8080/

net.js:1046
    throw new Error('Not running');
          ^
Error: Not running
    at Server.close (net.js:1046:11)
    at Server.<anonymous> (/home/ohtsu/hello.js:5:10)
    at Server.EventEmitter.emit (events.js:99:17)
    at HTTPParser.parser.onIncoming (http.js:1807:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23)
    at Socket.socket.ondata (http.js:1704:22)
    at TCP.onread (net.js:403:27)
@yosuke-furukawa
Copy link

はじめは、2回目のリクエスト後にserver.close()すればよいと考えて以下のコードを書いたのですが、req.socket.end()を実行しているのに
TCPのコネクションが切断されず、keep-aliveの分だけ接続が残ってしまいます。どうしてなのでしょうか……
これまさにcloseの課題にピッタリの現象じゃないでしょうか。

@hitsujiwool
Copy link
Author

そうなんですね……前回も質問した部分がやはりよくわかっていないようです。
次回までに理解できるようがんばります。

@hitsujiwool
Copy link
Author

TCPのコネクションは2本張られているにもかかわらず、実際にHTTPのやりとりをしているのはその片方だけだったようです(serverのconnectionイベントは2回実行されました)。req.socket.end()を実行しても、もう片方のTCPコネクションが残っており、すぐにサーバが落ちない、というのが原因のようです。

furukawaさんコメントありがとうございました。

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