{noproc,{gen_server{call.... 使用 gen_server 的简单 rebar3/Erlang 应用程序中出现错误

问题描述 投票:0回答:1

这让我抓狂。我知道这很简单。我就是看不到。

我有两个节点在同一台机器上运行。他们有一个共享的cookie。我可以双向使用 net_adm:ping/1。

这是我尝试访问的 gen_server 的代码。我省略了注释和 -spec 行。

-module(back_server).
-behaviour(gen_server).

-export([start/0,start/3,stop/0,setState/1,getState/0]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

start() ->
    gen_server:start_link({global, ?MODULE}, ?MODULE, [], []).
start(Registration_type,Name,Args) ->
    gen_server:start_link({Registration_type, Name}, ?MODULE, Args, []).
stop() -> gen_server:call(?MODULE, stop).

setState(NewState)->
        io:format("setState called~n"),
        gen_server:cast(?MODULE,{update,NewState}).

getState()->
        io:format("getState called~n"),
        gen_server:call(?MODULE,get).
init([]) ->
        {ok,started}.
handle_call(get, _From, State) ->
        {reply,State,State};
handle_call(stop, _From, _State) ->
        {stop,normal,
                stopped,
          down}.

handle_cast({update,Value}, State) ->
        io:format("changing state from ~p to ~p~n",[State,Value]),
        {noreply,Value};
handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.
terminate(_Reason, _State) ->
    ok.
code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

此代码在 back@ 节点上运行。我正在使用 rebar3 和主管来启动它。启动时没有错误。

当我使用 front@ 中的 global:registered_names/0 时,我会看到服务器的注册名称 back_server。

当我致电

erpc:call('back@<ip>',back_server,getState,[]).
时,我收到以下错误。

getState called
** exception exit: {exception,{noproc,{gen_server,call,[back_server,get]}}}
     in function  erpc:call/5 (erpc.erl, line 503)

我知道这将是一次额头拍击,呃经历。我只是没有其他人可以和我一起看这个。

谢谢。

erlang distributed gen-server rebar3
1个回答
0
投票

发生这种情况是因为像

gen_server:call(?MODULE,get)
这样的调用会查找“本地”注册为“?MODULE
”的进程,但您的服务器进程“全局”
注册为“?MODULE”。因此将
getState
函数更改为:
getState()->
        io:format("getState called~n"),
        gen_server:call({global,?MODULE},get).

(这也意味着你不需要
erpc

- 如果

back_server
模块加载在
front@
节点上,你可以直接调用
back_server:getState()
,它会将请求发送到全局注册的进程在另一个节点上。)
    

© www.soinside.com 2019 - 2024. All rights reserved.