4
3

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.

Spring BootでSSE

Last updated at Posted at 2020-01-20

Spring BootでSSE(text/event-stream)やりてえ〜。やりてえよね。

ということでおあつらえ向きなSseEmitterがある。

簡単な使い方

1秒ごとに現在日時を返すやつ。非同期実行自体は https://qiita.com/takkkun/items/1364fdaac8ae2b9fdc01 を参照。

@Service
class SseService {

  @Async
  fun emitDateTime(emitter: SseEmitter) {
    var finished = false
    while (!finished) {
      TimeUnit.SECONDS.sleep(1)

      try {
        sse.send(LocalDateTime.now().toString())
      }
      catch (e: IOException) {
        finished = true
      }
    }
  }
}

@Controller 
class SseController(private val service: SseService) {

  @RequestMapping(/* ... */)
  fun sse(): ResponseBodyEmitter {
    val emitter = SseEmitter()
    service.emitDateTime(emitter)
    return emitter
  }
}

これで以下のようなレスポンスが返ってくる。

$ curl -i 'http://localhost:8080/sse'
HTTP/1.1 200
Content-Type: text/event-stream;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 20 Jan 2020 07:01:31 GMT

data:2020-01-20T16:01:32.155751

data:2020-01-20T16:01:33.164949

data:2020-01-20T16:01:34.168721

data:2020-01-20T16:01:35.174836

data:2020-01-20T16:01:36.179743

...

タイムアウト

デフォルトのタイムアウトはSpring Bootが定めている。具体的にはspring.mvc.async.request-timeoutというプロパティで。単位はミリ秒。

もしくはSseEmitterのコンストラクタでも指定できる。この場合、コンストラクタに与えた値が優先される。

無期限にしたい場合は0を指定。

実際にタイムアウトが起きた場合は、SseEmitter#onTimeoutで指定したコールバックが呼ばれ、AsyncRequestTimeoutExceptionが投げられる。

クライアントから切断

クライアントから切断された瞬間にそれを検出する術はない、と思う。

ただ、クライアントから切断されている状態でSseEmitter#sendを呼び出すと、IOException(実際はそのサブクラスのClientAbortExceptionなはず)が投げられるので、それで検出することは可能。

最終的にSseEmitter#onErrorで指定したコールバックが呼ばれるので、それでも良いかな?

ちなみに@Asyncの中でハンドルされていない例外が発生すると、非同期処理実行の仕組みの方でログを記録するので、ちゃんとハンドルしてあげた方がベターだと思う(JavaだとIOExceptionがチェック例外なので強制されると思うけど)。

サーバーから完了

SseEmitter#completeを呼ぶとレスポンスが完了する。

クライアントから切断することがほとんどだとは思うけど、用途によってはあり得るので一応。

4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?