情報アイランド

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

expressモジュールによるHTTPサーバ 番外編(1)サーバ送信イベント(server-sent event)

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

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

また、HTTP自体について知りたい方は下を参照してください。

この記事ではexpressモジュールとserver-sent-eventsモジュールを使ってサーバ送信イベントを送信するHTTPサーバを作成する方法について説明します。

サーバ送信イベントとは?

サーバ送信イベントserver-sent event)とはtext/event-stream形式でサーバからクライアントに送信されるイベントストリームです。

サーバ送信イベントの送信

server-sent-eventsモジュールはサーバ送信イベントを送信するミドルウェアそのものです。

ですから、app.use関数の第1引数にserver-sent-eventsモジュールをそのまま指定することができます。

var express = require('express');
var serverSentEvents = require('server-sent-events');

var app = express();
app.use(serverSentEvents);

そして、このミドルウェアはサーバ送信イベントを送信する関数をres.sseに格納します。

この関数の第1引数にはイベントを文字列として指定します。

app.use('xxx', function (req, res, next) {
    res.sse('yyy');
});

なお、サーバ送信イベントを受信するクライアントは何らかの原因によりイベントストリームを受信するためのサーバとの接続が切断された場合にはサーバとの再接続を繰り返し試行しますが、クライアントによる再接続の試行を止めさせるにはステータスコードが204No Content)のHTTPレスポンスを返信するようにします。

サンプルコード1

クライアントからリクエストを受け取ったら1秒毎に5回サーバ送信イベントを送信するHTTPサーバを作成し、起動します。

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

express-server-sse.js

var express = require('express');
var serverSentEvents = require('server-sent-events');
var http = require('http');

var app = express();
app.set('env', 'development');
app.set('x-powered-by', false);
app.set('case sensitive routing', true);
app.set('strict routing', true);
app.use(function (req, res, next) {
    res.status(200);
    res.type('text/plain; charset=utf-8');
    next();
});
app.get('/', serverSentEvents, function (req, res, next) {
    var i = 0;
    var io = setInterval(function () {
        i++;
        if (i < 6) {
            res.sse('data: ' + Math.random() + '\n\n');
        }
        else {
            clearInterval(io);
        }
    }, 1000);
});
app.get('*', function (req, res, next) {
    res.status(404);
    res.send(http.STATUS_CODES[404] + '\r\n');
});
app.all('*', function (req, res, next) {
    res.status(501);
    res.send(http.STATUS_CODES[501] + '\r\n');
});
var server = app.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);
});

使用パッケージ

  • express
    npm install expressでインストールします。
  • server-sent-events
    npm install server-sent-eventsでインストールします。

実行結果

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

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

C:\work\node>node express-server-sse.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
< Content-Type: text/event-stream
< Cache-Control: no-cache
< Connection: keep-alive
< Date: Sat, 13 May 2017 02:22:02 GMT
< Transfer-Encoding: chunked
<
:



















retry: 2000

data: 0.03507783673105691

data: 0.7916407929979072

data: 0.25631373928567425

data: 0.03948919944684426

data: 0.8515524805140511

:keep-alive

:keep-alive

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

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

関連

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

-express, Node.js