Search code examples
functional-programmingerlangerlang-otp

How to send a message from one node to another node in Erlang OTP


We can send a message to an existing process via the shell as below. I register a process by its Username here (ex: alice) code:

start_link(Username) ->
  gen_server:start_link({local, Username}, ?MODULE, [Username], []).

stop(Username)->
  gen_server:stop(Username).

init([Username]) ->
  io:format("~p connected...",[Username]),
  {ok, #chat_server_state{
    username = Username
  }}.

Process started as below:

chat_client:start_link(alice).
alice connected...{ok,<0.143.0>}

I sent message hello to process alice and result as below:

alice ! hello. %%sent 'hello' atom to 'alice' process
hello   %% result

My problem is if I started two nodes with same coockie and connected both nodes with net_kernel, still why I cant send a message from one node to other node using the registered process name (instead of pid) as above procedure.

my code: here I register the process with the node name.

start_link(Username) ->
  gen_server:start_link({local, node()}, ?MODULE, [Username], []).

stop(Username)->
  gen_server:stop(Username).

init([Username]) ->
  io:format("~p connected...",[Username]),
  {ok, #chat_server_state{
    username = Username
  }}.

I started alice process on alice@... node.

(alice@DESKTOP-RD414DV)79> chat_client:start_link(alice).
alice connected...{ok,<0.280.0>}

This is where this alice process is registered with its node name

** Registered procs on node 'alice@DESKTOP-RD414DV' **
Name                  Pid          Initial Call                      Reds Msgs
'alice@DESKTOP-RD414D <0.250.0>    chat_client:init/1                  54    0

Why can't I send a message from this alice@..... node to another node (ex: bob@DESKTOP-RD414D by 'bob@DESKTOP-RD414D' ! hello. )

(alice@DESKTOP-RD414DV)71> whereis('alice@DESKTOP-RD414DV').                
<0.250.0>

I get this error:

(alice@DESKTOP-RD414DV)50> 'bob@DESKTOP-RD414DV' ! heelo.
** exception error: bad argument
     in operator  !/2
        called as 'bob@DESKTOP-RD414DV' ! heelo

Solution

  • To send a message to a registered process in any node, you can use the {Name :: atom(), Node :: node()} ! Message :: term() syntax:

    1> register(shell, self()).
    true
    2> shell ! test.
    test
    3> flush().
    Shell got test
    ok
    4> {shell, node()} ! test.
    test
    5> flush().
    Shell got test
    ok