情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

httpモジュールによるHTTPサーバ(1)サーバの作成と起動と停止

2016/08/03

この記事は「httpモジュールによるHTTPサーバ」という連載記事の1つ目の記事です。

その他の記事に関しては下を参照してください。

この記事ではhttpモジュールを使ってHTTPサーバを作成し、起動し、停止する方法を説明します。

HTTPサーバの作成

HTTPサーバを作成するにはhttp.createServer関数を使用します。

var http = require('http');

var server = http.createServer(function (req, res) {
    res.end();
});

第1引数

第1引数にクライアントからのHTTPリクエストを処理する関数を指定します。

この関数では必要に応じてクライアントからのHTTPリクエストの内容を取得し、クライアントに返すHTTPレスポンスの内容を適切なものに設定します。

この関数の第1引数はクライアントからのHTTPリクエストの内容を表すhttp.IncomingMessageクラスのインスタンスです。このインスタンスはHTTPリクエストボディのデータを読み込むストリームでもあります。また、この引数の名称はreq(requestの省略)とされることが多いです。以後この引数をreqと表記します。

第2引数はクライアントに返すHTTPレスポンスの内容を表すhttp.ServerResponseクラスのインスタンスです。このインスタンスはHTTPレスポンスボディにデータを書き込むストリームでもあります。また、この引数の名称はres(responseの省略)とされることが多いです。以後この引数をresと表記します。

返り値

返り値としてHTTPサーバを表すhttp.Serverクラスのインスタンスが得られます。以後このクラスのインスタンスをserverと表記します。

なお、HTTPリクエストを処理する関数を実装する際には注意しなければならない点が1つあります。

それは、resストリームへの書き込みを完了するまではクライアントとサーバの間の接続は開いたままで維持されるということです。

つまり、resストリームに書き込まなければならない全てのデータを書き込んだら必ず最後にストリームへの書き込みを完了するためにres.end関数を呼び出すようにしなければなりません

HTTPサーバの起動

HTTPサーバを起動するにはserver.listen関数を使用します。

server.listen(3000, function () {
});

第1引数にポート番号を指定します。0を指定した場合にはランダムなポート番号が割り当てられます。

第2引数にコールバック関数を指定します。この引数は指定しなくても構いません。

HTTPサーバの停止

HTTPサーバを停止するにはserver.close関数を使用します。

server.close(function () {
});

第1引数にコールバック関数を指定します。この引数は指定しなくても構いません。

エラー処理

serverでエラーが発生した場合にはerrorイベントが発生します。

このイベントのイベントハンドラでエラー処理を行います。

server.on('error', function (err) {
});

サンプルコード1

クライアントからリクエストを受け取ったら標準出力にメッセージを出力するHTTPサーバを作成し、起動します。

Enterキーが押されたらサーバを停止し、プログラムを終了します。

http-server.js

var http = require('http');

var server = http.createServer(function (req, res) {
    try {
        console.log('requested.');
    }
    catch (err) {
        console.error('unhandled exception has occured.');
        console.error(err);
    }
    finally {
        res.end();
    }
});
server.listen(3000, function () {
    console.log('http server is running...press enter key to exit.');

    process.stdin.on('data', function (data) {
        if (data.indexOf('\n') !== -1) {
            server.close(function () {
                console.log('http server closed.');
                process.exit(0);
            });
        }
    });
});
server.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

実行結果

実行結果の確認のためにcURLを使用しています。

コードを実行するとHTTPサーバが起動します。

C:\work\node>node http-server.js
http server is running...press enter key to exit.

cURLを使ってサーバに対してHTTPリクエストを行うと下のような結果になりました。

サーバから正しくレスポンスが返っていることが分かります。

C:\work\node>curl -v http://localhost:3000/
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 15 May 2016 23:05:04 GMT
< Connection: keep-alive
< Content-Length: 0
<
* Connection #0 to host localhost left intact

Enterキーを押すとサーバが停止し、プログラムが終了します。

C:\work\node>node http-server.js
http server is running...press enter key to exit.
requested.

http server closed.

サンプルコード2

サンプルコード1とほぼ同じですが、res.end関数を呼び出さなかった場合にはどうなるでしょうか?

これは悪い例ですので注意してください。

http-server-bad.js

var http = require('http');

var server = http.createServer(function (req, res) {
    try {
        console.log('requested.');
    }
    catch (err) {
        console.error('unhandled exception has occured.');
        console.error(err);
    }
    finally {
    }
});
server.listen(3000, function () {
    console.log('http server is running...press enter key to exit.');

    process.stdin.on('data', function (data) {
        if (data.indexOf('\n') !== -1) {
            server.close(function () {
                console.log('http server closed.');
                process.exit(0);
            });
        }
    });
});
server.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

実行結果

コードを実行するとHTTPサーバが起動します。

C:\work\node>node http-server-bad.js
http server is running...press enter key to exit.

cURLを使ってサーバに対してHTTPリクエストを行うと下のような結果になりました。

サーバからレスポンスが返ってこず、動作が止まったままです。

C:\work\node>curl -v http://localhost:3000/
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>

最終的に下のような結果になりました。

* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js