0

I'm trying to talk in a chatroom using erlang. Everything is almost good in it I think but none of the messages send to other users print to the console. I sent up some tests to see if anything would print and it looks like some stuff is printing, but none of the stuff that is supposed to be being message passed.

This chat example is taken from page 103 of this erlang documentation manual. I'm following the instructions that they post for peter, james, and fred talking in the chatroom on page 104, but I get no console output. I really get no notifications that the commands worked other than the standard ok or true that returns after I execute a funciton.

One thing that I think might be the cause is that I don't know what they mean when they state Configure the server_node() function.. I also just compiled the code by opening up erl -sname <name@messenger> and then typing c(messenger).

I want to know how to get the output that should be happening, and how to make sure I can do message passing between each of the members on the chatroom.


messenger.erl

-module(messenger).
-export([start_server/0, server/1, logon/1, logoff/0, message/2, client/2]).
%%% Change the function below to return the name of the node where the
%%% messenger server runs
server_node() ->
    messenger@super.
    %%% This is the server process for the "messenger"
    %%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]

server(User_List) ->
    receive
        {From, logon, Name} ->
            New_User_List = server_logon(From, Name, User_List),
            server(New_User_List);
        {From, logoff} ->
            New_User_List = server_logoff(From, User_List),
            server(New_User_List);
        {From, message_to, To, Message} ->
            server_transfer(From, To, Message, User_List),
            io:format("list is now: ~p~n", [User_List]),
            server(User_List)
    end.

%%% Start the server
start_server() ->
    register(messenger, spawn(messenger, server, [[]])).
    %%% Server adds a new user to the user list

server_logon(From, Name, User_List) ->
    %% check if logged on anywhere else
    case lists:keymember(Name, 2, User_List) of
    true ->
        From ! {messenger, stop, user_exists_at_other_node}, %reject logon
        User_List;
    false ->
        From ! {messenger, logged_on},
        [{From, Name} | User_List] %add user to the list
    end.

%%% Server deletes a user from the user list
server_logoff(From, User_List) ->
    lists:keydelete(From, 1, User_List).
    %%% Server transfers a message between user

server_transfer(From, To, Message, User_List) ->
    %% check that the user is logged on and who he is
    case lists:keysearch(From, 1, User_List) of
    false ->
        From ! {messenger, stop, you_are_not_logged_on};
    {value, {From, Name}} ->
        server_transfer(From, Name, To, Message, User_List)
    end.

%%% If the user exists, send the message
server_transfer(From, Name, To, Message, User_List) ->
%% Find the receiver and send the message
    case lists:keysearch(To, 2, User_List) of
    false ->
        From ! {messenger, receiver_not_found};
    {value, {ToPid, To}} ->
        ToPid ! {message_from, Name, Message},
        From ! {messenger, sent}
    end.

%%% User Commands
logon(Name) ->
    case whereis(mess_client) of
    undefined ->
        register(mess_client,
        spawn(messenger, client, [server_node(), Name]));
    _ -> already_logged_on
        end.

logoff() ->
    mess_client ! logoff.
    message(ToName, Message) ->
        case whereis(mess_client) of % Test if the client is running
    undefined ->
        not_logged_on;
    _ -> mess_client ! {message_to, ToName, Message},
    ok
    end.

%%% The client process which runs on each server node
client(Server_Node, Name) ->
    {messenger, Server_Node} ! {self(), logon, Name},
    await_result(),
    client(Server_Node).

client(Server_Node) ->
    receive

logoff ->
    {messenger, Server_Node} ! {self(), logoff},
    exit(normal);

{message_to, ToName, Message} ->
    {messenger, Server_Node} ! {self(), message_to, ToName, Message},
    await_result();

{message_from, FromName, Message} ->
    io:format("Message from ~p: ~p~n", [FromName, Message])
    end,
    client(Server_Node).

%%% wait for a response from the server
await_result() ->
    receive
    {messenger, stop, Why} -> % Stop the client
        io:format("~p~n", [Why]),
        exit(normal);
    {messenger, What} -> % Normal response
        io:format("~p~n", [What])
    end.
5
  • 2
    One difficulty here is that sending messages to a node that is not reachable fails silently. Check if the nodes can actually connect to each other by running net_adm:ping(messenger@super). in the shell. Erlang relies on normal host name resolution to find remote nodes, so this might work better if you change the node name to messenger@localhost instead. Commented Dec 3, 2018 at 13:27
  • @legoscia I can send messages if I do that. Thank-you. I think the problem definately stems from the fact that I didn't configure the server_node() function as the textbook states I should. I don't know what this means though. Do you know how to configure the function? Commented Dec 4, 2018 at 1:01
  • Change it to return messenger@localhost (or whatever your node's name is) instead of messenger@super. In a "real" program you would have the node name in a configuration file somewhere, but for a small example hard-coding it like this is simpler. Commented Dec 4, 2018 at 10:01
  • @legoscia That's what I am doing. I'm wondering if you know how to do the configuration file stuff though. Commented Dec 4, 2018 at 10:08
  • This answer shows one way to do it. Commented Dec 4, 2018 at 10:25

1 Answer 1

0

I know this is probably TOO LATE after all who the heck going to learn Erlang in 2025....
but if you are running on mac and some how previous ping pong example does not work for some reason either. RESTART your mac works...... I don't know what is going on but it works.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.