{noproc,{gen_server{call....在使用gen_server的简单rebar 3/Erlang应用程序中出错

qf9go6mv  于 2023-11-15  发布在  Erlang
关注(0)|答案(1)|浏览(222)

我快疯了。我知道这很简单。但我就是看不出来。
我有两个节点在同一台机器上运行。它们有一个共享的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@节点上。我用rebar 3和一个supervisor来启动它。启动时没有错误。
当我使用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)


我知道这将是一个额头拍击,嗯的经验。我只是没有其他人与我一起看这个。
谢谢.

mklgxw1f

mklgxw1f1#

发生这种情况是因为像gen_server:call(?MODULE,get)这样的调用会查找一个 * 本地 * 注册为?MODULE的进程,但您的服务器进程 * 全局 * 注册为?MODULE。因此将getState函数更改为:

getState()->
        io:format("getState called~n"),
        gen_server:call({global,?MODULE},get).

字符串
(That也意味着你不需要erpc-如果back_server模块加载在front@节点上,你可以直接调用back_server:getState(),它会将请求发送到另一个节点上的全局注册进程。

相关问题