11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

HerokuでServer-Sent Events使うときのタイムアウト対策

Last updated at Posted at 2014-02-10

HerokuでSSE使ったら途中で切れることがあるなーと思ったら単なるリクエストタイムアウトだった。

ロングポーリング系は30秒最初のレスポンスがないか、途中で55秒何も送らなかっらコネクション切られるらしい。

SSEではコロンで始まる行はコメントとみなされるので、これをタイムアウト対策で定期的におくるのがよい。

例えばPOSTされたデータを定期的に通知するようなNode.jsのサーバーをこんな感じで書いてみた。

app.js
var express = require('express');
var http = require('http');
var app = express();
var EventEmitter = require('events').EventEmitter;
var ev = new EventEmitter();

app.use(express.bodyParser());
app.use(express.static(__dirname + '/public'));

app.get('/stream', function(req, res) {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'no-cache');

  // 55秒のタイムアウト対策
  var timer = setInterval(function() {
    res.write(':\n\n');
  }, 50000);

  // 最初の30秒のタイムアウト対策
  res.write(':\n\n');

  ev.on('data', function(data) {
    res.write('data: ' + data + '\n\n');
  });

  req.on('close', function() {
    clearTimeout(timer);
  });
});

app.post('/stream', function(req, res) {
  ev.emit('data', JSON.stringify(req.body));
  res.end();
});

var port = process.env.PORT || 3000;
http.createServer(app).listen(port, function() {
  console.log('Express server listening on port ' + port);
});

このサーバー起動してクライアント側をこんな感じで書いたら

public/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>SSE Sample</title>
</head>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script>
var es = new EventSource('/stream');
 
es.onmessage = function(event) {
  $('<div>').text(event.data).appendTo('body');
};
</script>
</body>
</html>

HTTPでPOSTしたらブラウザに表示されるはず。

$ curl -d 'foo=bar' http://localhost:3000/stream

ちなみにSSEの仕様に、Proxyのタイムアウトを防ぐためにコメント使うといいよって書いてあるので間違った使い方ではない。

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?