Erlang Node Process Message Communication and Node Connection

  • The node actively disconnected, but the node actively reconnected by sending a message to the remote node process.
  • This may affect maintaining node topology.
  • Erlang VM 21+

Functions

Sending Messages

Dest ! Msg

erlang:send(Dest, Msg) -> Msg
erlang:send(Dest, Msg, Options) -> Res

erlang:send_nosuspend(Dest, Msg) -> boolean()
erlang:send_nosuspend(Dest, Msg, Options) -> boolean()

exit(Pid, Reason) -> true

Node Connection

%% Set the process to receive node connection and disconnection messages.
net_kernel:monitor_nodes(true, [{node_type, all}, nodedown_reason])

%% Disconnecting a node
net_kernel:disconnect(NodeName)

%% Connecting to a node
connect_node(Node) -> boolean() | ignored

Key Parameters

%% Sending message options
noconnect
nosuspend

%% Node startup parameters
erl -kernel dist_auto_connect never

Example

Node connection operation without setting the dist_auto_connect parameter

  • Central Node
%% Starting a central node
erl -setcookie '123456' -smp enable -name 'center@127.0.0.1'
%% Initializing a process
PID = erlang:spawn(fun() -> lists:foreach(fun(Index) -> receive Info -> io:format("Index=~w, Info=~w~n", [Index, Info]) end end, lists:seq(1, 10000000, 1)) end).
register(center_info, PID).
erlang:whereis(center_info).
  • Game Node
%% Start the game node
erl -setcookie '123456' -smp enable -name 'game@127.0.0.1'
%% View node connection information
nodes().
%% Set connection to the central node
true = erlang:set_cookie('center@127.0.0.1', '123456').
net_kernel:connect_node('center@127.0.0.1').
nodes().
%% Get and cache the central node process PID
CenterInfoPID = rpc:call('center@127.0.0.1', erlang, whereis, [center_info], 5000).

%% Test message communication.
erlang:send(CenterInfoPID, msg_hi).

%% Verify node connection.
net_kernel:disconnect('center@127.0.0.1').
nodes().

%% Send message. Message cannot be sent normally, and the node does not automatically connect.
erlang:send(CenterInfoPID, msg_noconnect, [noconnect]).
erlang:send_nosuspend(CenterInfoPID, msg_nosuspend_noconnect, [noconnect]).
nodes().

%% Send message. Message can be sent normally, and the node automatically connects.
CenterInfoPID !msg_yes.
erlang:send(CenterInfoPID, msg_hi).
erlang:send_nosuspend(CenterInfoPID, msg_nosuspend_hi).
erlang:exit(CenterInfoPID, done). %% The process exited and the node established a connection.
nodes().

Node connection operation: Set the dist_auto_connect = never parameter.

  • Game node
%% Start the game node.
erl -setcookie '123456' -smp enable -name 'game_noauto@127.0.0.1' -kernel dist_auto_connect never
%% View node connection information.
nodes().
%% Set the connection to the central node.
true = erlang:set_cookie('center@127.0.0.1', '123456').
net_kernel:connect_node('center@127.0.0.1').
nodes().
%% Get and cache the central node process PID.
CenterInfoPID = rpc:call('center@127.0.0.1', erlang, whereis, [center_info], 5000).

%% Tests message communication.
erlang:send(CenterInfoPID, msg_hi).

%% Verifies node connection.
net_kernel:disconnect('center@127.0.0.1').
nodes().

%% Sends a message. The message cannot be sent normally, and the node does not automatically connect.
erlang:send(CenterInfoPID, msg_noconnect, [noconnect]).
erlang:send_nosuspend(CenterInfoPID, msg_nosuspend_noconnect, [noconnect]).
nodes().
CenterInfoPID ! msg_yes.
erlang:send(CenterInfoPID, msg_hi).
erlang:send_nosuspend(CenterInfoPID, msg_nosuspend_hi).
erlang:exit(CenterInfoPID, done). %% The process did not exit.
nodes().

Node Connection Topology Design

  • Node connections use the Erlang default method - kernel dist_auto_connect once
  • Special service node topology is maintained independently, as follows:
%% Disconnect node connection
net_kernel:disconnect('center@127.0.0.1').
%% Set an invalid cookie
true = erlang:set_cookie('center@127.0.0.1', '').
  • Send messages using the noconnect parameter

Reference

If Dest is a pid(), it must be a pid() of a process created on the current runtime system instance. This process has either terminated or not. If Dest is an atom(), it is interpreted as the name of a locally registered process. The process referred to by the name is looked up at the time of timer expiration. No error is returned if the name does not refer to a process.