How to make Erlang client/server connect with arguments/nodes from config?

ساخت وبلاگ

Vote count: 0

I'm writing a client/server System in Erlang and can't get them to connect. The nodes they should use are stored in config files, which are loaded upon starting them. They also use several distributed data structures. Problem is, I'm first starting the data structure, then the server (works fine) but when I start the client, it doesn't connect to anything and throws an exception.

Server:

-module(server).
-export([startServer/0,loopServer/7,node/0,log/0,name/0]).
-compile({no_auto_import,[node/0]}).
-import(werkzeug, [get_config_value/2,lengthSL/1,logging/2,reset_timer/3,get_config_value/2]).
-import(erlang, [append/2]).
log() -> erlang:list_to_atom(lists:concat(["Server@", node(),".log"])).
node() -> {ok,Config} = file:consult("configs/server.cfg"), {ok, Node} = werkzeug:get_config_value(node,Config), Node.
name() -> {ok,Config} = file:consult("configs/server.cfg"), {ok, Name} = werkzeug:get_config_value(servername,Config), Name.
%%Startet den Server und die darin enthaltene Schleife
startServer() -> {ok,Config} = file:consult("configs/server.cfg"), {ok, Name} = get_config_value(servername,Config), %%CMEM initialisieren {ok, RemTime} = get_config_value(cmemtime,Config), CMEM = cmem:initCMEM(RemTime, log()), %%HBQ-Prozess erzeugen {ok,HBQName} = get_config_value(hbqname,Config), {ok,HBQNode} = get_config_value(node,Config), HBQ = {HBQName,HBQNode}, {ok,Serverzeit} = get_config_value(serverzeit,Config), %%Zeitpunkt des Timer übergeben {ok, Timer} = timer:send_after(round(RemTime * 1000),Name,delServer), %%Prozess registrieren, Serverschleife mit allen Infos starten, plus NNr 1 ServerPid = spawn(?MODULE, loopServer, [Name,CMEM,HBQ,Timer,Serverzeit,Config,1]), register(Name,ServerPid), %%HBQ initialisieren HBQ ! {ServerPid, {request,initHBQ}}, {Config,CMEM,HBQ,ServerPid}.
loopServer(Name,CMEM,HBQ,Timer,Serverzeit,Config,NNr) -> receive %%Client fragt neue Nachrichten ab, dazu wird aus CMEM die aktuelle NNr für %%den Client angefordert und mit der ClientPID an die HBQ weitergegeben {ClientPID,getmessages} -> NewTimer = reset_timer(Timer,Serverzeit,delServer), ClientNNr = cmem:getClientNNr(CMEM, ClientPID), HBQ ! {self(), {request, deliverMSG, ClientNNr, ClientPID}}, logging(log(), lists:concat(["Server: Nachricht ", NNr, " wurde zugestellt.n"])), loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NNr); %%Nachricht soll in HBQ verschoben werden {dropmessage,[INNr,Msg,TSclientout]} -> NewTimer = reset_timer(Timer,Serverzeit,delServer), HBQ ! {self(), {request,pushHBQ,[INNr,Msg,TSclientout]}}, receive {reply,ok} -> logging(log(), lists:concat(["Server: Nachricht ", INNr, " wurde in HBQ eingefuegt.n"])) end, loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NNr); %%Client fragt naechste NNr ab, diese wird dem Zustand des Server entnommen {ClientPID,getmsgid} -> NewTimer = reset_timer(Timer,Serverzeit,delServer), ClientPID ! {nid, NNr}, NewNNr = NNr + 1, logging(log(), lists:concat(["Server: Nachrichtennumer ", NNr, " an ", erlang:pid_to_list(ClientPID), "gesendet.n"])), loopServer(Name,CMEM,HBQ,NewTimer,Serverzeit,Config,NewNNr); %%Server beendet sich selbst und zugleich die HBQ delServer -> HBQ ! {self(),{request,delHBQ}}, receive {reply,ok} -> logging(log(), lists:concat([lists:concat(["Server: Downtime ", werkzeug:timeMilliSecond(), " von ", name() ,"n"])])), ok end end.

Client:

