如何正确使用 yaws_api:stream_process_deliver(Socket, IoList)
Posted
技术标签:
【中文标题】如何正确使用 yaws_api:stream_process_deliver(Socket, IoList)【英文标题】:How to use yaws_api:stream_process_deliver(Socket, IoList) properly 【发布时间】:2016-10-08 00:14:27 【问题描述】:我需要使用 Erlang/Yaws 将数据库数据/字符串流式传输到客户端。我找到了这个文档来实现这个,但是这个例子使用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
所以问题是如何在不使用端口的情况下流式传输文本/字符串?
【问题讨论】:
【参考方案1】:Yaws 示例创建了一个 OS 进程来读取 /dev/urandom
,这是一个提供伪随机值的特殊文件,它使用端口与该进程通信。它在作为内容流送器的 Erlang 进程中运行端口。
内容流媒体进程首先通过接收discard, YawsPid
或ok, YawsPid
等待来自Yaws 的指示。如果它得到丢弃消息,它就没有工作要做,否则它调用rec_loop/3
,它递归循环,从端口获取数据并将其流式传输到 Yaws HTTP 套接字。当rec_loop/3
从端口获得文件结束指示时,它通过调用yaws_api:stream_process_end/2
终止其流式传输,然后返回到rec_loop/2
,进而关闭端口并正常退出。
对于您的应用程序,您需要一个流式处理,就像 Yaws 示例一样,首先处理 discard, YawsPid
或 ok, YawsPid
。如果它得到ok, YawsPid
,它应该进入一个循环,接收提供你想要流式传输到HTTP客户端的文本的消息。当没有更多文本要发送时,它应该会收到某种消息告诉它停止,然后它应该正常退出。
【讨论】:
以上是关于如何正确使用 yaws_api:stream_process_deliver(Socket, IoList)的主要内容,如果未能解决你的问题,请参考以下文章
如何正确使用 Composer 安装 Laravel 扩展包