这让我抓狂。我知道这很简单。我就是看不到。
我有两个节点在同一台机器上运行。他们有一个共享的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)
我知道这将是一次额头拍击,呃经历。我只是没有其他人可以和我一起看这个。
谢谢。
发生这种情况是因为像
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()
,它会将请求发送到全局注册的进程在另一个节点上。)