Erlang:如何使用gproc

时间:2015-09-02 17:18:19

标签: erlang publish-subscribe

我对gproc和Pub / Sub方法(https://github.com/uwiger/gproc#use-case-pubsub-patterns)感到困惑。 我无法理解如何从其他进程接收消息。

示例:

    -module(ws_handler).
    -export([init/2]). 

 init(Req, Opts) ->
    lager:info("WS: init ws handler"),
    gproc:reg({p, l, {?MODULE, WSNewMsgKey}}),
    {cowboy_websocket, Req, Opts}.

 process_data(Data) ->
    lager:info("WS: start processing of json data"),
    gproc:send({p, l, WSNewMsgKey}, {self(), WSNewMsgKey, Data}).

有2个进程,它们都注册为订阅者。他们应该相互分享传入的数据。我想我必须实现一些接口/功能,但是文档并不能确切地说明这一点。

1 个答案:

答案 0 :(得分:1)

我从来没有使用gproc,但是看起来似乎缺少两件事:WSNewMsgKey的定义(它在上面的代码段中从不在范围内)和某个接受子句的接收条款发送的消息:

-module(ws_handler).
-export([init/2]). 

init(Req, Opts) ->
    gproc:reg({p, l, {?MODULE, ws_event}}),
    {some_state_blah, Req, Opts}.

notify_peers(Event) ->
    gproc:send({p, l, ws_event}, {self(), ws_event, Event}).

......和其他地方

handle_info({From, ws_event, Event}, State) ->
    ok = handle_ws_event(From, Event).

或在您的循环中(如果您手动编写过程):

loop(State) ->
  receive
    {From, ws_event, Event} ->
        ok = handle_ws_event(From, Event),
        loop(State);
    Whatever ->
        % other stuff...
  end.

我不确定发送的消息是否会通过呼叫,演员表或正常消息发送(我假设是OTP通用演员或正常消息) - 但似乎应该发生这种情况。但是,在所有情况下,您都需要一个明确定义的密钥来标识正在发送的消息类别,在这里我使用了原子'ws_event'来明确这一点。

至于上面代码段的详细信息......您似乎是为了某种处理而同时向一堆进程广播相同的JSON消息?我不确定这会对你有什么影响 - 我无法想到广播原始JSON会有益的任何情况(除非需要在系统之外广播JSON而你是广播到一堆订阅的客户端套接字处理程序?)。所以我在上下文中感到困惑(你想要达到什么目的?)。

这似乎是文档打算使用它的方式 - 但我必须真正使用它才能确定。