Logging 如何在Elixir中读取HTTP分块响应并向客户端发送分块响应?
我正在使用Elixir/Phoenix,我有一个端点,它返回一个分块的响应,比如说一个永无止境的日志行流。然而,日志行来自另一个服务A,该服务也返回分块响应。我希望我的端点读取来自服务A的分块响应,并将它们也分块传递给客户端。本质上,它只是服务a的代理,但我不能让客户端直接连接到服务a,因为我需要执行一些身份验证 以下是使用Phoenix发送区块数据的示例:Logging 如何在Elixir中读取HTTP分块响应并向客户端发送分块响应?,logging,proxy,elixir,phoenix-framework,chunked-encoding,Logging,Proxy,Elixir,Phoenix Framework,Chunked Encoding,我正在使用Elixir/Phoenix,我有一个端点,它返回一个分块的响应,比如说一个永无止境的日志行流。然而,日志行来自另一个服务A,该服务也返回分块响应。我希望我的端点读取来自服务A的分块响应,并将它们也分块传递给客户端。本质上,它只是服务a的代理,但我不能让客户端直接连接到服务a,因为我需要执行一些身份验证 以下是使用Phoenix发送区块数据的示例: def test_1(conn, _params) do conn = conn |> put_resp_con
def test_1(conn, _params) do
conn = conn
|> put_resp_content_type("text/event-stream")
|> send_chunked(200)
conn |> chunk("a")
conn |> chunk("b")
conn |> chunk("c")
# send data five times, once per second, to simulate a log
for n <- 1..5 do
conn |> chunk(Integer.to_string(n))
Process.sleep(1000)
end
conn
end
一些参考资料:
HTTPoison
有一个recv\u timeout
选项,默认值为5000
ms。你可以将其设置为较大的值,或者:无穷大
。类似于:HTTPoison.get!(url,%{},stream_to:self(),recv_timeout::infinity)
recv_timeout::infinity
通常非常危险。最好将超时设置为较长的时间,并让它最终失败。
def test_2(conn, _params) do
url = "http://localhost:4000/test_1"
%HTTPoison.AsyncResponse{id: id} = HTTPoison.get!(url, %{}, stream_to: self())
conn = conn
|> put_resp_content_type("text/event-stream")
|> send_chunked(200)
process_httpoison_chunks(conn, id)
end
def process_httpoison_chunks(conn, id) do
receive do
%HTTPoison.AsyncStatus{id: ^id} ->
# TODO handle status
process_httpoison_chunks(conn, id)
%HTTPoison.AsyncHeaders{id: ^id, headers: %{"Connection" => "keep-alive"}} ->
# TODO handle headers
process_httpoison_chunks(conn, id)
%HTTPoison.AsyncChunk{id: ^id, chunk: chunk_data} ->
conn |> chunk(chunk_data)
process_httpoison_chunks(conn, id)
%HTTPoison.AsyncEnd{id: ^id} ->
conn
end
end