[英]erlang pass message from server to a different Node
I'm trying to get a simple erlang server to work where I'm trying to register the server, pass messages to the server which should register and create 2 processes on a different Node but I'm getting this error:我试图让一个简单的 erlang 服务器在我尝试注册服务器的地方工作,将消息传递给应该在不同节点上注册和创建 2 个进程的服务器,但我收到此错误:
{badarg,[{erlang,register,[printer1,<12172.86.0>],[]},
{testerl,server,1,[{file,"testerl.erl"},{line,13}]}]}
My code:我的代码:
-module(testerl).
-export([start_server/1,
server/1,
printer/0
]).
server(Node_1) ->
receive
finished ->
exit(normal);
{Message} ->
register(printer1, spawn(Node_1, testerl, printer, [])),
register(printer2, spawn(Node_1, testerl, printer, [])),
{printer1, Node_1} ! {Message},
{printer2, Node_1} ! {Message},
server(Node_1)
end.
printer() ->
receive
finished->
exit(normal);
{Message} ->
io:format("printer received msg ~p~n", [Message]),
server ! finished
end.
start_server(Node_1) ->
register(server, spawn(testerl, server, [Node_1])).
I can start the 2 Nodes with erl -sname [name], start the server with the name of the other Node but when I try to pass a message with server !我可以使用 erl -sname [name] 启动 2 个节点,使用另一个节点的名称启动服务器,但是当我尝试使用服务器传递消息时! "some message" it crashes.
“一些消息”它崩溃了。 What am I doing wrong here?
我在这里做错了什么? How can i register a process and call it so it executes on the other machine?
我如何注册一个进程并调用它以便它在另一台机器上执行?
You are getting the badarg error because you are attempting to register a non-local Pid via erlang:register/2.您收到 badarg 错误是因为您试图通过 erlang:register/2 注册非本地 Pid。
The documentation ( http://erlang.org/doc/man/erlang.html ) indicates:文档 ( http://erlang.org/doc/man/erlang.html ) 指出:
badarg
If PidOrPort is not an existing local process or port.
The result of your spawn(Node_1,...) is a Pid that is on another node (ie, Node_1).您的 spawn(Node_1,...) 的结果是另一个节点(即 Node_1)上的 Pid。 If you want to register a non-local Pid, you could use global:register_name.
如果要注册非本地 Pid,可以使用 global:register_name。
So:所以:
-module(testerl).
-export([start_server/1,
server/1,
printer/0
]).
server(Node_1) ->
receive
finished ->
exit(normal);
{Message} ->
global:register_name(printer1, spawn(Node_1, testerl, printer, [])),
global:register_name(printer2, spawn(Node_1, testerl, printer, [])),
global:send(printer1, {Message}),
global:send(printer2, {Message}),
server(Node_1)
end.
printer() ->
receive
finished->
exit(normal);
{Message} ->
io:format("printer received msg ~p~n", [Message]),
global:send(server, finished)
end.
start_server(Node_1) ->
global:register_name(server, spawn(testerl, server, [Node_1])).
Running this, I get:运行这个,我得到:
(node1@f0189805e911)59> testerl:start_server('node2@f0189805e911').
(node1@f0189805e911)60> yes
(node1@f0189805e911)61> global:send(server,{test}).
(node1@f0189805e911)62> printer received msg test
(node1@f0189805e911)63> printer received msg test
Of course, one need not use Registered Processes:当然,不需要使用注册进程:
-module(testerl).
-export([start_server/1,
server/3,
printer/1
]).
server(Node_1, P1, P2) ->
receive
finished ->
exit(normal);
{Message} ->
P1 ! {Message},
P2 ! {Message},
server(Node_1, P1, P2)
end.
printer(ServerPid) ->
receive
finished->
exit(normal);
{Message} ->
io:format("printer received msg ~p~n", [Message]),
ServerPid ! finished
end.
start_server(Node_1) ->
P1 = spawn(Node_1, testerl, printer, [self()]),
P2 = spawn(Node_1, testerl, printer, [self()]),
spawn(testerl, server, [Node_1, P1, P2]).
Running this:运行这个:
(node1@f0189805e911)14> Pid = testerl:start_server('node2@f0189805e911').
<0.117.0>
(node1@f0189805e911)15> Pid ! {test}.
{test}
printer received msg test
printer received msg test
(node1@f0189805e911)16>
To make that possible you need use Distributed Erlang .为了使这成为可能,您需要使用Distributed Erlang 。 To pass messages between nodes they need to be clustered.
为了在节点之间传递消息,它们需要集群。 This is done by using a cookie.
这是通过使用 cookie 来完成的。 To illustrate this I will use an example from LYSE (Fred Hèbert, 2013).
为了说明这一点,我将使用来自LYSE的示例(Fred Hèbert,2013 年)。
First we start two nodes首先我们启动两个节点
erl -sname node1 -setcookie 'asd11'
erl -sname node2 -setcookie 'asd11'
Check that the nodes are connected net_kernel:connect_node('node2@polar')
.检查节点是否已连接
net_kernel:connect_node('node2@polar')
。
We register a the console process itself on both我们在两者上注册了一个控制台进程本身
(node1@polare)1> register(server, self()).
(node2@polare)1> register(client, self()).
We will let the server answer to an incoming message from client.我们将让服务器回答来自客户端的传入消息。 On node1 we do
在 node1 上我们做
receive {hello, from, OtherShell} -> OtherShell ! <<"hey there!">> end.
Now can send a message from the client.现在可以从客户端发送消息。
{server, node1@polar} ! {hello, from, self()}.
On the first node you should see <<"hey there!">>
printed in its console.在第一个节点上,您应该看到
<<"hey there!">>
打印在其控制台中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.