-module(client).
-export([startClients/0,loopClient/4,spawnC/1,forLoop/3,mitServerVerbinden/6,configLaden/0]).
-import(werkzeug, [get_config_value/2]).
-import(timer, [apply_after/4]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Client %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%initClient
startClients() -> Config = configLaden(), {ok, ClientAnzahl} = werkzeug:get_config_value(clientanzahl, Config), {ok, ServerName} = werkzeug:get_config_value(servername, Config), {ok, ServerNode} = werkzeug:get_config_value(servernode, Config), ServerPid = {ServerName,ServerNode},
forLoop(ClientAnzahl, fun client:spawnC/1, ServerPid).
%%Hilfsfunktion fuer for-Schleife: Zaehlt runter,
%%ruft Funktion auf und gibt Ergebnisse als Liste zurueck
forLoop(Clients, Spawn, SPid) -> forLoop(Clients, Spawn, SPid, []).
forLoop(0, _Spawn, _SPid, ClientListe) -> ClientListe;
forLoop(Clients, Spawn, SPid, ClientListe) -> ClientListeNew = ClientListe ++ [Spawn(SPid)], ClientsNew = Clients - 1,
forLoop(ClientsNew, Spawn, SPid, ClientListeNew).
%%Neuen ClientProzess erzeugen
spawnC(ServerPid) -> Config = configLaden(), {ok, Lebenszeit} = werkzeug:get_config_value(lebenszeit, Config), {ok, Cookie} = werkzeug:get_config_value(cookie, Config), {ok, ServerNode} = werkzeug:get_config_value(servernode, Config), {ok, Wartezeit} = werkzeug:get_config_value(wartezeit, Config), ClientPid = erlang:spawn(?MODULE, mitServerVerbinden, [ServerPid, [], [], Wartezeit, ServerNode, Cookie]), timer:kill_after(Lebenszeit, ClientPid),
ClientPid.
%%mit Server Verbinden
mitServerVerbinden(ServerPid,Datei,NNummern,Wartezeit,ServerNode,Cookie) -> erlang:set_cookie(ServerNode,Cookie), pong = net_adm:ping(ServerNode),
loopClient(ServerPid,NNummern,Wartezeit,Datei).
%%loopClient
loopClient(ServerPid,NNummern,Wartezeit,Datei) -> %%Client wird zum Redakteur {NNummernNew, WartezeitNew, DateiNew} = nachrichtenSenden(5,ServerPid,NNummern,Wartezeit,Datei), %%Client wird zum Leser nachrichtenLesen(false, NNummernNew, ServerPid,DateiNew), %%Methode ruft sich selbst wieder auf loopClient(ServerPid, NNummernNew, WartezeitNew,DateiNew).
configLaden() -> {ok, Config} = file:consult("configs/client.cfg"), Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Redakteur %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%Nachricht soll vergessen werden
nachrichtenSenden(0,ServerPid,NNummern,Wartezeit,Datei) -> %%Naechste NNr beim Server anfragen ServerPid ! {self(),getmsgid}, receive %%Server sendet NNr {nid,NNr} -> %%Logeintrag werkzeug:logging(Datei,lists:concat([NNr, "te Nachricht um ", werkzeug:timeMilliSecond(), " vergessen zu senden. ******n"])) end, WartezeitNew = wartezeitBerechnen(Wartezeit), %%Rückgabewerte: Liste mit Nachrichtennummern fuer leser, neue Wartezeit, Logfile {NNummern,WartezeitNew,Datei};
%%Nachrichtennummer anfragen und erhalten, Nachricht schreiben
nachrichtenSenden(NachrichtenVorVergessen,ServerPid,NNummern,Wartezeit,Datei) -> Config = configLaden(), {ok, ServerNode} = werkzeug:get_config_value(servernode, Config), %%Naechste NNr beim Server anfragen ServerPid ! {self(),getmsgid}, receive %%Server sendet NNr {nid,NNr} -> %%Nachricht schreiben Nachricht = nachrichtSchreiben(NNr), %%NNr zur Liste hinzufuegen fuer Leser NNummernNew = NNummern ++[NNr], timer:sleep(Wartezeit), %%Nachricht an Server senden ServerPid ! {dropmessage,[NNr,Nachricht,erlang:now()]}, %%Logeintrag schreiben werkzeug:logging(Datei,lists:concat([Nachricht, " gesendet"])), %%Neue Wartezeit berechnen WartezeitNew = wartezeitBerechnen(Wartezeit), %%Zaehler dekrementieren NachrichtenVorVergessenNew = NachrichtenVorVergessen -1, %%Methode neu aufrufen nachrichtenSenden(ServerPid,NNummernNew,WartezeitNew,NachrichtenVorVergessenNew,Datei) end.
%%nachrichtSchreiben
nachrichtSchreiben(NNr) -> Config = configLaden(), {ok, Rechner} = werkzeug:get_config_value(rechner, Config), {ok, Praktikumsgruppe} = werkzeug:get_config_value(praktikumsgruppe, Config), {ok, Teamnummer} = werkzeug:get_config_value(teamnummer, Config),
lists:concat(["client@",Rechner, "_", Praktikumsgruppe, "_", Teamnummer, ": ", integer_to_list(NNr), "_te Nachricht. Sendezeit: ", werkzeug:timeMilliSecond()]).
%%Hilfsmethode: Intervall darf nicht kleiner als zwei Sekunden werden
minimumTime() -> 2000.
%%Berechnet das neue Zeitintervall, um die Haelfte groesser oder
%%kleiner als die alte Zeit, solange sie groesser gleich 2 Sekunden ist
wartezeitBerechnen(Wartezeit) -> GroesserKleiner = werkzeug:bool_rand(), HaelfteZeit = trunc(max(Wartezeit * 0.5, minimumTime())), if GroesserKleiner -> Wartezeit + HaelfteZeit; true -> max(Wartezeit - HaelfteZeit, minimumTime())
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Leser %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nachrichtenLesen(true,NNummern,ServerPid,Datei) -> ok;
nachrichtenLesen(false,NNummern,ServerPid,Datei) -> ServerPid ! {self(),getmessages}, receive {reply,Message,Terminated} -> nachrichtInLogSchreiben(Message,NNummern,Datei), nachrichtenLesen(Terminated,NNummern,ServerPid,Datei) end.
nachrichtInLogSchreiben([NNr,Msg,TSclientout,TShbqin,TSdlqin,TSdlqout],NNummern,Datei) -> Now = erlang:timestamp(), DLQInTrue = werkzeug:validTS(TSdlqin), DLQOutTrue = werkzeug:validTS(TSdlqout), DLQInZukunft = werkzeug:lessTS(Now, TSdlqin), DLQOutZukunft = werkzeug:lessTS(Now, TSdlqout), MsgVonGleichemClient = msgVonGleichemClient(NNr, Msg, NNummern), if DLQInTrue and DLQInZukunft -> Zeitunterschied = werkzeug:now2stringD(werkzeug:diffTS(TSdlqin, Now)), MsgNew = MsgVonGleichemClient ++ ", Zeitunterschied: " ++ Zeitunterschied, werkzeug:logging(Datei, MsgNew ++ "n"); DLQOutTrue and DLQOutZukunft -> Zeitunterschied = werkzeug:now2stringD(werkzeug:diffTS(TSdlqout, Now)), MsgNew = MsgVonGleichemClient ++ ", Zeitunterschied: " ++ Zeitunterschied, werkzeug:logging(Datei, MsgNew ++ "n"); true -> werkzeug:logging(Datei, MsgVonGleichemClient ++ "n") end.
msgVonGleichemClient(NNr,Msg,NNummern) -> MsgVonGleichemClient = lists:member(NNr, NNummern), if MsgVonGleichemClient -> Msg ++ "*******"; true -> Msg
end.

Config file for server:

{sizedlq,400}.
{servername,'serverpa'}.
{cmemtime,2000}.
{hbqname,'hbqpa'}.
{node,'hbqnode'}.
{serverzeit,50}.

Config file for client:

{wartezeit,20}.
{lebenszeit,240}.
{pratikumsgruppe,'2'}.
{teamnummer,'02'}.
{servername,'serverpa'}.
{clientanzahl,5}.
{servernode,'servernode'}.
{cookie,pa}.
{rechner,'rechner'}.

There are also files for the DLQ, HBQ and CMEM which are essentially queues and seem to be working fine. The problem is, when I compile them, the start the HBQ, then the server and then the client, I get

=ERROR REPORT==== 18-Apr-2017::10:25:46 ===
Error in process <0.104.0> with exit value: {distribution_not_started,[{auth,set_cookie,2,[{file,"auth.erl"},{line,119}]},{client,mitServerVerbinden,6,[{file,"client.erl"},{line,42}]}]}

So apparently there is an issue with the client not connecting to the server. This is my first time working with Erlang and distributed systems, so I have no idea what is going on.

Is it not enough to put the nodes and cookie into the configs and tell the components of the system to look there?

asked 33 secs ago

back soft...
ما را در سایت back soft دنبال می کنید

برچسب : نویسنده : استخدام کار backsoft بازدید : 316 تاريخ : سه شنبه 29 فروردين 1396 ساعت: 15:45