如何正确使用yaws_api:stream_process_deliver(Socket,IoList)

时间:2016-06-07 22:28:16

标签: sockets erlang yaws

我需要使用 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 个答案:

答案 0 :(得分:1)

Yaws示例创建一个OS进程来读取/dev/urandom,这是一个提供伪随机值的特殊文件,它使用一个端口与该进程通信。它在Erlang进程中运行端口,该进程充当内容流。

内容流媒体流程首先通过接收{discard, YawsPid}{ok, YawsPid}来等待来自雅司的指示。如果它获得丢弃消息,则无需执行任何操作,否则调用rec_loop/3,它以递归方式循环,从端口接收数据并将其流式传输到Yaws HTTP套接字。当rec_loop/3从端口获得文件结束指示时,它会通过调用yaws_api:stream_process_end/2来终止其流式传输,然后返回rec_loop/2,然后关闭端口并正常退出。 / p>

对于您的应用程序,您需要一个流式处理流程,就像Yaws示例一样,首先处理{discard, YawsPid}{ok, YawsPid}。如果它得到{ok, YawsPid},它应该进入一个循环,接收消息,提供要传输到HTTP客户端的文本。当没有更多文本要发送时,它应该收到某种消息告诉它停止,之后它应该正常退出。