1

根据 Erlang 参考手册,发送运算符 (!)的语法是Expr1 ! Expr2.
它指出

  • Expr1可以是 形式的元组{Name, Node},其中 "Name是一个原子,Node是一个节点名称,也是一个原子”,并且
  • 分布式消息发送 [...] 永远不会失败”。

使用FreeSWITCHmod_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@tr2and相同def@tr2

4

2 回答 2

0

消息发送“成功”(即不抛出错误)和“得到响应消息”之间存在差异。在我看来,在一种情况下,发送的消息成功并且返回了一条消息;在另一种情况下,发送的消息成功并且没有消息返回。

于 2019-11-22T01:15:35.067 回答
0

应该只是RTFM ,因为答案在C 节点的第一部分是正确的(重点是我的):

7.1 Erlang 程序

从 Erlang 的角度来看,C 节点被视为普通的 Erlang 节点。因此,调用函数 foo 和 bar 只需要向 C 节点发送一条消息,请求调用该函数并接收结果。发送消息需要接收者,即可以使用 pid 或元组定义的进程,由注册名称和节点名称组成。在这种情况下,元组是唯一的选择,因为没有已知 pid

{RegName, Node} ! Msg

节点名称 Node 是 C 节点的名称。如果使用短节点名称,则节点的普通名称为 cN,其中 N 是整数。如果使用长节点名称,则没有这样的限制。因此,使用短节点名称的 C 节点名称示例是 c1@idril,使用长节点名称的示例是 cnode@idril.ericsson.se。

注册名称 ,RegName可以是任何 atom。名字可以

  • 被 C 代码忽略,或者,
  • 例如,用于区分不同类型的消息
于 2019-11-24T05:55:51.310 回答