查看源代码 Phoenix.LiveView.UploadWriter 行为 (Phoenix LiveView v0.20.17)

提供将上传的块写入最终目标的行为。

默认情况下,上传被写入服务器上的临时文件,并由 LiveView 通过读取临时文件或将其复制到持久位置来使用。某些用例需要对上传的块进行自定义处理,例如将用户的上传流式传输到另一个服务器。在这些情况下,我们不希望将块写入磁盘,因为我们只需要将它们转发。

注意:上传写入器在通道上传进程内部运行,因此任何阻塞工作都会阻塞通道错误并导致通道进程崩溃。

可以将 Phoenix.LiveView.UploadWriter 的自定义实现传递给 allow_upload/3。若要使用选项初始化写入器,请定义一个三元函数,该函数返回一个 {writer, writer_opts} 的元组。例如,想象一个记录块大小并跟踪客户端发送的总字节数的上传写入器

socket
|> allow_upload(:avatar,
  accept: :any,
  writer: fn _name, _entry, _socket -> {EchoWriter, level: :debug} end
)

这样的 EchoWriter 可能如下所示

defmodule EchoWriter do
  @behaviour Phoenix.LiveView.UploadWriter

  require Logger

  @impl true
  def init(opts) do
    {:ok, %{total: 0, level: Keyword.fetch!(opts, :level)}}
  end

  @impl true
  def meta(state), do: %{level: state.level}

  @impl true
  def write_chunk(data, state) do
    size = byte_size(data)
    Logger.log(state.level, "received chunk of #{size} bytes")
    {:ok, %{state | total: state.total + size}}
  end

  @impl true
  def close(state, reason) do
    Logger.log(state.level, "closing upload after #{state.total} bytes}, #{inspect(reason)}")
    {:ok, state}
  end
end

当 LiveView 使用上传的条目时,它将接收从 meta 回调返回的 %{level: ...}。这允许写入器在处理块时保持状态,以便稍后在使用时中继到 LiveView。

关闭原因

当上传完成或取消时,会调用 close/2 回调。以下值可以传递

  • :done - 客户端发送了所有预期块,并且上传正在等待使用
  • :cancel - 上传被取消,可能是由服务器或客户端导航离开引起的。
  • {:error, reason} - 上传由于 write_chunk/2 返回的错误而取消。例如,如果 write_chunk/2 返回 {:error, :enoent, state},则上传将被取消,并且 close/2 将使用原因 {:error, :enoent} 被调用。

总结

回调

@callback close(state :: term(), reason :: :done | :cancel | {:error, term()}) ::
  {:ok, state :: term()} | {:error, term()}
@callback init(opts :: term()) :: {:ok, state :: term()} | {:error, term()}
@callback meta(state :: term()) :: map()
链接到此回调

write_chunk(data, state)

查看源代码
@callback write_chunk(data :: binary(), state :: term()) ::
  {:ok, state :: term()} | {:error, reason :: term(), state :: term()}