Befehle auf Webseite serverseitig ausführen

Mr. Poe

Lt. Commander
Registriert
Juli 2010
Beiträge
1.915
hallo,

ich suche eine methode, um eine webseite zu programmieren, die auf tastatur eingaben reagiert und jenachdem, welche taste gedrückt wurde auf dem server ein script ausführt...

die seite soll nicht neugeladen werden o.ä. also mit php wird das nicht gehen oder?
theoretisch geht das mit node.js... aber irgentwie bekomme ich das nicht hin.

hab mir einen roboter gebaut, der übers wlan gesteuert werden soll. zm testen habe ich mir von github ein projekt runtergeladen, mit dem ich über node.js den roboter steuern kann...
leider funktioniert das irgentwie bei mir nicht...

jetzt will ich selber was programmieren.

geht das vllt mit javascript und php?
kann man diese 2 techniken vllt verknüpfen?
oder gibt es da was ganz anderes, einfacheres?

noch ein beispiel, was ich genau vorabe:
ich rufe diese webseite auf und drücke auf meiner tastatur eine taste (z.b. W).
dann soll auf dem server ein befehl ausgeführt werden.
wenn die taste losgelassen wird, soll ein anderer befehl ausgeführt werden.
 
Hey,

Ich gehe mal davon aus, dass JavaScript + PHP dein Freund seien wird, wie du schon korrekt vermutet hast. In Kombination nennt sich das "Ajax", wo du die Seite nicht komplett neuladen musst, sondern entweder ein Script anstößt oder sogar Teile der aktuell angezeigten Seite ersetzt.

Beispiel zu Ajax: http://matthiasschuetz.com/jquery-tutorial-dynamische-inhalte-mit-ajax-laden

Liebe Grüße
 
Amarok2 schrieb:
die seite soll nicht neugeladen werden o.ä. also mit php wird das nicht gehen oder?
theoretisch geht das mit node.js... aber irgentwie bekomme ich das nicht hin.
Warum sollte mit Node.JS etwas gehen, was mit PHP nicht geht? Auch Node.JS nutzt nur das HTTP-Protokoll. Es ist deine Sache, wie du die Schnittstelle entwirfst.

noch ein beispiel, was ich genau vorabe:
ich rufe diese webseite auf und drücke auf meiner tastatur eine taste (z.b. W).
dann soll auf dem server ein befehl ausgeführt werden.
wenn die taste losgelassen wird, soll ein anderer befehl ausgeführt werden.

Tastaturanschläge im Browser können NUR mit JavaScript behandelt werden. Kein JS, kein Event Handling im Browser. Das Event muss dann nur die richtige Anfrage an den verarbeitenden Server schicken, und der muss darauf reagieren.

Aber:
1.) Thema Sicherheit: Webseite + Serverbefehle? Wenn du nicht genau weißt, was du tust, kann das extrem nach hinten losgehen.
2.) Thema Rechtesystem: Wem gehört der HTTP-Dienst? Wer hat Ausführungsrechte auf dein Ziel-Programm?
Ergänzung ()

bpblub schrieb:
Ich gehe mal davon aus, dass JavaScript + PHP dein Freund seien wird, wie du schon korrekt vermutet hast. In Kombination nennt sich das "Ajax", wo du die Seite nicht komplett neuladen musst

AJAX hat gar nichts mit PHP zu tun. Du kannst AJAX sogar mit purem HTML verwenden, ohne serverseitiger Programmiersprache.
 
Daaron schrieb:
AJAX hat gar nichts mit PHP zu tun. Du kannst AJAX sogar mit purem HTML verwenden, ohne serverseitiger Programmiersprache.

Ok, da hast du Recht, per Definition. Aber um ein Script auszuführen der sein Roboter anspricht wäre PHP sicherlich eine gute Möglichkeit oder sehe ich das falsch?
 
Es wäre eine von vielen Möglichkeiten, ja.
Ich rate von solchen Spielereien trotzdem ab, egal in welcher Sprache. Wenn man nicht weiß, was man tut, erzeugt man unter Umständen massive Sicherheitslücken im System.
 
Und wenn der Roboter nur im lokalen Netzwerk gesteuert werden soll, sind deine Bedenken sofort für die Katz.
Nicht immer ist die Security-Keule sinnvoll ;)
 
