"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

node.js script macht mich narrisch (Cannot GET /)

UnleashThebeast 29.01.2022 - 18:35 5715 16 Thread rating
Posts

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3546
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'));

liegt auf dem raspi in /home/pi/wetter
startet beim start automatisch via init.d:
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

Wenn ich jetzt aber im Browser $ip:8000 aufrufe, krieg ich nur ein "Cannot GET /", gleichweise mit $ip:8000/index.js ein "Cannot GET /index.js".

Wieso funktioniert das auf einmal nimmer? Ich rauf mir jetzt seit 2 Stunden die Haare :(.

issue

Rock and Stone, brother!
Avatar
Registered: Feb 2003
Location: Linz
Posts: 3645
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

JDK

Oberwortwart
Avatar
Registered: Feb 2007
Location: /etc/graz
Posts: 2830
Zitat aus einem Post von IsSuE
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

Das.

Und was willst du mit dem /scripts Directory? Scheint als ob du dir da den GET / Endpoint, der dir eine HTML Page ausliefert, „verloren“ hast.
Bearbeitet von JDK am 29.01.2022, 18:49

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3546
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 }

Daten kommen alle 30 Sekunden. Funktioniert auch gut. A Zeitlang. Dann denk ich mir "passt, machst ein sexy
Code:
sudo /etc/init.d/wetter start
funktioniert auch gut. Bis dann der Dienst nach ein paar Minuten einfach weg is. :(. Für heut reichts mir...

pinkey

Here to stay
Registered: Nov 2003
Location: Tirol/Wien
Posts: 2275
Wird dir irgendein Fehler angezeigt oder bleibts einfach hängen oder ... ?

Kann dir sehr gern damit weiterhelfen aber bissl mehr Infos wären super :)

JDK

Oberwortwart
Avatar
Registered: Feb 2007
Location: /etc/graz
Posts: 2830
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.

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3546
/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 via node index.js starte, krieg ich die OkPacket von oben, bis es nach einer Zeit einfach abschmiert.

spunz

Super Moderator
Super Moderator
Avatar
Registered: Aug 2000
Location: achse des bösen
Posts: 11243
Wenn ich es richtig verstanden habe, fehlten einige Files oder diese waren ggf beschädigt? => ggf mal die SD Karte prüfen

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3546
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...

COLOSSUS

Administrator
GNUltra
Avatar
Registered: Dec 2000
Location: ~
Posts: 12073
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/

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3546
was genau is an init.d schwindlich?

COLOSSUS

Administrator
GNUltra
Avatar
Registered: Dec 2000
Location: ~
Posts: 12073
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.

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3546
@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

dann brauch ich ein
sudo systemctl daemon-reload
und ein
sudo systemctl enable wetter

sorry für die blöde Fragerei, aber das is alles schwarze Magie für mich ;) Dafür kann ich dir einen SCCM super gschmeidig konfigurieren :x.

COLOSSUS

Administrator
GNUltra
Avatar
Registered: Dec 2000
Location: ~
Posts: 12073
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.

UnleashThebeast

Mr. Midlife-Crisis
Avatar
Registered: Dec 2005
Location: 127.0.0.1
Posts: 3546
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...
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz