According to the Erlang Reference Manual, the send operator (!) syntax is Expr1 ! Expr2
.
It states that
Expr1
can be a tuple in the form of {Name, Node}
, where "Name
is an atom and Node
is a node name, also an atom", and When using FreeSWITCH with mod_erlang_event
(that starts up an Erlang C node), and a message is sent with any atom as Name
, it will result in a response:
$ 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]
Why wouldn't this work with two regular Erlang nodes below?
The atoms above are also not registered processes, and message sending feels like a remote procedure call.
Peeked into mod_erlang_event
's source, but I don't have much C experience, and haven't used non-native Erlang nodes. It feels though as if running a C node would result in
(1) running an Erlang node
(2) with a process automatically started
(with the C logic serving as the receive
loop of that process)
(3) that will match any atom.
So maybe that is why that only explicitly registered processes can be used with native Erlang nodes. (Again, I'm probably completely wrong.)
Starting node "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]
Going back to node "abc" started earlier:
$ 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]
The freeswitch@tr2
and test@tr2
got also immediately connected as hidden nodes, but this behaviour seems to be the same with abc@tr2
and def@tr2
.
Should've just RTFM because the answer is right in the first section of C nodes (emphases mine):
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.