2017-11-28 7 views
1

Ich musste eine Kommunikation zwischen einer in C++ geschriebenen Anwendung und einem mit PHP skriptgesteuerten Webserver implementieren. Die Grundidee war, einen Socket mit der C++ - Anwendung zu erstellen, ihn zu binden und auf die PHP-Verbindung zu warten. Die PHP würde dann eine Nachricht über TCP senden, die nach Daten fragt, und das C++ würde die Antwort zurücksenden. Single-Header-Anfrage, Einzel-String (JSON) -Antwort. So weit, so gut. Dies ist der Code, den ich für die PHP-Seite verwendet:Socket-Verbindung auf der gleichen Maschine, PHP zu C++ und zurück

<?php 
error_reporting(E_ALL); 

$service_port = 8080; 
$address = 'localhost'; 


$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
if ($socket === false) { 
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; 
} 

echo "Attempting to connect to '$address' on port '$service_port'..."; 
$result = socket_connect($socket, $address, $service_port); 
if ($result === false) { 
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; 
} 


$in = "request1"; 

$out = ''; 

socket_write($socket, $in, strlen($in)); 

$buf = 'This is my buffer.'; 
if (false !== ($bytes = socket_recv($socket, $buf, 2048, MSG_WAITALL))) { 
    echo "Read $bytes bytes from socket_recv(). Closing socket..."; 
} else { 
    echo "socket_recv() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n"; 
} 
socket_close($socket); 

echo $buf . "\n"; 
//elaborate the $buf 
?> 

Jetzt würde ich auch eine automatische Aktualisierung der Daten implementieren möchten, mit der C++ (Server-Seite) das Senden von Daten und der PHP-Seite (Client-Seite) um sie zu sammeln. Die Datenaktualisierung sollte jede Minute durchgeführt werden. Leider habe ich nicht viel Erfahrung mit Web-Entwicklung, also bitte ich um einige Ratschläge dazu.

Die einfachste Sache, die ich tun konnte, war das Schleifen des PHP-Codes, bis eine bekannte Nachricht empfangen wurde. Das Problem, dem ich gegenüberstand, ist, dass ich keine Daten bekomme, bis die Schleife vorbei ist und das PHP-Skript beendet ist. Um das Problem zu überwinden, versuchte ich, PHP-Seite den Socket als nicht blockierende setzen in der socket_recv die Option MSG_WAITALL mit MSG_DONTWAIT ersetzt, aber nichts geändert. Dann habe ich versucht, aus dem PHP-Skript auszubrechen, aber es kann nicht gemacht werden, da ich es zyklisch machen muss, um die Daten jede Sekunde zu bekommen. Plus Ich bekomme ein weiteres Problem, während der Schleife Zyklen, der Apache-Server, auf dem PHP ausgeführt wird, erhält einen Fehler 503, Server nicht verfügbar. Ich weiß nicht, warum es passiert, vielleicht ist der empfangene Nachrichtenpuffer voll, oder das Skript benötigt zu viele Ressourcen. Aufgrund meiner mangelnden Erfahrung kann ich nicht verstehen warum. Ich weiß, dass es gute Bibliotheken gibt, um das auszuführen, was ich brauche, aber ich arbeite an einem eingebetteten Computer, so dass ich nur mit einfachen Bibliotheken arbeiten kann.

Wie kann ich das PHP auf dem Apache-Server erzielen, um Zeitdaten von der C++ - Anwendung zu erhalten? Was übersehe ich? Vielen Dank im Voraus für Ihre Hilfe.

Edit: Deleted rhetorische Frage.

+0

[Warum ist "zeigen Sie mich in die richtige Richtung" ist keine eigentliche Frage.] (Https://meta.stackexchange.com/questions/226103/are-point-me-in-the-right-direction- Fragen-akzeptabel) –

Antwort

2

Die Verwendung von php, um Daten von einem anderen Prozess über tcp/ip zu erhalten, erfordert etwas mehr Aufwand im Vergleich zum Senden von Daten aus einem PHP-Skript über Apache an einen anderen Prozess mit tcp/ip Sockets.

Ihr PHP-Skript muss außerhalb von Apache gestartet werden und erfordert eine Endlosschleife, die kontinuierlich auf den angegebenen Port hört, um Eingabedaten zu lesen. Die following post umreißt, was ich glaube, dass Sie danach sind.

EDIT

Um die Ergebnisse auf der Webseite angezeigt werden Sie ein im Speicher Datenspeicher wie Redis nutzen könnten. Die PHP-Server-Anwendung würde eine Datenstruktur in redis aktualisieren, dann könnte die Webseite onload den neuesten Wert von redis ziehen und auf dem Bildschirm anzeigen, jedoch würde dies eine Seitenaktualisierung erfordern.

Wenn Sie möchten, dass die Daten sofort aktualisiert werden, sobald sie ohne Server-Postback empfangen werden, erfordert dies einige Javascript.Wenn ein Benutzer die Seite lädt, würden Sie eine Websocket-Verbindung mit einem Websocket-Server initialisieren (Leute verwenden normalerweise node.js und socket.io, um dies zu implementieren, aber Sie können einen Websocket-Server in allem kodieren, das die Technologie unterstützt). Der Websocket-Server würde einen Redis-Kanal abonnieren, der bei der Aktualisierung die neuen Werte an alle verbundenen Clients senden würde. Ich nehme an, dass dies auch ohne redis möglich wäre, je nachdem, was Ihre Anforderungen sind. Das Programm für den Websocket-Server könnte auch der Server sein, der die Informationen aus Ihrem C++ - Programm mit einem separaten Thread akzeptiert. Wenn Daten aus dem C++ Programm kommen, können Sie diese direkt an die über Websocket verbundenen Clients senden.

+0

Ich verstehe, was Sie mit dem PHP-Skript außerhalb Apache meinen. Wie könnte ich das Ergebnis auf der Webseite visualisieren? – Podarce

+0

@Podarce aktualisierte Antwort – commanderZiltoid

1

Das Rad nicht neu erfinden. Verwenden Sie einen Websockel. Es wurde entwickelt, um diese asynchrone Kommunikation durchzuführen, und Sie können JSON ganz einfach darüber senden.

Es gibt Bibliotheken für C++ und PHP, was bedeutet, dass dies ziemlich einfach sein sollte.

+0

Danke für den Vorschlag, Sir. Ich kann externe Bibliotheken nicht laden, außer sie sind nur Header. Vielleicht könnte ich versuchen, meinen eigenen Code für Websockets zu schreiben, denkst du, dass es machbar ist? – Podarce

+0

Nein, fehlende Websockets werfen JSON-Objekte einfach über den Socket hin und her. Das einzige Problem ist, dass Sie nicht wissen, wann das Objekt im Puffer fertig sein wird, also müssen Sie zuerst die Länge und dann das Json-Objekt senden. Dann lesen Sie auf der anderen Seite die Länge, lesen Sie dann diese vielen Bytes und rufen Sie an JSON.parse() darauf, damit für die nächste Nachricht nichts mehr übrig bleibt. – UserOneFourTwo

Verwandte Themen