Процесс Erlang зависает

Я работаю на erlang в первый раз. каждый раз, когда я пытаюсь запустить процесс erlang, он зависает и не принимает ввод. Я использую плагин erlide в eclipse для тестирования кода erlang.

КОД ЕСТЬ::

-module(message_router).

%% ====================================================================
%% API functions
%% ====================================================================
%%-compile(export_all).
-export([start/0]).
-export([stop/1]).
-export([send_chat_message/3]).
-export([route_messages/0]).



%% ====================================================================
%% Internal functions
%% ====================================================================
start() ->
    spawn(message_router, route_messages, []).

stop(RouterPid) ->
    RouterPid ! shutdown.

send_chat_message(RouterPid, Addressee, MessageBody) ->
    io:format("send_chat_msg FROM:: ~p TO:: ~p ~n", [RouterPid, Addressee]),
    RouterPid ! {send_chat_msg, Addressee, MessageBody}.

route_messages() ->

receive
    {send_chat_msg, Addressee, MessageBody} ->
        io:format("recv_chat_msg PID:: ~p ~n", [Addressee]),
        Addressee ! {recv_chat_msg, MessageBody},
        route_messages();

    {recv_chat_msg, MessageBody} ->
        io:format("Received: ~p~n", [MessageBody]);

    shutdown ->
        io:format("Shutting down ~n");

    Oops ->
        io:format("Warning! Received: ~p~n", [Oops]),
        route_messages()
end.

Когда я нажимаю, попробуйте запустить код, как в оболочке

Eshell V5.10.4
(nodename@pa)1> P1 = message_router:start().
<0.1308.0>
(nodename@pa)2> P2 = message_router:start().
<0.1373.0>
(nodename@pa)3> chat_client:send_message(P1, P2, "FIRST Msg").
Sending chat message from chat_client
send_chat_msg FROM:: <0.1308.0> TO:: <0.1373.0> 

Все, что я ввожу в оболочку после этого, подействует. Также может кто-нибудь объяснить, как обрабатываются циклы в erlang и передовых методах.

[править]

код клиента чата:

-module(chat_client).
-export([send_message/3]).
send_message(RouterPid, Addressee, MessageBody) ->
    io:format("Sending chat message from chat_client~n"),
    message_router:send_chat_message(RouterPid, Addressee, MessageBody).

person Prajun Adhikary    schedule 12.01.2014    source источник
comment
Попробуйте позвонить message_router:send_message(P1, P2, "FIRST Msg").   -  person aggelgian    schedule 12.01.2014
comment
Вы смотрели в gen_servers? Это хорошая практика для таких примеров, как этот, и она немного облегчит вашу работу erlang.org /doc/man/gen_server.html | learnyousomeerlang.com/clients-and-servers   -  person danihodovic    schedule 12.01.2014
comment
Не могли бы вы показать код chat_client:send_message?   -  person Odobenus Rosmarus    schedule 13.01.2014
comment
Если у вас нет опыта работы с Erlang или даже с функциональным программированием, рассмотрите возможность чтения, чтобы освоиться. Если проблемы с книгами, есть отличные онлайн-руководства, подобные этому: learnyousomeerlang.com/content.   -  person Berzemus    schedule 13.01.2014
comment
Odobenus Rosmarus Вот код из chat_client -module(chat_client). -экспорт([отправить_сообщение/3]). send_message(RouterPid, Addressee, MessageBody) -> io:format(Отправка сообщения чата от chat_client~n), message_router:send_chat_message(RouterPid, Addressee, MessageBody).   -  person Prajun Adhikary    schedule 13.01.2014
comment
Берземус, я перешел по предложенной вами ссылке. Очень благодарен вам.   -  person Prajun Adhikary    schedule 13.01.2014
comment
Кажется, что вызов route_messages() отсутствует в предложении {recv_chat_msg,...}. Преднамеренный?   -  person shino    schedule 17.01.2014


Ответы (1)


Проблема в модуле. Назовите это message_router:send_chat_message(P1, P2, "FIRST Msg")
Посмотрите на этот пример и сравните с его:

При вызове модуля observer он регистрирует два процесса loop/0 и trans/0

-module(observer).
-export([observer/0, loop/0, trans/0]).

observer() ->
  register(loop, spawn(fun observer:loop/0)),
  register(trans, spawn(fun observer:trans/0)).

loop() ->
  receive
    {'PRINT', Msg} -> 
      io:format("print from ~p~n~p~n", [self(), Msg]), loop();
    {'EXIT', _FromPid} -> 
      io:format("Exit ~nFrom ~p", [_FromPid]), exit(self(), kill)
  end.

trans() ->
  receive
    {Command, Msg} -> io:format("transports from: ~p~n~p~n", [self(), Msg]),
                      loop ! {Command, Msg}
  end.

и иметь в модуле send_messenger одну функцию send_message, которая отправляет сообщения через trans:

-module(send_messenger).
-export([send_message/1]).

send_message({Command, Msg}) ->
  trans ! {Command, Msg},
  ok.

Я надеюсь, что это помогло вам!

person Зелёный    schedule 12.01.2014
comment
Я устал от предложенной вами команды. Я все еще застреваю. Я не могу понять, как зацикливается route_message(). - person Prajun Adhikary; 13.01.2014