目的
ひとつの escript を ノード A では server モードで起動して, ノード B では client モードで起動すると, ノード B の escript がノード A の escript に connect しにいき,互いに Message を送受信できるような escriptをつくりたい.
忘備録程度にまとめる.
A$ ./myescript --server
waiting for connection...
... (waiting) ...
B connected.
B sent me message: connected
B$ ./myescript --client A
connecting to A... connected.
sending "connected" to A... sent
成果物
-
net_kernel:start([NodeName])
で long-name を設定できる. - escript を実行しているメインプロセスの pid がわからないので, escript 起動時に
register/2
しておく. - メッセージを送る際は対象ノードに rpc し,メインプロセスの名前に向かって
!
する.
-module(myapp).
%%
%% $./myapp hoge server
%% I am `hoge@localhost`
%% ...
%% received: {<5437.2.0>,connected}
%%
%% $./myapp fuga client "hoge@localhost"
%% I am 'fuga@mlocalhost'
%% connected to 'localhost'
%%
-export([
main/1,
rpc_send_message/1
]).
%% Macro
-define(MYNAME, myname).
%% Exported
main([NodeNameStr, Command|Rest]) ->
NodeName = list_to_atom(NodeNameStr),
net_kernel:start([NodeName]),
io:format("I am ~p~n", [node()]),
true = register(?MYNAME, self()),
case Command of
"server" ->
do_receive();
"client" ->
[ServerNodeStr] = Rest,
do_connect(list_to_atom(ServerNodeStr))
end.
rpc_send_message(Msg) ->
?MYNAME ! Msg.
%% Internals
do_receive() ->
receive
Msg -> io:format("received: ~p~n", [Msg])
end.
do_connect(ServerNode) ->
case net_kernel:connect(ServerNode) of
true ->
io:format("connected to ~p~n", [ServerNode]),
Self = self(),
rpc:call(ServerNode, myapp, rpc_send_message, [{Self, connected}]);
false ->
io:format("connect failed~n")
end.