0

我希望将数据流式传输yaws我的彗星应用程序,我已经阅读并努力理解它,但是来自 yaws 的示例对我来说似乎有点复杂(我是 Erlang 的新手)。我就是摸不着头脑...

这是来自 yaws 的示例(我稍作修改):

out(A) ->
    %% Create a random number
    {_A1, A2, A3} = now(),
    random:seed(erlang:phash(node(), 1),
                erlang:phash(A2, A3),
                A3),
    Sz = random:uniform(1),

    Pid = spawn(fun() ->
                        %% Read random junk
                        S="Hello World",
                        P = open_port({spawn, S}, [binary,stream, eof]),
                        rec_loop(A#arg.clisock, P)
                end),

    [{header, {content_length, Sz}},
     {streamcontent_from_pid, "text/html; charset=utf-8", 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.

我需要将上面的脚本转换为可以与以下内容结合使用的脚本。

mysql:start_link(p1, "127.0.0.1", "root", "azzkikr", "mydb"),
                {data, Results}  = mysql:fetch(p1, "SELECT*FROM messages WHERE id > " ++ LASTID),
                {mysql_result, FieldNames, FieldValues, NoneA, NoneB} = Results,
                parse_data(FieldValues, [], [], [], [], [])

Whereparse_data(FieldValues, [], [], [], [], [])返回条目的 JSON 字符串。 结合此脚本应该不断检查数据库中的新条目,如果有,它应该像彗星一样获取。

谢谢你们,愿你们都去天堂!

4

1 回答 1

0

正如这个答案所解释的,有时您需要运行一个独立于任何传入 HTTP 请求的进程。对于您的情况,您可以使用发布/订阅的形式:

  • Publisher:当你的 Erlang 节点启动时,启动某种数据库客户端进程,或这样的进程池,执行你的查询并独立于 Yaws 运行。
  • 订阅者:当 Yaws 接收到 HTTP 请求并将其分派给您的代码时,您的代码订阅发布者。当发布者向订阅者发送数据时,订阅者将它们流式传输回 HTTP 客户端。

在这里详细说明完整的解决方案是不切实际的,但一般步骤是:

  • 当您的数据库客户端进程启动时,它们会将自己注册到一个pg2组或类似的东西中。使用类似的东西poolboy而不是滚动您自己的进程池,因为它们是出了名的难以正确处理。每个数据库客户端都可以是gen_server运行查询、接收数据库结果以及处理订阅请求调用的实例。
  • 当您的 Yaws 代码收到请求时,它会查找数据库客户端发布者进程并订阅它。订阅需要调用数据库客户端模块中的函数,该函数又用于gen_server:call/2,3与实际的gen_server发布者进程进行通信。订阅者使用Yaws 流功能(或SSEWebSocket)来完成与 HTTP 客户端的连接,并向其发送任何所需的响应标头。
  • 发布者存储订阅者的进程 ID,并在订阅者上建立一个监视器,以便在订阅者死亡或意外退出时清理订阅。
  • 发布者在发送给订阅者的消息中使用监视器的引用作为唯一 ID,因此订阅函数将该引用返回给订阅者。订阅者使用引用来匹配来自发布者的传入消息。
  • 当发布者从数据库中获得新的查询结果时,它会将数据发送给它的每个订阅者。这可以通过普通的 Erlang 消息来完成。
  • 订阅者使用Yaws 流功能(或SSEWebSocket功能)将查询结果发送到 HTTP 客户端。
  • 当 HTTP 客户端断开连接时,订阅者会调用另一个发布者函数来取消订阅。
于 2016-06-05T14:00:14.057 回答