查看源代码 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}
被调用。