How to make Erlang client/server connect with arguments/nodes from config? - erlang
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 distributed data strutures which are essentially queues and seem to be working fine:
HBQ:
-module(hbq).
-export([startHBQ/0, checkTransfer/6,loophbq/4]).
%% HBQ !{self(), {request,pushHBQ,[INNr,Msg,TSclientout]}}
startHBQ() ->
startHBQ("./configs/server.cfg").
%% Used for starting the HBQ with a custom config file
startHBQ(Configfile) ->
%%Config und Namen auslesen
Config = loadConfig(Configfile),
Config = loadConfig(Configfile),
%%{ok,Config} = file:consult("./config/server.cfg"),
{ok,HBQName} = werkzeug:get_config_value(hbqname,Config),
%%Prozess der HBQ starten
HBQPid = spawn(?MODULE,loophbq,[[],[],Config, 1]),
%%Prozess registrieren
register(HBQName,HBQPid),
HBQPid.
loophbq(HBQ,DLQ,Config,CurrNumber) ->
receive
%%initialisere HBQ und DLQ, sendet ok an Server
{ServerPid,{request,initHBQ}} ->
HBQList = [],
Log = log(Config,["HBQ>>> initialisiert worden von ", ServerPid, ".\n"]),
{ok,DLQSize} = werkzeug:get_config_file(sizedlq,Config),
DLQ = dlq:initDLQ(DLQSize,Log),
ServerPid ! {reply,ok},
loophbq(HBQList, DLQ ,Config, CurrNumber);
%%fuegt der Msg einen Zeitstempel hinzu, fuegt sie in HBQ ein, sendet ok
{ServerPid,{request,pushHBQ,[NNr,Msg,TSclientout]}} ->
TShbqin = werkzeug:timeMillliSecond(),
NewMessage = {NNr,lists:concat(Msg,["HBQ in: ",TShbqin])},
Log = log(Config,["HBQ>>> Nachricht ",NNr, "in HBQ eingefügt.\n"]),
NewHBQ = [HBQ|NewMessage],
lists:sort(fun({A,_},{B,_}) -> A=<B end),
checkTransfer(NewHBQ, CurrNumber, Config, DLQ,TSclientout,TShbqin),
ServerPid ! {reply,ok},
loophbq(NewHBQ, DLQ ,Config, CurrNumber);
%%DLQ soll über HBQ Nachricht an Client senden
{ServerPid,{request,deliverMSG,NNr,ToClient}} ->
{ok, HBQName} = werkzeug:get_config_value(hbqname, Config),
Log = lists:concat(["HB-DLQ#", HBQName, ".log"]),
Datei = erlang:list_to_atom(Log),
log(Config, ["HBQ>>> dlq:delivermsg", NNr, pid_to_list(ToClient), "\n"]),
NNrDLQ = dlq:deliverMSG(NNr, ToClient, DLQ, Datei),
ServerPid ! {reply, NNrDLQ},
loophbq(HBQ, DLQ ,Config, CurrNumber);
%%Terminiert Prozess der DLQ
{ServerPid,{request,delHBQ}} ->
ServerPid ! {reply,ok},
ok
end.
%%CheckTransfer
checkTransfer(HBQ, Number, Config, [DLQ,Size],TSclientout,TShbqin) ->
Datei = log(Config, ["HBQ>>> Nachricht Nr ", Number, " wird in DLQ uebertragen\n"]),
FoundMatch = lists:keyfind(Number, 1, HBQ),
if FoundMatch =:= false ->
if(length(HBQ)>Size*0.667) ->
[{MinNNr,_}|_] = HBQ,
%wegen sort ist immer die kleinste NNr vorne in der Liste
NewMessage = {MinNNr-1,lists:concat(["Weiß noch nicht was hier reinsoll: ",werkzeug:timeMilliSecond()])},
NewHBQ = lists:append([{MinNNr-1,NewMessage}], HBQ),
log(Config,["HBQ>>> Fehlernachricht fuer Nachrichten ",Number," bis",MinNNr-1, " generiert.\n"]),
NewNumber = MinNNr-1,
checkTransfer(NewHBQ, NewNumber, Config,[DLQ,Size],TSclientout,TShbqin);
true -> ok
end;
true ->
{MatchNr,Msg} = FoundMatch,
dlq:push2DLQ([MatchNr, Msg, TSclientout, TShbqin], DLQ, Datei),
lists:delete(FoundMatch, HBQ),
checkTransfer(HBQ, Number+1, Config,[DLQ,Size],TSclientout,TShbqin)
end.
log(Config,Message) ->
{ok,HBQNode} = werkzeug:get_config_value(node,Config),
DateiName = lists:concat(["HB-DLQ#", HBQNode,".log"]),
Datei = erlang:list_to_atom(DateiName),
werkzeug:logging(Datei, lists:concat(Message)),
Datei.
%%Dummy-Nachrichten schreiben um Lücken in der HBQ zu füllen wenn sie kritische Größe erreicht
%%Methode um zu prüfen, ob Nachrichten in DLQ geschoben werden können, das dann auch machen
loadConfig(Configfile) ->
{ok, Config} = file:consult(Configfile),
Config.
DLQ:
-module(dlq).
-export([initDLQ/2, delDLQ/1, expectedNr/1, push2DLQ/3, deliverMSG/4]).
%%Initialisiert DLQ mit Kapazitaet Size, Log in Datei
initDLQ(Size, Datei) ->
werkzeug:logging(Datei,lists:concat(["DLQ>>> intitialisiert worden mit Groesse ",Size,".\n"])),
[[],Size].
%%Loescht DLQ
delDLQ(_Queue) -> ok.
%%Liefert NNr die als naechstes in DLQ gespeichert werden kann
%%expectedNr(Queue)
expectedNr([[], _Size]) -> 1;
expectedNr([[[NNr, _Msg, _TSclientout, _TShbqin, _TSdlqin] | _Rest], _Size]) -> NNr + 1.
%%Speichert Nachricht in DLQ, fuegt Zeitstempel hinzu, Rueckgabe: Modifizierte DLQ
%%push2DLQ([NNr, Msg, TSclientout, TShbqin], Queue, Datei)
%%Fehlt noch: Abfrage, ob das die passende Nummer ist!
push2DLQ([NNr, Msg, TSclientout, TShbqin], [DLQ,Size], Datei) ->
if
length(DLQ) < Size ->
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", NNr, " in DLQ eingefügt.\n"])),
[[[NNr, Msg, TSclientout, TShbqin, erlang:now()] | DLQ], Size];
length(DLQ) =:= Size ->
[LastNNr, _Msg, _TSclientout, _TShbqin, _TSdlqin] = lists:last(DLQ),
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", LastNNr, " aus DLQ entfernt.\n"])),
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", NNr, " in DLQ eingefügt.\n"])),
[[[NNr, Msg, TSclientout, TShbqin, erlang:now()] | lists:droplast(DLQ)], Size]
end.
%%Sendet Nachricht an Leser-Client
deliverMSG(MSGNr, ClientPID, Queue, Datei) ->
%%Aendern: MSGNer = -1, flag am Ende der Reply (siehe zeile 42)
[{NewestNr,Msg}|Rest] = Queue,
if MSGNr > NewestNr ->
DummyMessage = {-1,lists:concat(["DLQ in: ",werkzeug:timeMilliSecond()])}, %% -1 Flag
werkzeug:logging(Datei, lists:concat(["DLQ>>> DummyNachricht fuer ",MSGNr," an Client ",ClientPID, " ausgeliefert.\n"])),
ClientPID ! {reply,Msg,true}
end,
%%%%%%Ab hier noch aendern bzgl Flag
FoundMatch = lists:keyfind(MSGNr, 1, Queue),
if
FoundMatch =:= false ->
deliverMSG(MSGNr+1, ClientPID, Queue, Datei),
if
MSGNr =:= NewestNr ->
{Number,Msg} = FoundMatch,
NewMessage = {Number,lists:concat(Msg,["DLQ in: ",werkzeug:timeMilliSecond()],-1)},
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", Number, " an Client ",ClientPID, " ausgeliefert.\n"])),
ClientPID ! {reply,Msg,false};
true ->
{Number,Msg} = FoundMatch,
NewMessage = {Number,lists:concat(Msg,["DLQ in: ",werkzeug:timeMilliSecond()],0)},
werkzeug:logging(Datei, lists:concat(["DLQ>>> Nachricht ", Number, " an Client ",ClientPID, " ausgeliefert.\n"])),
ClientPID ! {reply,Msg,false}
end;
true ->
ok
end.
CMEM:
-module(cmem).
-export([initCMEM/2, delCMEM/1, updateClient/4, getClientNNr/2]).
-import(werkzeug, [get_config_value/2,lengthSL/1,logging/2,reset_timer/3,get_config_value/2,getUTC/0]).
%%Initialisiert CMEM
initCMEM(RemTime, Datei) -> werkzeug:logging(Datei, lists:concat(["CMEM>>> initialisiert mit ", RemTime, " Sekunden\n"])),
[[], RemTime].
%%Loescht CMEM
delCMEM(_CMEM) -> ok.
%%Speichert/aktualisiert Client und NNr im CMEM,
updateClient([CMEM, RemTime], ClientID, NNr, Datei) ->
ClientTS = getUTC(),
logging(Datei, lists:concat(["CMEM>>> Client ", ClientID, " wird aktualisiert.\n"])),
[lists:keystore(ClientID, 1, CMEM, {ClientID, NNr, ClientTS}), RemTime].
%%Gibt naechste vom Client erwartete NNr zurueck
%%Es wird geprueft ob Client in der Liste steht und dann
%%mit diesem Wissen eine Hilfsfunktion aufgerufen
getClientNNr([CMEM, RemTime], ClientID) ->
ClientBekannt = lists:keymember(ClientID, 1, CMEM),
isClientKnown([CMEM, RemTime], ClientID, ClientBekannt).
%%Client ist nicht bekannt: Naechste NNr = 1
isClientKnown(_CMEM, _ClientID, false) -> 1;
%% Der Client ist bekannt.
%%Zeit noch nicht abgelaufen: Gibt naechste Nummer aus
%%Zeit abgelaufen: Naechste NNr = 1
isClientKnown([CMEM, RemTime], ClientID, true) ->
{ClientID, NNr, ClientTS} = lists:keyfind(ClientID, 1, CMEM),
RemainingTime = ClientTS + RemTime,
Now = getUTC(),
if
RemainingTime >= Now -> NNr + 1;
true -> 1
end.
The client is supposed to contact the server sending it a message, the server puts it in data structures which send it back to the client under the right circumstances.
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?
The error distribution_not_started is returned by the auth module when the erlang VM calling it does not have a name. Ensure that a -sname or -name flag is passed when starting erlang e.g.:
erl -sname test
Related
Dashboard Tableau Filter
ich habe zwei Kreuztabellen im Tableau angelegt. Die erste Kreuztabelle habe ich mit einem Filter im Bericht hinterlegt. Zeige mir alle IDs an, wo Updated_By bestimmter User "Test" drin steht. Das funktioniert. Parallel dazu habe ich mir eine Kreuztabelle angelegt, die mir Details zeigen soll. Alle Zeilen anzeigen lassen mit der ID, unabhängig von Updated_By User "Test". Jetzt sollen diese beiden Tabellen in ein Dashboard, da sind sie schon. Filter ist aktiviert für Kreuztabelle 1. Mir werden alle Vorgänge angezeigt, wo der Update User "Test" enthalten ist. Nun möchte ich auf die ID klicken (Tabelle 1), welche auch in der Tabelle 2 enthalten ist, und alle Datensätze zu der ID angezeigt bekommen, allerdings den kompletten Vorgang nicht nur die Upbdates_BY "Test" - sondern die ganze Historie des Vorganges. Hat hier jemand einen Rat für mich?
MQTT-SN Gateway - Not able to publish or changed my clientID, but able to connect and subscribe?
I have a project using MQTT-SN protocol, I use this https://github.com/S3ler/arduino-mqtt-sn-client as my MQTT-SN Client (I'm Using nodeMCU same as Arduino ESP8266) , my MQTT-SN Gateway use paho.mqtt-sn.embedded-c on my laptop and for my broker I use Mosquitto on my laptop too this is the code for the MQTT-SN client #include <ESP8266WiFi.h> #include <WiFiUdp.h> #include <WiFiUdpSocket.h> #include <MqttSnClient.h> const char* ssid = "xxx"; const char* password = "xxx"; #define buffer_length 10 char buffer[buffer_length + 1]; uint16_t buffer_pos = 0; IPAddress gatewayIPAddress(192, 168, 1, 151); uint16_t localUdpPort = 1884; // #define gatewayHostAddress "arsmb.de" WiFiUDP udp; WiFiUdpSocket wiFiUdpSocket(udp, localUdpPort); MqttSnClient<WiFiUdpSocket> mqttSnClient(wiFiUdpSocket); const char* clientId = "Kevin"; char* subscribeTopicName = "test"; char* publishTopicName = "test"; int8_t qos = 0; void mqttsn_callback(char *topic, uint8_t *payload, uint16_t length, bool retain) { Serial.print("Received - Topic: "); Serial.print(topic); Serial.print(" Payload: "); for (uint16_t i = 0; i < length; i++) { char c = (char) * (payload + i); Serial.print(c); } Serial.print(" Lenght: "); Serial.println(length); } void setup() { Serial.begin(115200); delay(1000); pinMode (sensor,INPUT); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default, would try to act as both a client and an access-point and could cause network-issues with your other WiFi-devices on your WiFi-network. */ WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.print("Starting MqttSnClient - "); mqttSnClient.setCallback(mqttsn_callback); if (!mqttSnClient.begin()) { Serial.print("Could not initialize MQTT-SN Client "); while (true) { Serial.println("."); delay(1000); } } Serial.println(" ready!"); } void convertIPAddressAndPortToDeviceAddress(IPAddress& source, uint16_t port, device_address& target) { // IPAdress 0 - 3 bytes target.bytes[0] = source[0]; target.bytes[1] = source[1]; target.bytes[2] = source[2]; target.bytes[3] = source[3]; // Port 4 - 5 bytes target.bytes[4] = port >> 8; target.bytes[5] = (uint8_t) port ; } void loop() { if (!mqttSnClient.is_mqttsn_connected()) { #if defined(gatewayHostAddress) IPAddress gatewayIPAddress; if (!WiFi.hostByName(gatewayHostAddress, gatewayIPAddress, 20000)) { Serial.println("Could not lookup MQTT-SN Gateway."); return; } #endif device_address gateway_device_address; convertIPAddressAndPortToDeviceAddress(gatewayIPAddress, localUdpPort, gateway_device_address); Serial.print("MQTT-SN Gateway device_address: "); printDeviceAddress(&gateway_device_address); if (!mqttSnClient.connect(&gateway_device_address, clientId, 180) ) { Serial.println("Could not connect MQTT-SN Client."); delay(1000); return; } Serial.println("MQTT-SN Client connected."); mqttSnClient.subscribe(subscribeTopicName , qos); } if (Serial.available()> 0) { buffer[buffer_pos++] = Serial.read(); if (buffer[buffer_pos - 1] == '\n') { // only qos -1, 0, 1 are supported if (!mqttSnClient.publish(buffer, publishTopicName , qos)) { Serial.println("Could not publish"); } Serial.println("Published"); memset(buffer, 0x0, buffer_length); buffer_pos = 0; } } mqttSnClient.loop(); } and this my MQTT-SN Gateway look, I can only connect and subscribe, I can't Publish or change my clientID I already try to fix with https://github.com/S3ler/arduino-mqtt-sn-client/issues/3 but still I can't publish and I can only subscribe even my clientid won't change like I declared on my code I don't know what's wrong with it,Can someone tell me what's wrong with my code? Edit: This is what it look like in my Arduino IDE Terminal, Someone know what is the error? or what is the problem that keep me can't publish? 00:57:06.516 -> Connecting to WiFi 00:57:07.061 -> ..... 00:57:09.071 -> WiFi connected 00:57:09.071 -> IP address: 00:57:09.071 -> 192.168.1.192 00:57:09.071 -> Starting MqttSnClient - ready! 00:57:09.071 -> MQTT-SN Gateway device_address: 192, 168, 1, 151, 7, 92 00:57:09.173 -> MQTT-SN Client connected. 00:57:09.173 -> 00:57:09.173 -> Exception (28): 00:57:09.173 -> epc1=0x4000bf80 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000 00:57:09.173 -> 00:57:09.173 -> >>>stack>>> 00:57:09.173 -> 00:57:09.173 -> ctx: cont 00:57:09.173 -> sp: 3ffffc80 end: 3fffffc0 offset: 0190 00:57:09.173 -> 3ffffe10: 00000011 3ffeeb84 00000000 fffffffe 00:57:09.206 -> 3ffffe20: 00000011 00000001 00000001 3ffef57c 00:57:09.206 -> 3ffffe30: 3ffef500 3ffef57c 3ffef4fc 40215182 00:57:09.206 -> 3ffffe40: 3ffeec00 00000000 00000000 40215cef 00:57:09.206 -> 3ffffe50: 00000016 3ffee478 3ffe8750 40210538 00:57:09.206 -> 3ffffe60: 3ffeec00 0000005a 00000020 40100990 00:57:09.206 -> 3ffffe70: 3ffeec00 3ffeec04 0000075c 3ffef5e0 00:57:09.206 -> 3ffffe80: 00000810 00000102 00000000 3ffef500 00:57:09.241 -> 3ffffe90: 0000075c 3ffef57c 3ffef4fc 4021058f 00:57:09.241 -> 3ffffea0: 007a1200 59b425ea 00000000 40210628 00:57:09.241 -> 3ffffeb0: 00000000 00000000 00000001 00000000 00:57:09.241 -> 3ffffec0: 00000000 3ffef57c 00000000 40202b90 00:57:09.241 -> 3ffffed0: 3ffee478 3ffee5c8 00000000 40203cae 00:57:09.241 -> 3ffffee0: 00000013 3ffee4ba 3ffef4ac 00000008 00:57:09.241 -> 3ffffef0: 00000000 3ffee4c0 3ffee4a8 40205a04 00:57:09.275 -> 3fffff00: 00000008 3ffee4c0 3ffee4a8 40201771 00:57:09.275 -> 3fffff10: 40205d30 9701a8c0 3ffe876f 40203405 00:57:09.275 -> 3fffff20: 00000000 00000019 3ffee630 402034cc 00:57:09.275 -> 3fffff30: 3ffee478 00002710 3ffee630 3ffe8750 00:57:09.275 -> 3fffff40: 3ffee478 00000016 3ffee45c 40201c94 00:57:09.275 -> 3fffff50: 0104040c 654b00b4 006e6976 00000000 00:57:09.275 -> 3fffff60: 00000000 00000000 00000000 a8c00000 00:57:09.275 -> 3fffff70: 5c079701 00000000 00000000 00000000 00:57:09.309 -> 3fffff80: 3ffe8755 00000005 0000000c 00000001 00:57:09.309 -> 3fffff90: 40201068 c001a8c0 feefeffe 3ffee75c 00:57:09.309 -> 3fffffa0: 3fffdad0 00000000 3ffee71c 40203d90 00:57:09.309 -> 3fffffb0: feefeffe feefeffe 3ffe8500 40100c1d 00:57:09.309 -> <<<stack<<< 00:57:09.309 -> 00:57:09.309 -> ets Jan 8 2013,rst cause:2, boot mode:(3,6) 00:57:09.343 -> 00:57:09.343 -> load 0x4010f000, len 3456, room 16 00:57:09.343 -> tail 0 00:57:09.343 -> chksum 0x84 00:57:09.343 -> csum 0x84 00:57:09.343 -> va5432625 00:57:09.343 -> ~ld 00:57:10.395 -> if anyone from this issue can help me , I want to know what is the problem and how can I fix it? Socket error on client <>, disconnecting with Paho MQTT-SN Gateway and ESP8266 CLient I already decode the error and it say like this Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads PC: 0x4000bf80 EXCVADDR: 0x00000000 Decoding stack results 0x4021547a: ip4_output_if_src at core/ipv4/ip4.c line 1590 0x40215fe3: ip_chksum_pseudo at core/inet_chksum.c line 395 0x40210830: udp_sendto_if_src at core/udp.c line 893 0x40100990: malloc(size_t) at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 511 0x40210887: udp_sendto_if at core/udp.c line 692 0x40210920: udp_sendto at core/udp.c line 599 0x40202c28: WiFiUDP::endPacket() at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 176 0x40204df5: uart_write(uart_t*, char const*, size_t) at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\uart.cpp line 509 0x40204df5: uart_write(uart_t*, char const*, size_t) at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\uart.cpp line 509 0x402033e4: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/HardwareSerial.h line 164 0x402033e4: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/HardwareSerial.h line 164 0x402033f0: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/HardwareSerial.h line 165 0x402036c1: Print::write(char const*) at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/Print.h line 62 0x40201d34: loop() at C:\Users\ASUS\OneDrive\Documents\Arduino\Test/Test.ino line 133 0x40201074: mqttsn_callback(char*, unsigned char*, unsigned short, bool) at C:\Users\ASUS\OneDrive\Documents\Arduino\Test/Test.ino line 35 0x40204058: loop_wrapper() at C:\Users\ASUS\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\core_esp8266_main.cpp line 197 Is anyone know what the error mean? Please tell me and Thank You
Thank you for all, but i already fix my problem it seem there is a wrong code in the library and you must change it, right now i'm doing fine doing some publish
How to join more than 2 regions with Apache Geode?
I've been trying to query some regions and i'm failing to join more than 2 of them. I set that up in a Java test to run them more easily but it fails all the same in pulse. #Test public void test_geode_join() throws QueryException { ClientCache cache = new ClientCacheFactory() .addPoolLocator(HOST, LOCATOR_PORT) .setPoolSubscriptionEnabled(true) .setPdxSerializer(new MyReflectionBasedAutoSerializer()) .create(); { #SuppressWarnings("unchecked") SelectResults<StructImpl> r = (SelectResults<StructImpl>) cache.getQueryService() .newQuery("SELECT itm.itemId, bx.boxId " + "FROM /items itm, /boxs bx " + "WHERE itm.boxId = bx.boxId " + "LIMIT 5") .execute(); for (StructImpl v : r) { System.out.println(v); } } { #SuppressWarnings("unchecked") SelectResults<StructImpl> r = (SelectResults<StructImpl>) cache.getQueryService() .newQuery("SELECT bx.boxId, rm.roomId " + "FROM /boxs bx, /rooms rm " + "WHERE bx.roomId = rm.roomId " + "LIMIT 5") .execute(); for (StructImpl v : r) { System.out.println(v); } } { // That fails #SuppressWarnings("unchecked") SelectResults<StructImpl> r = (SelectResults<StructImpl>) cache.getQueryService() .newQuery("SELECT itm.itemId, bx.boxId, rm.roomId " + "FROM /items itm, /boxs bx, /rooms rm " + "WHERE itm.boxId = bx.boxId " + "AND bx.roomId = rm.roomId " + "LIMIT 5") .execute(); for (StructImpl v : r) { System.out.println(v); } } } The first 2 queries work fine and respond in an instant but the last query holds until it timeouts. I get the following logs [warn 2018/02/06 17:33:17.155 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname:31902: Connection[hostname:31902]#1978504976) [warn 2018/02/06 17:33:27.333 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname2:31902: Connection[hostname2:31902]#1620459733 attempt=2) [warn 2018/02/06 17:33:37.588 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname3:31902: Connection[hostname3:31902]#422409467 attempt=3) [warn 2018/02/06 17:33:37.825 CET <main> tid=0x1] Pool unexpected socket timed out on client connection=Pooled Connection to hostname3:31902: Connection[hostname3:31902]#422409467 attempt=3). Server unreachable: could not connect after 3 attempts [info 2018/02/06 17:33:37.840 CET <Distributed system shutdown hook> tid=0xd] VM is exiting - shutting down distributed system [info 2018/02/06 17:33:37.840 CET <Distributed system shutdown hook> tid=0xd] GemFireCache[id = 1839168128; isClosing = true; isShutDownAll = false; created = Tue Feb 06 17:33:05 CET 2018; server = false; copyOnRead = false; lockLease = 120; lockTimeout = 60]: Now closing. [info 2018/02/06 17:33:37.887 CET <Distributed system shutdown hook> tid=0xd] Destroying connection pool DEFAULT And it ends up crashing org.apache.geode.cache.client.ServerConnectivityException: Pool unexpected socket timed out on client connection=Pooled Connection to hostname3:31902: Connection[hostname3:31902]#422409467 attempt=3). Server unreachable: could not connect after 3 attempts at org.apache.geode.cache.client.internal.OpExecutorImpl.handleException(OpExecutorImpl.java:798) at org.apache.geode.cache.client.internal.OpExecutorImpl.handleException(OpExecutorImpl.java:623) at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:174) at org.apache.geode.cache.client.internal.OpExecutorImpl.execute(OpExecutorImpl.java:115) at org.apache.geode.cache.client.internal.PoolImpl.execute(PoolImpl.java:763) at org.apache.geode.cache.client.internal.QueryOp.execute(QueryOp.java:58) at org.apache.geode.cache.client.internal.ServerProxy.query(ServerProxy.java:70) at org.apache.geode.cache.query.internal.DefaultQuery.executeOnServer(DefaultQuery.java:456) at org.apache.geode.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:338) at org.apache.geode.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:319) at local.test.geode.GeodeTest.test_geode_join(GeodeTest.java:226) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206) I tried to set timeouts at 60 seconds but i'm still not getting any results. All regions are configured like this: Type | Name | Value ------ | --------------- | -------------------- Region | data-policy | PERSISTENT_REPLICATE | disk-store-name | regionDiskStore1 | size | 1173 | scope | distributed-ack Am I missing anything here ?
Based on all the information provided, it looks like you are doing everything correct. I tried to reproduce in a simple test (similar test) and the test returns 5 results. However, if one of the predicates did not match, it could cause the query to take a lot longer to join enough rows to find a tuple that matches. Below is a sample test that does not have an issue, but if I modify the test to put into region3 only portfolios with ID = -1. Then the test "hangs" trying to find 5 rows that fulfill the search criteria (it has to join 1000 * 1000 * 1000 rows which takes awhile to do). In the end the query will not find an p3.ID = p1.ID. Is it possible that the itm.boxIds just do not match box.boxId often enough so it takes a lot longer to find ones that do? public void testJoinMultipleReplicatePersistentRegionsWithLimitClause() throws Exception { String regionName = "portfolio"; Cache cache = serverStarterRule.getCache(); assertNotNull(cache); Region region1 = cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT).create(regionName + 1); Region region2 = cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT).create(regionName + 2); Region region3 = cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT).create(regionName + 3); for ( int i = 0; i < 1000; i++) { Portfolio p = new Portfolio(i); region1.put(i, p); region2.put(i, p); region3.put(i, p); //modify this line to region3.put(i, new Portfolio(-1)) to cause query to take longer } QueryService queryService = cache.getQueryService(); SelectResults results = (SelectResults) queryService .newQuery("select p1.ID, p2.ID, p3.ID from /portfolio1 p1, /portfolio2 p2, /portfolio3 p3 where p1.ID = p2.ID and p3.ID = p1.ID limit 5").execute(); assertEquals(5, results.size()); }
getting {badarith,[{erlang,'+',[error,0],[]}, while performing arithmetic operation in TSUNG using Erlang snippet
I have wriiten a arithmetic snippet using TSUNG-Erlang function but unable to get through it successfully ; getting following error in my TSUNG controller's log , TSUNG-Erlang Snippet, <setdynvars sourcetype="file" fileid="NBILM_testUsers" delimiter=";" order="iter"> <var name="minnum"/> <var name="maxnum"/> </setdynvars> <setdynvars sourcetype="eval" code='fun({Pid,DynVars})-> {ok,Maxfound}=ts_dynvars:lookup(maxnum,DynVars), Maxstr = lists:flatten(io_lib:format("~p",[Maxfound])), {MAX, _} = string:to_integer(Maxstr), {ok,Minfound}=ts_dynvars:lookup(minnum,DynVars), Minstr = lists:flatten(io_lib:format("~p",[Minfound])), {MIN, _} = string:to_integer(Minstr), {ok,Countern} = ts_dynvars:lookup(counter,DynVars,999), Counternstr = lists:flatten(io_lib:format("~p",[Countern])), {Counternum, _} = string:to_integer(Counternstr), Mnum1 = MAX + Counternum rem ( 2 - 1 ), Mnum1 end. '> <var name="mnum" /> </setdynvars> Erroneous log events from TSUNG Controller, =INFO REPORT==== 5-May-2017::11:42:40 === ts_client:(5:<0.134.0>) Stop in state think, reason= {badarith, [{erlang, '+', [error,0], []}, {erl_eval, do_apply,6, [{file, "erl_eval.erl"}, {line, 669}]}, {erl_eval, expr,5, [{file, "erl_eval.erl"}, {line, 438}]}, {erl_eval, exprs,5, [{file, "erl_eval.erl"}, {line, 122}]}, {ts_client, handle_next_action, 1, [{file, "src/tsung/ts_client.erl"}, {line, 459}]}, {gen_fsm, handle_msg, 7, [{file, "gen_fsm.erl"}, {line, 518}]}, {proc_lib, init_p_do_apply, 3, [{file, "proc_lib.erl"}, {line, 239}]}]} =ERROR REPORT==== 5-May-2017::11:42:40 === ** State machine <0.134.0> terminating ** Last message in was {timeout,#Ref<0.0.8.22>,end_thinktime} ** When State == think ** Data == {state_rcv,none, {{0,0,0,0},0}, undefined,0,10000,"xyz",80,ts_tcp, {proto_opts,negociate,"/http-bind/",false,"/chat", "binary",10,3,600000,infinity,infinity,32768,32768, undefined,undefined,[],false,true}, false,1,undefined,true,undefined, {1493,964755,255814}, 18,18,false,undefined,0,[],<<>>, {http,0,0,-1, {none,none}, false,false, {false,false}, [],"tsung",[]}, 0,1,524288,524288, [{tsung_userid,1}], ts_http,[],undefined,full} Reason for termination = {badarith,[{erlang,'+',[error,0],[]}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,669}]}, {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,438}]}, {erl_eval,exprs,5,[{file,"erl_eval.erl"},{line,122}]}, {ts_client,handle_next_action,1, [{file,"src/tsung/ts_client.erl"},{line,459}]}, {gen_fsm,handle_msg,7,[{file,"gen_fsm.erl"},{line,518}]}, {proc_lib,init_p_do_apply,3, [{file,"proc_lib.erl"},{line,239}]}]} It would be really helpful, if someone can point what am doing incorrectly.
The message says that in the line Mnum1 = MAX + Counternum rem ( 2 - 1 ), you are trying to add error with 0 (by the way Counternum rem ( 2 - 1 ) is always equal to 0 so there must be an error here). Max is the result of {MAX, _} = string:to_integer(Maxstr),, it is equal to error if Maxstr is not a string starting by an integer: "123" will return {123,[]} "123 ab" will return {123," ab"} "a123" will return {error,no_integer} an_atom will return {error,not_a_list} To debug further verify the value of Maxfound and Maxstr you can also shorten your code using the function io:fread/2 which will directly return an integer.
Message exchange between Paho java & javascript client not happening
How can I send a message from paho java client to paho javascript client. String topic = "chatWith/904"; String content = "Message from MqttPublishSample"; int qos = 0; String broker = "tcp://127.0.0.1:1883"; String clientId = "JavaSample"; MemoryPersistence persistence = new MemoryPersistence(); try { MqttClient sampleClient = new MqttClient(broker, clientId, persistence); MqttConnectOptions connOpts = new MqttConnectOptions(); connOpts.setCleanSession(true); System.out.println("Connecting to broker: "+broker); sampleClient.connect(connOpts); System.out.println("Connected"); System.out.println("Publishing message: "+content); MqttMessage message = new MqttMessage(content.getBytes()); message.setQos(qos); sampleClient.publish(topic, message); System.out.println("Message published"); sampleClient.disconnect(); System.out.println("Disconnected"); System.exit(0); } catch(MqttException me) { me.printStackTrace(); } Message exchange between two JS client is happening. But between Javasript & java client, message exchange is not happening. Here is JS code client = new Messaging.Client(host, Number(port), clientId); client.onConnect = onConnect; client.onMessageArrived = onMessageArrived; client.onMessageDelivered = onMessageDelivered; client.onConnectionLost = onConnectionLost; var willMessage = createByteMessage({ id: '', 'msgType':'USER_STATUS', 'status': 'Offline', 'senderId': myUserId, 'senderName': myName }, statusTopic); willMessage.retained = true; client.connect({ userName:user, password:password, onSuccess:onConnect, onFailure:onFailure, 'willMessage': willMessage }); Here port is 8083 and mqtt broker is emqtt client.config testclientid0 testclientid1 127.0.0.1 testclientid2 192.168.0.1/24 emqttd.config % -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ft=erlang ts=4 sw=4 et [{kernel, [ {start_timer, true}, {start_pg2, true} ]}, {sasl, [ {sasl_error_logger, {file, "log/emqttd_sasl.log"}} ]}, {ssl, [ %{versions, ['tlsv1.2', 'tlsv1.1']} ]}, {lager, [ {colored, true}, {async_threshold, 5000}, {error_logger_redirect, false}, {crash_log, "log/emqttd_crash.log"}, {handlers, [ %%{lager_console_backend, info}, %%NOTICE: Level >= error %%{lager_emqtt_backend, error}, {lager_file_backend, [ {formatter_config, [time, " ", pid, " [",severity,"] ", message, "\n"]}, {file, "log/emqttd_error.log"}, {level, error}, {size, 104857600}, {date, "$D0"}, {count, 30} ]} ]} ]}, {esockd, [ {logger, {lager, error}} ]}, {emqttd, [ %% Authentication and Authorization {access, [ %% Authetication. Anonymous Default {auth, [ %% Authentication with username, password %{username, []}, %% Authentication with clientid %{clientid, [{password, no}, {file, "etc/clients.config"}]}, %% Authentication with LDAP % {ldap, [ % {servers, ["localhost"]}, % {port, 389}, % {timeout, 30}, % {user_dn, "uid=$u,ou=People,dc=example,dc=com"}, % {ssl, fasle}, % {sslopts, [ % {"certfile", "ssl.crt"}, % {"keyfile", "ssl.key"}]} % ]}, %% Allow all {anonymous, []} ]}, %% ACL config {acl, [ %% Internal ACL module {internal, [{file, "etc/acl.config"}, {nomatch, allow}]} ]} ]}, %% MQTT Protocol Options {mqtt, [ %% Packet {packet, [ %% Max ClientId Length Allowed {max_clientid_len, 512}, %% Max Packet Size Allowed, 64K default {max_packet_size, 65536} ]}, %% Client {client, [ %% Socket is connected, but no 'CONNECT' packet received {idle_timeout, 30} %% seconds ]}, %% Session {session, [ %% Max number of QoS 1 and 2 messages that can be “in flight” at one time. %% 0 means no limit {max_inflight, 100}, %% Retry interval for redelivering QoS1/2 messages. {unack_retry_interval, 60}, %% Awaiting PUBREL Timeout {await_rel_timeout, 20}, %% Max Packets that Awaiting PUBREL, 0 means no limit {max_awaiting_rel, 0}, %% Statistics Collection Interval(seconds) {collect_interval, 0}, %% Expired after 2 day (unit: minute) {expired_after, 2880} ]}, %% Queue {queue, [ %% simple | priority {type, simple}, %% Topic Priority: 0~255, Default is 0 %% {priority, [{"topic/1", 10}, {"topic/2", 8}]}, %% Max queue length. Enqueued messages when persistent client disconnected, %% or inflight window is full. {max_length, infinity}, %% Low-water mark of queued messages {low_watermark, 0.2}, %% High-water mark of queued messages {high_watermark, 0.6}, %% Queue Qos0 messages? {queue_qos0, true} ]} ]}, %% Broker Options {broker, [ %% System interval of publishing broker $SYS messages {sys_interval, 60}, %% Retained messages {retained, [ %% Expired after seconds, never expired if 0 {expired_after, 0}, %% Max number of retained messages {max_message_num, 100000}, %% Max Payload Size of retained message {max_playload_size, 65536} ]}, %% PubSub and Router {pubsub, [ %% Default should be scheduler numbers {pool_size, 8}, %% Store Subscription: true | false {subscription, true}, %% Route aging time(seconds) {route_aging, 5} ]}, %% Bridge {bridge, [ %%TODO: bridge queue size {max_queue_len, 10000}, %% Ping Interval of bridge node {ping_down_interval, 1} %seconds ]} ]}, %% Modules {modules, [ %% Client presence management module. %% Publish messages when client connected or disconnected {presence, [{qos, 0}]}, %% Subscribe topics automatically when client connected {subscription, [ %% $c will be replaced by clientid %% {"$queue/clients/$c", 1}, %% Static subscriptions from backend backend ]} %% Rewrite rules %% {rewrite, [{file, "etc/rewrite.config"}]} ]}, %% Plugins {plugins, [ %% Plugin App Library Dir {plugins_dir, "./plugins"}, %% File to store loaded plugin names. {loaded_file, "./data/loaded_plugins"} ]}, %% Listeners {listeners, [ {mqtt, 1883, [ %% Size of acceptor pool {acceptors, 16}, %% Maximum number of concurrent clients {max_clients, 512}, %% Socket Access Control {access, [{allow, all}]}, %% Connection Options {connopts, [ %% Rate Limit. Format is 'burst, rate', Unit is KB/Sec %% {rate_limit, "100,10"} %% 100K burst, 10K rate ]}, %% Socket Options {sockopts, [ %Set buffer if hight thoughtput %{recbuf, 4096}, %{sndbuf, 4096}, %{buffer, 4096}, %{nodelay, true}, {backlog, 1024} ]} ]}, {mqtts, 8883, [ %% Size of acceptor pool {acceptors, 4}, %% Maximum number of concurrent clients {max_clients, 512}, %% Socket Access Control {access, [{allow, all}]}, %% SSL certificate and key files {ssl, [{certfile, "etc/ssl/ssl.crt"}, {keyfile, "etc/ssl/ssl.key"}]}, %% Socket Options {sockopts, [ {backlog, 1024} %{buffer, 4096}, ]} ]}, %% WebSocket over HTTPS Listener %% {https, 8083, [ %% %% Size of acceptor pool %% {acceptors, 4}, %% %% Maximum number of concurrent clients %% {max_clients, 512}, %% %% Socket Access Control %% {access, [{allow, all}]}, %% %% SSL certificate and key files %% {ssl, [{certfile, "etc/ssl/ssl.crt"}, %% {keyfile, "etc/ssl/ssl.key"}]}, %% %% Socket Options %% {sockopts, [ %% %{buffer, 4096}, %% {backlog, 1024} %% ]} %%]}, %% HTTP and WebSocket Listener {http, 8083, [ %% Size of acceptor pool {acceptors, 4}, %% Maximum number of concurrent clients {max_clients, 64}, %% Socket Access Control {access, [{allow, all}]}, %% Socket Options {sockopts, [ {backlog, 1024} %{buffer, 4096}, ]} ]} ]}, %% Erlang System Monitor {sysmon, [ %% Long GC, don't monitor in production mode for: %% https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421 {long_gc, false}, %% Long Schedule(ms) {long_schedule, 240}, %% 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM. %% 8 * 1024 * 1024 {large_heap, 8388608}, %% Busy Port {busy_port, false}, %% Busy Dist Port {busy_dist_port, true} ]} ]} ].