URL: https://www.overclockers.at/coding-stuff/node-js-script-macht-mich-narrisch-cannot-get_259473/page_1 - zur Vollversion wechseln!
Hallo,
folgendes Problem.
Ich habe ein Node.js Zeugs, das läuft um Daten via einem ESP entgegenzunehmen und in eine mysql db zu schreiben.
Das hat jetzt auch 4 Jahre lang einwandfrei funktioniert, plötzlich aber aus irgendeinem Grund nichtmehr...
das script:
index.js
Code:var express = require('express'); var mysql = require('mysql'); var app = express(); var bodyParser = require('body-parser'); var SavePassword = 'wetter'; var connection = mysql.createConnection({ host : 'localhost', user : 'wetter', password : 'x', database : 'wetter', debug : false, connectionLimit : 100 }); app.set('port', (process.env.PORT || 8000)) app.use('/scripts', express.static(__dirname + '/node_modules/vis/dist/')); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); // Send data app.post('/', function(req, res){ var sender_id, temperature, humidity; if (!req.body.hasOwnProperty("password") || req.body.password != SavePassword) { res.json({"code" : 403, "error": "Password incorrect / missing"}); return; } if (!req.body.hasOwnProperty("sender_id") || req.body.sender_id == "") { res.json({"code" : 403, "error": "Sender ID missing"}); return; } else { sender_id = req.body.sender_id; } if (!req.body.hasOwnProperty("temperature") || parseFloat(req.body.temperature) == NaN) { res.json({"code" : 403, "error": "Temperature Value missing"}); return; } else { temperature = parseFloat(req.body.temperature); } if (!req.body.hasOwnProperty("humidity") || parseFloat(req.body.humidity) == NaN) { res.json({"code" : 403, "error": "Humidity Value missing"}); return; } else { humidity = parseFloat(req.body.humidity); } // save var query = connection.query('INSERT INTO temperature VALUES ' + ' (DEFAULT, '+mysql.escape(sender_id)+', NOW(), '+temperature+', '+humidity+');', function (error, results, fields) { if (error) { res.json({"code" : 403, "status" : "Error in connection database"}); return; } res.json({"code": 200}); }); }); app.listen(app.get('port'));
Code:#!/bin/sh ### BEGIN INIT INFO # Provides: wetter # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO dir="/home/pi/wetter" cmd="node index.js" user="pi" name=`basename $0` pid_file="/var/run/$name.pid" stdout_log="/var/log/$name.log" stderr_log="/var/log/$name.err" get_pid() { cat "$pid_file" } is_running() { [ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1 } case "$1" in start) if is_running; then echo "Already started" else echo "Starting $name" cd "$dir" if [ -z "$user" ]; then sudo $cmd >> "$stdout_log" 2>> "$stderr_log" & else sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" & fi echo $! > "$pid_file" if ! is_running; then echo "Unable to start, see $stdout_log and $stderr_log" exit 1 fi fi ;; stop) if is_running; then echo -n "Stopping $name.." kill `get_pid` for i in 1 2 3 4 5 6 7 8 9 10 # for i in `seq 10` do if ! is_running; then break fi echo -n "." sleep 1 done echo if is_running; then echo "Not stopped; may still be shutting down or shutdown may have failed" exit 1 else echo "Stopped" if [ -f "$pid_file" ]; then rm "$pid_file" fi fi else echo "Not running" fi ;; restart) $0 stop if is_running; then echo "Unable to stop, will not attempt to start" exit 1 fi $0 start ;; status) if is_running; then echo "Running" else echo "Stopped" exit 1 fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0
.Ohne mich wirklich auszukennen: du hast nur eine app.post aber keine app.get. Sprich ein Post request kannst nach / schicken, aber get / hat keine route
Zitat aus einem Post von IsSuEOhne mich wirklich auszukennen: du hast nur eine app.post aber keine app.get. Sprich ein Post request kannst nach / schicken, aber get / hat keine route
Es geht lustig weiter. Ich habe tatsächlich was verloren, das ist jetzt wieder da, index.js (und der Rest) sehen so aus:
https://github.com/tutRPi/Raspberry...master/index.js
Ich krieg jetzt auch wieder Werte in meine DB.
Hab in der index.js mal debug auf true gestellt, somit krieg ich wenn Daten ankommen einen Output ins Terminal:
Code:pi@WetterPi:~/wetter $ node index.js <-- HandshakeInitializationPacket { protocolVersion: 10, serverVersion: '5.5.5-10.3.17-MariaDB-0+deb10u1', threadId: 63, scrambleBuff1: <Buffer 64 3b 3a 51 67 32 60 71>, filler1: <Buffer 00>, serverCapabilities1: 63486, serverLanguage: 45, serverStatus: 2, serverCapabilities2: 33215, scrambleLength: 21, filler2: <Buffer 00 00 00 00 00 00 07 00 00 00>, scrambleBuff2: <Buffer 36 56 2e 25 6b 6c 5e 71 3e 22 2e 5f>, filler3: <Buffer 00>, pluginData: 'mysql_native_password', protocol41: true } --> (63) ClientAuthenticationPacket { clientFlags: 455631, maxPacketSize: 0, charsetNumber: 33, filler: undefined, user: 'wetter', scrambleBuff: <Buffer 9f bd a4 7a c3 18 30 38 d5 83 7a 31 63 c3 e8 fb 97 e1 25 d6>, database: 'wetter', protocol41: true } <-- (63) OkPacket { fieldCount: 0, affectedRows: 0, insertId: 0, serverStatus: 16386, warningCount: 0, message: '', protocol41: true, changedRows: 0 } --> (63) ComQueryPacket { command: 3, sql: 'INSERT INTO temperature VALUES (DEFAULT, \'5e:cf:7f:c3:f8:3b\', NOW(), 26.2, 33.1);' } <-- (63) OkPacket { fieldCount: 0, affectedRows: 1, insertId: 760739, serverStatus: 2, warningCount: 0, message: '', protocol41: true, changedRows: 0 }
funktioniert auch gut. Bis dann der Dienst nach ein paar Minuten einfach weg is.Code:sudo /etc/init.d/wetter start
. Für heut reichts mir...Wird dir irgendein Fehler angezeigt oder bleibts einfach hängen oder ... ?
Kann dir sehr gern damit weiterhelfen aber bissl mehr Infos wären super 
Schau mal, was dir dein Skript in /var/log/ schreibt, sonst lass es halt mal direkt per node (anstelle via init.d) laufen und beobachte den Output.
/var/log/wetter.err sagt:
Code:Error: Connection lost: The server closed the connection. at Protocol.end (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:112:13) at Socket.<anonymous> (/home/pi/wetter/node_modules/mysql/lib/Connection.js:94:28) at Socket.<anonymous> (/home/pi/wetter/node_modules/mysql/lib/Connection.js:526:10) at Socket.emit (events.js:203:15) at endReadableNT (_stream_readable.js:1143:12) at process._tickCallback (internal/process/next_tick.js:63:19) Emitted 'error' event at: at Connection._handleProtocolError (/home/pi/wetter/node_modules/mysql/lib/Connection.js:423:8) at Protocol.emit (events.js:198:13) at Protocol._delegateError (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:398:10) at Protocol.end (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:116:8) at Socket.<anonymous> (/home/pi/wetter/node_modules/mysql/lib/Connection.js:94:28) [... lines matching original stack trace ...] at process._tickCallback (internal/process/next_tick.js:63:19) events.js:174 throw er; // Unhandled 'error' event ^ Error: read ECONNRESET at TCP.onStreamRead (internal/stream_base_commons.js:111:27) Emitted 'error' event at: at Connection._handleProtocolError (/home/pi/wetter/node_modules/mysql/lib/Connection.js:423:8) at Protocol.emit (events.js:198:13) at Protocol._delegateError (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:398:10) at Protocol.handleNetworkError (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:371:10) at Connection._handleNetworkError (/home/pi/wetter/node_modules/mysql/lib/Connection.js:418:18) at Socket.emit (events.js:198:13) at emitErrorNT (internal/streams/destroy.js:91:8) at emitErrorAndCloseNT (internal/streams/destroy.js:59:3) at process._tickCallback (internal/process/next_tick.js:63:19)
Wenn ich es richtig verstanden habe, fehlten einige Files oder diese waren ggf beschädigt? => ggf mal die SD Karte prüfen
SD ist seit heute früh eine neue mit einer frischen Raspian Install drauf und das script frisch aus Github. Bis jetzt läufts via node index.js, mal ein paar Stunden schauen. Bin vorsichtig optimistisch, aber auch misstrauisch. Es fehlte nur in einem File ein Stück Text, das ist keine SD Corruption die ich bis jetzt kannte...
Du solltest den Dienst auf jeden Fall via systemd starten, nicht schwindlig via /etc/init.d/<whatever> - zur Not via systemd-sysvcompat, aber ein eigenes Unit File schreiben sollte sehr einfach sein. Vgl. z. B. https://fedoramagazine.org/systemd-...svinit-scripts/
was genau is an init.d schwindlich?
Du nutzt damit die Reste eines Init- bzw. Service-Management-Systems, das es de facto auf deinem Host nicht mehr gibt, bzw. das nicht mehr die "Hoheit" ueber den Host hat. (Auch vor systemd war es oftmals Falsch, Scripts in /etc/init.d/ direkt auszufuehren, und nicht ueber den `service`-Wrapper zu steuern, der das Environment fuer die Kindprozesse entsprechend aufraeumt/massiert.) Mit ausreichend Pech bzw. der entsprechenden Konfiguration (vgl. https://systemd.network/logind.conf...lUserProcesses=) knallt dir der diensthabende Service Manager (eben systemd) alle so gestarteten Prozesse, die nicht als Teil einer Service Unit gestartet wurden, nach deinem Logout ab.
@colo
wenn ich dich schon da hab, korrekt wär also:
rm -rf /etc/init.d/wetter
unter /lib/systemd/system/ eine wetter.service anlegen und folgendes rein:
Code:[Unit] Description=Wetterservice After=network.target [Service] Environment=NODE_PORT=8000 Type=simple User=pi ExecStart=/usr/bin/node /home/pi/wetter/index.js Restart=on-failure [Install] WantedBy=multi-user.target
Dafür kann ich dir einen SCCM super gschmeidig konfigurieren :x.Fast ganz richtig - das Unit File sollte besser in /etc/systemd/system/wetter.service zu liegen kommen, weil /lib/systemd/system/ dem Paketmanager "gehoert". Nach dem `sudo systemctl enable wetter` in deiner Kommandoabfolge wirst du dann auch noch ein `sudo systemctl start wetter` brauchen. Alternativ verwendest du `sudo systemctl enable --now wetter` (enable = sicherstellen, dass das Service beim Erreichenwollen des default targets gestartet wird - ohne start waere das ggf. nach dem naechsten Reboot).
Bevor du das alles tust, solltest du auch nochmal via `/etc/init.d/wetter stop` dafuer sorgen, dass moeglichst nix vom runtime state des alten Service uebrigbleibt.
Cool.
Ja, vorher hab ichs gestoppt und den noch laufenden screen via kill -9 abgeschossen.
Ich war aber ungeduldig und habs schon in /lib/systemd/system abgelegt - is das jetzt sehr sehr schlimm und zerschiesst mir bei einem apt-get wieder das service oder is das eher ein semantisches Problem bzw "schöner wärs halt"?
läuft übrigens schon, mal schauen obs jetzt als service wieder stirbt, vorher is es mal von ~08:00 bis 13:00 in einem screen ohne crash gelaufen...
overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025