Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Logging 如何在Elixir中读取HTTP分块响应并向客户端发送分块响应?_Logging_Proxy_Elixir_Phoenix Framework_Chunked Encoding - Fatal编程技术网

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

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

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

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

  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
一些参考资料:


您应该使用任何HTTP客户端并自行进行身份验证。我在这里看到的唯一问题是分块数据的大小,但使用流/流可能会有所帮助。哇!谢谢你的回答和推荐!我刚刚实现了这个,但是注意到当我在5秒钟左右没有收到另一个数据块时,连接就会断开。你知道保持tcp连接活动的方法吗?@JesseShieh啊,是的,
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