Amarok2 schrieb:
geht das vllt mit javascript und php?

Ginge, ja.
Läuft der Server direkt auf deinem Roboter, oder ist der Server eine stationäre, zusätzliche Maschine? Das würde doch einen beträchtlichen Unterschied machen.
 
Zuletzt bearbeitet:
also zum roboter:
der roboter erzeugt seinen eigenen wlan hotspot. und es kann sich maximal 1ne person damit verbinden.
wie sicher die webseite ist ist egal...
ja der server läuft direkt auf dem roboter (mit einem raspberry pi)

wie kann ich javascript denn mit php verbinden?
 
PHP ist möglich, aber nicht zweckmäßig. Du müsstest einen kompletten Webserver laufen lassen, nur für ein kleines und sehr spezielles Werkzeug.
Schreib lieber was auf Basis von C/C++, das ist um einiges effizienter.

Wie du per JS Requests über HTTP sendest, solltest du wohl selbst herausfinden, ansonsten ist das Projekt doch weit außerhalb deiner Fähigkeiten.
 
Daaron schrieb:
Warum sollte mit Node.JS etwas gehen, was mit PHP nicht geht?
Sehr witzig....Node.JS ist weitaus mächtiger als PHP und grade lang dauernden Prozesse sind nicht eine stärke von PHP (ja ich weiß man kann auch rumhacken oder andere Libs einbauen)...

Amarok2 schrieb:
noch ein beispiel, was ich genau vorabe:
ich rufe diese webseite auf und drücke auf meiner tastatur eine taste (z.b. W).
dann soll auf dem server ein befehl ausgeführt werden.
wenn die taste losgelassen wird, soll ein anderer befehl ausgeführt werden.

Ich kenn mich in Node.js sehr gut aus, für das was du machen möchtest brauchst du kein HTTP, Ajax, PHP.... Hierfür kannst du ein einfachen TCP Server in Node.js aufziehen und über die Socketverbindung deine Keyboardeingaben aus dem STDIN Stream auslesen. Dann kannst du die entsprechenden Befehle an deinen Roboter weitersenden.... das ist eine Sache von 30-40 Zeilen Code. Such mal nach Tutorials wie man einen TCP Server (+ Process.STDIN für dein Keyboard stream) erstellt.
 
Zuletzt bearbeitet:
also... nodejs funktioniert hier irgentwie nicht. (per lan zwar schon... aber sobald der accespoint läuft gehts nichtmehr :/)

ich möchte den roboter über ein webinterface steuern und keine anwendung in C schreiben.

wie verbinde ich javscript mit php genau?
hab bis jetzt nichts gefunden.

kennt jemand ein paar tutorials?
 
Mit AJAX. Wenn du nach AJAX Tutorials in Google suchst, bekommst du auch gleich ein paar simple Code Schnipsel.
 
Du musst so oder so eine Anwendung schreiben, die auf der Maschine läuft. Ob du die nun in PHP schreibst und einen überladenen Webserver dazu packst, in Node.JS arbeitest und etwas schlanker daher kommst oder eine noch effizientere Lösung wie C wählst (Stichwort Sockets), spielt nur eine untergeordnete Rolle.

Was die angebliche "Verbindung" zwischen PHP und JavaScript angeht: http://lmgtfy.com/?q=php+javascript
Kann es so schwer sein, etwas Eigeninitiative zu zeigen? Belies dich doch erst einmal, wie du Daten per HTML versendest und per PHP auswertest. Danach liest du, wie du JavaScript dazu verwendest, Daten per HTML zu versenden.
 
Man braucht doch überhaupt keinen Webserver! Zumindest wenn man nicht gerade sinnloserweise PHP einsetzt. Per JS sendet man doch einfach Daten via TCP und die muss man dann auf dem Pi auswerten und in eine Bewegung des Roboters umsetzen. Dazu kann man absolut jede Sprache die Sockets mitbringt nehmen. Genau das und nichts anderes hat Daaron gesagt, aber für einige war das wohl nicht deutlich genug.

Edit: Man sendet zwar von JS aus HTTP, aber das baut ja nur auf TCP auf, weshalb man einfach den HTTP Header wegwirft und das wars. Evtl. kann man das auch gleich so senden, ich glaube aber nicht.
 
