First create an Erlang module called server that receives messages in the format {Sender,Data} and echoes the Data portion back to the Sender. Then create a Java class called EchoClient that prompts for a node to connect to and prompts in a loop for messages to send. You will need OtpErlang.jar in your build classpath and runtime classpath. I found it in /opt/local/lib/erlang/lib/jinterface-1.5.1/priv/ on Mac OS X. I had to install Erlang from source on Ubuntu since the APT package is missing Jinterface.
Listing of server.erl:
-module(server).
-compile(export_all).
start() -> register(server,spawn(fun loop/0)).
loop() ->
receive
{Sender,Data} ->
Sender ! Data,
loop();
shutdown -> ok
end.
Listing of EchoClient.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import com.ericsson.otp.erlang.*;
public class EchoClient {
public static void main(String[] args) throws Exception {
OtpNode node = new OtpNode("java");
OtpMbox mbox = node.createMbox("admin_gui");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String defaultServerNodeName = "erl_node@" + node.host();
System.out.format("Server Node to contact [%s]> ", defaultServerNodeName);
String serverNodeName = in.readLine();
if (serverNodeName == null || "".equals(serverNodeName)) {
serverNodeName = defaultServerNodeName;
}
OtpErlangTuple serverPidTuple = new OtpErlangTuple(new OtpErlangObject[] {
new OtpErlangAtom("server"), new OtpErlangAtom(serverNodeName)});
while (true) {
if (!node.ping(serverNodeName, 1000)) {
System.out.println("Erlang node is not available: " + serverNodeName);
System.exit(1);
}
System.out.print("Message (Hit Enter to send)> ");
String message = in.readLine();
if (message != null) {
mbox.send("server", serverNodeName, new OtpErlangTuple(
new OtpErlangObject[] {
mbox.self(), new OtpErlangList(message)}));
OtpErlangObject serverReply = mbox.receive(1000);
if (serverReply == null) {
System.out.println("WARN: Timeout when receiving reply");
} else {
System.out.format("%s replied : %s%n", serverPidTuple, serverReply);
}
}
}
}
}
Open an Erlang shell in the directory with server.erl by running erl -sname erl_node. From that shell compile and run the Erlang server module.
Listing of the Erlang shell interaction
$> erl -sname erl_node
Erlang R13B01 (erts-5.7.2) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.2 (abort with ^G)
(erl_node@alains_desktop)1> server:start().
true
(erl_node@alains_desktop)2> server ! {self(), hello}.
{<0.84.0>,hello}
(erl_node@alains_desktop)3> f(M), receive M -> {ok, M} after 100 -> {error,timeout} end.
{ok,hello}
(erl_node@alains_desktop)4>
Run the EchoClient Java program and either accept the default node or specify the name of another Erlang node you want to work with. Type messages in and see them echoed back to the EchoClient console.
Listing of the EchoClient Java program console interaction:
Server Node to contact [erl_node@alains_desktop]> [ENTER]
Message (Hit Enter to send)> Hello, Erlang![ENTER]
{server,erl_node@alains_desktop} replied : "Hello, Erlang!"
Message (Hit Enter to send)>
3 comments:
The server you defined doesn't echo its message. It would probably be better if it also wrapped its reply in the same way as the messages it receives.
Good catch Robert. I had put the wrong server.erl into the highlighter in my rush to publish this post. It is fixed now :)
I should probably also have wrapped the response as you suggest Robert. My understanding of the benefit of doing that is that it would make it possible to selectively receive the echo server's reply.
Post a Comment