logging - 如何在 Elixir 中读取 HTTP 分块响应并向客户端发送分块响应?

标签 logging proxy elixir phoenix-framework chunked-encoding

我正在使用 Elixir/Phoenix,并且我有一个端点,它返回一个分 block 的响应,比如一个永无止境的日志行流。然而,日志行来自另一个服务 A,该服务也返回分 block 响应。我希望我的端点从服务 A 读取分 block 响应,并将它们也分 block 传递给客户端。本质上,它只是服务 A 的代理,但我不能让客户端直接连接到服务 A,因为我需要执行一些身份验证。

最佳答案

以下是使用 Phoenix 发送 block 数据的示例:

  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

有一些可用于 Elixir/Erlang 的 http 库;我喜欢HTTPoison

这是一个从 url 读取 block 并在它们进入时将其发送出去的示例:

  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

一些引用资料:

关于logging - 如何在 Elixir 中读取 HTTP 分块响应并向客户端发送分块响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43966598/

相关文章:

Python:自动记录类中每个方法的名称和输出

google-app-engine - 如何清除 Google Cloud Platform 中的 Stackdriver 日志?

wcf - 如何限制 WCF 日志记录

python - SSL 上的 MITM 代理卡在客户端的 wrap_socket 上

erlang - Elixir - 使用它代替普通的 erlang 是否会造成性能损失?

elixir - 如何在不预加载的情况下加载关联?

logging - ASP.NET Core日志记录-筛选出系统项目

performance - Mozilla Firefox 不接受用于脚本录制的 Jmeter 代理证书

ssl - firefox ssl 代理模式

elixir - 在预加载中添加 Group By 子句