はじめに
ElixirにてCowboyを直接動かすための記事となります。
前回の記事では、sendfileメソッドにて送信時に直接ファイルを送信する方法を実装しました。
今回の記事ではStream通信に関して記載していきます。
バージョン
使用した言語やライブラリのバージョンは下記となります。
cowboy 1.0のバージョン
Version | |
---|---|
Elixir | 1.3.2 |
Erlang | 19.2 |
Cowboy | 1.0.4 |
cowboy 2.0のバージョン
Version | |
---|---|
Elixir | 1.3.2 |
Erlang | 19.2 |
Cowboy | 2.0.0-pre4 |
Stream通信
今回はStream通信についてです。
通信内容に関してはHTMLの通信を実施し、1つずつ画面の表示内容を増やしていきます。
画面だけ先に表示するためにStreamでの通信を行う場合などもあるかと思いますので役にたつのではないでしょうか。
cowboy 1.0の場合
lib/elixir_cowboy_example.ex
routes = [
{"/", ElixirCowboyExample.Handler, []},
# Add it.
{"/stream", ElixirCowboyExample.StreamHandler, []},
{"/sendfile", ElixirCowboyExample.SendFileHandler, []},
{"/cookie", ElixirCowboyExample.CookieHandler, []},
{"/upload", ElixirCowboyExample.UploadHandler, []},
{"/dynamic", ElixirCowboyExample.DynamicPageHandler, []},
{"/json", ElixirCowboyExample.JsonHandler, []},
{"/:html", ElixirCowboyExample.Handler, []},
{"/priv/static/js/:javascript", ElixirCowboyExample.JavascriptHandler, []},
{"/priv/static/css/:css", ElixirCowboyExample.CssHandler, []},
{"/priv/static/image/[...]", :cowboy_static, {:priv_dir, :elixir_cowboy_example, "static/image"}}
]
lib/elixir_cowboy_example/stream_handler.ex
defmodule ElixirCowboyExample.StreamHandler do
def init({:tcp, :http}, req, opts) do
{:ok, req, opts}
end
def handle(req, state) do
# stream通信を実施するための準備
{:ok, req} = :cowboy_req.chunked_reply(200, req)
# 2秒おきにHTML内容を送信実施する
:ok = :cowboy_req.chunk("<html><head>Hello world!</head>", req)
:timer.sleep(2000)
:ok = :cowboy_req.chunk("<body><p>Stream!</p>", req)
:timer.sleep(2000)
:ok = :cowboy_req.chunk("<p>Output!</p></body></html>", req)
{:ok, req, state}
end
def terminate(_reason, _req, _state) do
:ok
end
end
cowboy 2.0の場合
lib/elixir_cowboy_example.ex
routes = [
{"/", ElixirCowboyExample.Handler, []},
# Add it.
{"/stream", ElixirCowboyExample.StreamHandler, []},
{"/sendfile", ElixirCowboyExample.SendFileHandler, []},
{"/cookie", ElixirCowboyExample.CookieHandler, []},
{"/upload", ElixirCowboyExample.UploadHandler, []},
{"/dynamic", ElixirCowboyExample.DynamicPageHandler, []},
{"/json", ElixirCowboyExample.JsonHandler, []},
{"/:html", ElixirCowboyExample.Handler, []},
{"/priv/static/js/:javascript", ElixirCowboyExample.JavascriptHandler, []},
{"/priv/static/css/:css", ElixirCowboyExample.CssHandler, []},
{"/priv/static/image/[...]", :cowboy_static, {:priv_dir, :elixir_cowboy_example, "static/image"}}
]
lib/elixir_cowboy_example/stream_handler.ex
defmodule ElixirCowboyExample.StreamHandler do
def init(req, opts) do
# stream通信のための準備
req = :cowboy_req.stream_reply(200, req)
# 2秒おきにHTMLの内容を送信
# cowboy2.0では通信を続ける間は、:nofin を設定し、完了時に :fin を送るように設定を実施する
:cowboy_req.stream_body("<html><head>Hello world!</head>", :nofin, req)
:timer.sleep(2000)
:cowboy_req.stream_body("<body><p>Stream!</p>", :nofin, req)
:timer.sleep(2000)
:cowboy_req.stream_body("<p>Output!</p></body></html>", :fin, req)
{:ok, req, opts}
end
end
記載したコードの実行
コードの記述が完了しましたので、それでは実行していきましょう。
いつも通り iex -S mix
にて cowboy を実行していき、http://localhost:4000/sendfile
にアクセスしてみましょう。
2秒おきにHTMLの内容が追加で表示されれば成功です。
最後に
今回はstream通信を実施する方法を記載してきました。
上記でも記載しましたが、一括で送信するのではなくstreamで通信したいこともありますので役にたつのではないでしょうか。
それではまた次回