如何正确使用yaws_api:stream_process_deliver(Socket, IoList)
How to use yaws_api:stream_process_deliver(Socket, IoList) properly
我需要使用 Erlang/Yaws 将数据库 data/string 流式传输到客户端。我找到了此文档来实现此目的,但此示例使用 open_port
发送数据。
这是来自 [http://yaws.hyber.org/stream.yaws][1]
的示例
out(A) ->
%% Create a random number
{_A1, A2, A3} = now(),
random:seed(erlang:phash(node(), 100000),
erlang:phash(A2, A3),
A3),
Sz = random:uniform(100000),
Pid = spawn(fun() ->
%% Read random junk
S="dd if=/dev/urandom count=1 bs=" ++
integer_to_list(Sz) ++ " 2>/dev/null",
P = open_port({spawn, S}, [binary,stream, eof]),
rec_loop(A#arg.clisock, P)
end),
[{header, {content_length, Sz}},
{streamcontent_from_pid, "application/octet-stream", Pid}].
rec_loop(Sock, P) ->
receive
{discard, YawsPid} ->
yaws_api:stream_process_end(Sock, YawsPid);
{ok, YawsPid} ->
rec_loop(Sock, YawsPid, P)
end,
port_close(P),
exit(normal).
rec_loop(Sock, YawsPid, P) ->
receive
{P, {data, BinData}} ->
yaws_api:stream_process_deliver(Sock, BinData),
rec_loop(Sock, YawsPid, P);
{P, eof} ->
yaws_api:stream_process_end(Sock, YawsPid)
end.
我需要流式传输字符串,直到这里我才设法理解这个过程,除了 port_close(p) - 这显然关闭了端口。
rec_loop(Sock, P) ->
receive
{discard, YawsPid} ->
yaws_api:stream_process_end(Sock, YawsPid);
{ok, YawsPid} -> rec_loop(Sock, YawsPid, P)
end,
port_close(P),
exit(normal).
这部分没看懂
rec_loop(Sock, YawsPid, P) ->
receive
{P, {data, BinData}} ->
yaws_api:stream_process_deliver(Sock, BinData),
rec_loop(Sock, YawsPid, P);
{P, eof} ->
yaws_api:stream_process_end(Sock, YawsPid)
end.
现在,{P, {data, BinData}} ->
和 {P, eof} ->
都没有文档,我需要将内容类型
{streamcontent_from_pid, "application/octet-stream", Pid}.
更改为 {streamcontent_from_pid, "text/html; charset=utf-8", Pid}
所以问题是如何在不使用端口的情况下流式传输text/string?
Yaws 示例创建了一个 OS 进程来读取 /dev/urandom
,这是一个提供伪随机值的特殊文件,它使用一个端口与该进程通信。它在充当内容流传输器的 Erlang 进程中运行端口。
内容流媒体进程首先通过接收 {discard, YawsPid}
或 {ok, YawsPid}
来等待来自 Yaws 的指示。如果它收到丢弃消息,则无事可做,否则它会调用 rec_loop/3
,递归循环,从端口获取数据并将其流式传输到 Yaws HTTP 套接字。当 rec_loop/3
从端口获得文件结束指示时,它会通过调用 yaws_api:stream_process_end/2
和 returns 到 rec_loop/2
来终止其流式传输,这又会关闭端口并正常退出。
对于您的应用程序,您需要一个流式进程,就像 Yaws 示例一样,首先处理 {discard, YawsPid}
或 {ok, YawsPid}
。如果它得到 {ok, YawsPid}
,那么它应该进入一个循环接收消息,这些消息提供了您想要流式传输到 HTTP 客户端的文本。当没有更多的文本要发送时,它应该会收到某种消息告诉它停止,之后它应该正常退出。
我需要使用 Erlang/Yaws 将数据库 data/string 流式传输到客户端。我找到了此文档来实现此目的,但此示例使用 open_port
发送数据。
这是来自 [http://yaws.hyber.org/stream.yaws][1]
的示例out(A) ->
%% Create a random number
{_A1, A2, A3} = now(),
random:seed(erlang:phash(node(), 100000),
erlang:phash(A2, A3),
A3),
Sz = random:uniform(100000),
Pid = spawn(fun() ->
%% Read random junk
S="dd if=/dev/urandom count=1 bs=" ++
integer_to_list(Sz) ++ " 2>/dev/null",
P = open_port({spawn, S}, [binary,stream, eof]),
rec_loop(A#arg.clisock, P)
end),
[{header, {content_length, Sz}},
{streamcontent_from_pid, "application/octet-stream", Pid}].
rec_loop(Sock, P) ->
receive
{discard, YawsPid} ->
yaws_api:stream_process_end(Sock, YawsPid);
{ok, YawsPid} ->
rec_loop(Sock, YawsPid, P)
end,
port_close(P),
exit(normal).
rec_loop(Sock, YawsPid, P) ->
receive
{P, {data, BinData}} ->
yaws_api:stream_process_deliver(Sock, BinData),
rec_loop(Sock, YawsPid, P);
{P, eof} ->
yaws_api:stream_process_end(Sock, YawsPid)
end.
我需要流式传输字符串,直到这里我才设法理解这个过程,除了 port_close(p) - 这显然关闭了端口。
rec_loop(Sock, P) ->
receive
{discard, YawsPid} ->
yaws_api:stream_process_end(Sock, YawsPid);
{ok, YawsPid} -> rec_loop(Sock, YawsPid, P)
end,
port_close(P),
exit(normal).
这部分没看懂
rec_loop(Sock, YawsPid, P) ->
receive
{P, {data, BinData}} ->
yaws_api:stream_process_deliver(Sock, BinData),
rec_loop(Sock, YawsPid, P);
{P, eof} ->
yaws_api:stream_process_end(Sock, YawsPid)
end.
现在,{P, {data, BinData}} ->
和 {P, eof} ->
都没有文档,我需要将内容类型
{streamcontent_from_pid, "application/octet-stream", Pid}.
更改为 {streamcontent_from_pid, "text/html; charset=utf-8", Pid}
所以问题是如何在不使用端口的情况下流式传输text/string?
Yaws 示例创建了一个 OS 进程来读取 /dev/urandom
,这是一个提供伪随机值的特殊文件,它使用一个端口与该进程通信。它在充当内容流传输器的 Erlang 进程中运行端口。
内容流媒体进程首先通过接收 {discard, YawsPid}
或 {ok, YawsPid}
来等待来自 Yaws 的指示。如果它收到丢弃消息,则无事可做,否则它会调用 rec_loop/3
,递归循环,从端口获取数据并将其流式传输到 Yaws HTTP 套接字。当 rec_loop/3
从端口获得文件结束指示时,它会通过调用 yaws_api:stream_process_end/2
和 returns 到 rec_loop/2
来终止其流式传输,这又会关闭端口并正常退出。
对于您的应用程序,您需要一个流式进程,就像 Yaws 示例一样,首先处理 {discard, YawsPid}
或 {ok, YawsPid}
。如果它得到 {ok, YawsPid}
,那么它应该进入一个循环接收消息,这些消息提供了您想要流式传输到 HTTP 客户端的文本。当没有更多的文本要发送时,它应该会收到某种消息告诉它停止,之后它应该正常退出。