我正在尝试将一台gen_server连接到另一台gen_server,并且在连接期间,服务器需要互相监视,并知道服务器何时崩溃,整个节点还是服务器进程。在我执行第一个start_link之后,其中一台服务器崩溃后,另一台服务器从代码中的监视器获取了一条消息(handle_info函数已激活),但是第二次发生时,监视器将信息直接发送到外壳程序(消息不会通过handle_info传递,而是直接转到仅在shell内使用flush()可见的shell),并且假定从监视器发出警报的服务器未收到任何消息。 我在发送方的代码:
handle_call({connect, Node, Who}, _From, _State) ->
case Who of
cdot -> ets:insert(address, {cdot, Node}), ets:insert(address,
{Node, cdot}), monitor_node(Node, true);
cact -> ets:insert(address, {cact, Node}), ets:insert(address,
{Node, cdot}), monitor_node(Node ,true);
ctitles -> ets:insert(address, {ctitles, Node}),
ets:insert(address, {Node, cdot}), monitor_node(Node, true);
_-> ok
end,
[{_, Pid2}] = ets:lookup(?name_table3, pidGui),
Pid2 ! {db, "Node "++ atom_to_list(Who) ++ " connected"}, %print to
gui witch node was connected
{reply, {{node(), self()}, connected}, node()};
接收方的是:
connect() ->
{{Node, Pid}, Connected} = gen_server:call(server_node(), {connect,
node(), cact}),
monitor_node(Node, true),
monitor(process, Pid),
Connected.
请任何人告诉我为什么会这样吗?
节点或进程监视也是如此
答案 0 :(得分:2)
如果在shell中收到第二条监视消息,那是因为您在shell上下文中调用了connect函数。
检查如何调用此函数,它必须在服务器上下文中完成,这意味着在handle_call,handle_cast或handle_info函数内部。
答案 1 :(得分:0)
在我执行第一个start_link之后,其中一台服务器崩溃了 其他服务器在代码中从监视器获取消息,但是当它 发生第二次
听起来好像您在服务器崩溃后正在启动新服务器。您是否在新服务器Pid上调用monitor()?
A monitor is triggered only once,之后将其从 监视过程和被监视实体。显示器被解雇 当受监视的进程或端口终止时,该端口不存在 创建时刻或与它的连接丢失。在这种情况下 与连接有关,如果事实仍然存在,我们将失去有关事实的知识 或不。调用demonitor / 1时,监视也会关闭。