Kanibal schrieb:
Jo, mal eben kurz nen Webserver implementieren.
Keinen ganzen. Es reicht, auf Port 80 zu lauschen und auf eingehende Requests standardgemäß zu antworten. All das, was Apache & Co können, ist vollkommen unnötig.

Freezedevil schrieb:
Man braucht doch überhaupt keinen Webserver! Zumindest wenn man nicht gerade sinnloserweise PHP einsetzt.
Auch in PHP sollte es ohne vollwertigen Webserver im Hintergrund gehen, per PHP CLI. Man muss aber so oder so wissen, was man grundsätzlich tun muss und wie solche Request-Response - Geschichten laufen.

Edit: Man sendet zwar von JS aus HTTP, aber das baut ja nur auf TCP auf, weshalb man einfach den HTTP Header wegwirft und das wars. Evtl. kann man das auch gleich so senden, ich glaube aber nicht.
HTML5 WebSockets sind wohl die Antwort...
Aber das ist trotz allem schon eher was für Fortgeschritten. Es wäre sinnvoll, das Ganze vorher möglichst schlicht zu halten, einfach nur ein paar kleine POST-Requests.
 
Daaron schrieb:
Auch in PHP sollte es ohne vollwertigen Webserver im Hintergrund gehen, per PHP CLI. Man muss aber so oder so wissen, was man grundsätzlich tun muss und wie solche Request-Response - Geschichten laufen.
Ja, das ist richtig.

Daaron schrieb:
HTML5 WebSockets sind wohl die Antwort...
Aber das ist trotz allem schon eher was für Fortgeschritten. Es wäre sinnvoll, das Ganze vorher möglichst schlicht zu halten, einfach nur ein paar kleine POST-Requests.

Mit Websockets hab ich mich leider noch nie auseinandergesetzt. Ich hab gerade mal auf Basis von XMLHttpRequests eine kleine Demo geschrieben (aus eigenem Forschungsdrang^^). Da klebt der Browser auf jeden Fall noch nen Http-Header auf die Daten drauf, aber den kann man in seiner Serveranwendung einfach wegwerfen.
Ergänzung ()

Also bei mir sähe das dann so ungefähr aus
Website:
Code:
<html>
<head>
    <script type="text/javascript">

document.onkeydown = function(event) {
    var address = "http://141.24.46.171:1339";
    var req = new XMLHttpRequest();
    req.open("POST", address, true);
    req.send(event.keyCode);
}

    </script>
</head>
<body>
</body>
</html>

Die gesendeten Daten sehen dann ungefähr so aus:
Code:
POST / HTTP/1.1
Host: 141.24.46.171:1337
Connection: keep-alive
Content-Length: 3
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1626.0 Safari/537.36
Origin: null
Content-Type: text/plain;charset=UTF-8
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

87

Der Server:
Code:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>

using std::cout;
using std::cerr;
using std::endl;
int main() {

    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket < 0) {
        cerr << "Problem opening socket" << endl;
    }

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(1339);

    if (bind(clientSocket, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) {
        cerr << "Error on binding" << endl;
    }

    listen(clientSocket, 5);

    int keyCode = 0;
    while(keyCode != 13) {
        struct sockaddr_in client_addr;
        socklen_t clientlen = sizeof(client_addr);
        int accsocket = accept(clientSocket, (struct sockaddr*) &client_addr, &clientlen);
        if (accsocket < 0) {
            cerr << "Error on accept" << endl;
        }

        char buffer[2048];
        int bytes = read(accsocket, buffer, 2047);
        std::string s(buffer);
        keyCode = atoi(s.substr(bytes-2, 2).c_str());
        write(accsocket, "ok", 2);
        close(accsocket);

        switch(keyCode) { // w 87; a 65; s 83; d 68; enter 13; + arrows
            case 38:
            case 87: cout << "Move forward" << endl; break;
            case 37:
            case 65: cout << "Move left" << endl; break;
            case 40:
            case 83: cout << "Move backward" << endl; break;
            case 39:
            case 68: cout << "Move right" << endl; break;
            case 13: break;
            default: cout << "Unknown Command" << endl;
        }
    }
    close(clientSocket);
    return 0;
}

