如果远程节点上没有注册处理,分布式消息发送如何导致回复?
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
。
它指出
Expr1
可以是{Name, Node}
形式的元组,其中“Name
是一个原子,Node
是一个节点名,也是一个原子",和
- "分布式消息发送 [...] 永远不会失败"。
当使用 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@tr2
和test@tr2
也立即连接为隐藏节点,但这种行为似乎与abc@tr2
和def@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.
根据 Erlang 参考手册,the send operator (!) 语法是 Expr1 ! Expr2
。
它指出
Expr1
可以是{Name, Node}
形式的元组,其中“Name
是一个原子,Node
是一个节点名,也是一个原子",和- "分布式消息发送 [...] 永远不会失败"。
当使用 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@tr2
和test@tr2
也立即连接为隐藏节点,但这种行为似乎与abc@tr2
和def@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.