1

クライアントとサーバー間のメッセージ通信に影響を与える最初のプログラムを Erlang で作成しようとしています。理論的には、サーバーはクライアントからメッセージを受信しないと終了しますが、クライアント コードを編集してサーバーを再実行するたびに、古いコードが実行されます。新しいコードを表示するには、^G>q>erl>[コマンドを再入力] する必要があります。

-module(srvEsOne).

%%
%% export functions
%%

-export([start/0]).

%%function definition

start()->
    io:format("Server: Starting at pid: ~p \n",[self()]),
    case lists:member(serverEsOne, registered()) of
        true ->
            unregister(serverEsOne);                            %if the token  is present, remove it
        false ->
            ok
    end,
    register(serverEsOne,self()),
    Pid = spawn(esOne, start,[self()]),
    loop(false, false,Pid).

%
loop(Prec, Nrec,Pd)->
    io:format("Server: I am waiting to hear from: ~p \n",[Pd]),
    case Prec of
        true ->
            case Nrec of
                true ->     
                    io:format("Server: I reply to ~p \n",[Pd]),
                    Pd ! {reply, self()},
                    io:format("Server: I quit \n",[]),
                    ok;
                false ->
                    receiveLoop(Prec,Nrec,Pd)
            end;
        false ->
            receiveLoop(Prec,Nrec,Pd)
    end.

receiveLoop(Prec,Nrec,Pid) ->
    receive
        {onPid, Pid}->
            io:format("Server: I received a message to my pid from ~p \n",[Pid]),
            loop(true, Nrec,Pid);
        {onName,Pid}->
            io:format("Server: I received a message to name from ~p \n",[Pid]),
            loop(Prec,true,Pid)
    after
        5000->
            io:format("Server: I received no messages, i quit\n",[]),
            ok
    end.

そして、クライアントコードは読み取ります

-module(esOne).

-export([start/1, func/1]).

start(Par) ->
    io:format("Client: I am ~p, i was spawned by the server: ~p \n",[self(),Par]),

    spawn(esOne, func, [self()]),
    io:format("Client: Now I will try to send a message to: ~p \n",[Par]),
    Par ! {self(), hotbelgo},
    serverEsOne ! {self(), hotbelgo},

    ok.



func(Parent)->
    io:format("Child: I am ~p, i was spawned from ~p \n",[self(),Parent]).

サーバーはクライアントからのメッセージの受信に失敗していますが、より簡単な方法でコードを変更できるようになるまでは、賢明にもデバッグを開始することはできません。

4

2 に答える 2

2

モジュールを変更するときは、それをコンパイルする必要があります。

コマンド c(module) または c(module,[options]) を使用して erlang シェルで実行すると、モジュールの新しいコンパイル済みバージョンがそのシェルに自動的にロードされます。これは、起動するすべての新しいプロセスで使用されます。

生きていてすでに使用しているものについては、説明がより複雑であり、あなたが求めているものではないと思います。

複数の erlang シェルを実行している場合、モジュールをコンパイルしたシェルだけがそれをロードしました。つまり、他のシェルでは、モジュールが以前にロードされていた場合、基本的にそれらのシェルで既にモジュールを使用している場合、対応するプロセスが終了した場合でも、新しいバージョンは無視されます。

コマンド erlc を使用してコンパイルする場合も同じです。

これらすべての場合において、シェルでコマンド l(module) を使用して明示的にモジュールをロードする必要があります。

于 2013-10-26T10:02:13.787 に答える
0

サーバー ループには、ローカル関数呼び出しのみが含まれます。実行中のコードは、リモート (または外部) 関数呼び出しがある場合にのみ変更されます。したがって、最初にループ関数をエクスポートする必要があります。

-export([loop/3]).

そしてloop/3、関数内のすべての呼び出しをreceiveLoop/3次のように変更する必要があります

?MODULE:loop(...)

または、代わりに同じことを行うこともできますreceiveLoop/3。重要なアプリケーションのベスト プラクティスは、必要に応じてホット コード スワップを行うことです。そのためloop/3、特別なメッセージを受信した後にのみリモート/外部に変更します。

于 2013-10-26T11:30:40.257 に答える