Der Server ist übrigens ganz schön zusammengeschustert. Vor allem das "parsen" der eigentlichen Informationen ist hochgradig gefährlich^^ (zB falls der keyCode nicht genau zweistellig ist). Naja, es funktioniert aber und liefert beispielsweise folgende Ausgaben:
Code:
Move forward
Move forward
Move left
Move left
Move backward
Move backward
Move right
Move right
Unknown Command
 
Wenn mans nicht in C machen will oder kann:
http://php.net/manual/de/sockets.examples.php <- PHP-basiertes Lauschen auf einem Socket im Command Line - Modus.
Der Vorteil von C ist natürlich, dass man bei erfolgtem Eventeingang einfach forken kann und die tatsächliche Verarbeitung in nem separaten Prozess erfolgt. Ist schön, wenn man langwierige Dinge zünden will. Dafür wirds schwerer zu verhindern, dass Dinge nicht gleichzeitig passieren, die nicht gleichzeitig passieren dürfen.

Auf was bei all dem immer zu achten ist, egal womit man nun im Endeffekt die Server-Anwendung schreibt: Nicht die Ports mehrfach belegen. Wenn bereits ein Webserver läuft, z.B. eben Apache, dann ist Port 80 tabu.
So oder so wäre es sinniger, das Ding auf nem Fantasie-Port laufen zu lassen, damit sich nix in die Quere kommt.

Was HTML5 Websockets angeht: Ich hatte leider auch noch keine Gelegenheit, damit praktisch herumzupfuschen. Ich werd leider dafür bezahlt, dass der Kunde zügig was vorzeigbares hat, nicht dafür, neumod'schen Kram auszuprobieren. Von der Theorie her sollten Websockets aber tatsächlich ohne HTTP-Header auskommen.
 
Darf ich mal? :D

index.html
HTML:
<html>
<head>
    <script type="text/javascript">
		document.onkeydown = function(event) {
			var req = new XMLHttpRequest();
			req.open("POST", '/', true);
			req.setRequestHeader("x-requested-with", "XMLHttpRequest");
			req.send(event.keyCode);
		}
    </script>
</head>
<body>
</body>
</html>

server.nodejs
Code:
#!/usr/bin/env nodejs

var http = require('http'), util = require('util'), fs = require('fs'), console = require('console')

http.createServer(function (request, response) {
    if (request.headers['x-requested-with'] == 'XMLHttpRequest') {
        response.writeHead(200, {'content-type':'text/plain'})
        request.on('data', function (data) {
            data = parseInt(data)
            switch(data) {
                case 37:
                    console.log("Moving left ...")
                    break
                case 38:
                    console.log("Moving up ...")
                    break
                case 39:
                    console.log("Moving right ...")
                    break
                case 40:
                    console.log("Moving down ...")
                    break
            }
        });
        response.end()
    } else {
        if (request.url == '/') {
            response.writeHead(200, {'content-type': 'text/html'})
            util.pump(fs.createReadStream('index.html'), response)
        }
    }
}).listen(1337)

Hat halt keine Buffer-Overflows und ist deutlich kompakter.
 
Klar ist das schöner. Das abstrahiert von dem ganzen lowlevel Socketgedöhns, was mir auch immer auf den Sack geht, da sich das kein Mensch merken kann und man es immer irgendwoher kopieren muss. Das Problem war ja, dass das node.js beim TE irgendwie nicht ging und daher andere Lösungen gefragt waren (das Problem saß vermutlich ca. 50cm vorm Bildschirm ;)).

Ich hab mir vorhin schon ein bisschen was zu node.js angesehen und finde das eigentlich ziemlich cool. Das werde ich mir zusammen mit Websockets demnächst sicherlich mal näher ansehen.
Ergänzung ()

Zwei Anmerkungen hätte ich allerdings noch.

1. Wie sprichst du mit req.open("POST", '/', true); den Server an? Das funktioniert bei mir nicht, bis ich nicht für '/' ne IP und nen Port eintrage (anders kann ich mir das beim besten Willen auch nicht vorstellen)

2. Ich muss in die die Funktion unbedingt noch die folgenden Zeilen schreiben, damit das bei mir geht. Ich denke damit bin ich nicht der Einzige.
Code:
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
 
Zuletzt bearbeitet:
Zurück
Oben