如果远程节点上没有注册处理,分布式消息发送如何导致回复?

How can distributed message sending result in a reply, if there is no registered processed on the remote node?

根据 Erlang 参考手册,the send operator (!) 语法是 Expr1 ! Expr2
它指出

当使用 FreeSWITCH with mod_erlang_event(启动 Erlang C 节点)时,消息以任何原子作为 Name 发送,将导致响应:

$ erl -sname test -setcookie ClueCon
Erlang/OTP 19 [erts-8.2.1] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Eshell V8.2.1  (abort with ^G)

(test@tr2)1> {polgarjenohivatalba, freeswitch@tr2} ! {api, msleep, 500}.
{api,msleep,500}

(test@tr2)2> receive X -> X after 1000 -> to end.        
{ok,"+OK"}

(test@tr2)3> {vizbolveszikiazoxigent, freeswitch@tr2} ! holafafonok.       
holafafonok

(test@tr2)4> flush().              
Shell got {error,undef}

(test@tr2)5> nodes().
[]

(test@tr2)6> nodes(connected).
[freeswitch@tr2]

为什么这不适用于下面的两个常规 Erlang 节点?

上面的原子也不是注册进程,消息发送感觉就像远程过程调用。

偷看了mod_erlang_event's source,但我没有太多的C经验,也没有使用过非原生的Erlang节点。感觉好像 运行 一个 C 节点会导致
(1) 运行 一个 Erlang 节点
(2) 自动启动一个进程
(使用 C 逻辑作为该进程的 receive 循环)
(3) 将匹配任何原子。

所以也许这就是为什么只有显式注册的进程才能与本机 Erlang 节点一起使用的原因。 (再一次,我可能完全错了。)

起始节点"def":

$ erl -sname def -setcookie lofa
Erlang/OTP 19 [erts-8.2.1] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Eshell V8.2.1  (abort with ^G)

(def@tr2)1> {lofa, abc@tr2} ! miez.
miez

(def@tr2)2> nodes(connected).
[abc@tr2]

返回节点 "abc" 较早开始:

$ erl -sname abc -setcookie lofa
Erlang/OTP 19 [erts-8.2.1] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Eshell V8.2.1  (abort with ^G)

(abc@tr2)1> receive X -> X after 27000 -> timeout end.
timeout

(abc@tr2)2> nodes(connected).
[def@tr2]

freeswitch@tr2test@tr2也立即连接为隐藏节点,但这种行为似乎与abc@tr2def@tr2相同。

消息发送 "succeeding" 和 "getting a response message" 之间存在差异,即不抛出错误。在我看来,在一种情况下,发送的消息成功并且返回了一条消息;另一种情况下发送消息成功,没有返回消息。

应该 RTFM because the answer is right in the first section of C nodes(强调我的):

7.1 Erlang Program

From Erlang's point of view, the C node is treated like a normal Erlang node. Thus, calling the functions foo and bar only involves sending a message to the C node asking for the function to be called, and receiving the result. Sending a message requires a recipient, that is, a process that can be defined using either a pid or a tuple, consisting of a registered name and a node name. In this case, a tuple is the only alternative as no pid is known:

{RegName, Node} ! Msg

The node name Node is to be the name of the C node. If short node names are used, the plain name of the node is cN, where N is an integer. If long node names are used, there is no such restriction. An example of a C node name using short node names is thus c1@idril, an example using long node names is cnode@idril.ericsson.se.

The registered name, RegName, can be any atom. The name can be

  • ignored by the C code, or,
  • for example, be used to distinguish between different types of messages.