Netzwerkservice

01/03/2012 - 10:16 von Stefan Dreyer | Report spam
Hallo,

ich bin dabei zu überlegen, wie ich einen Netzwerkservice in PHP
programmiere, für folgendes Szenario:

Es gibt einen Remote-Barcode-Scanner, der eingescannte Codes per TCP
oder UDP an einen Server zur Weiterverarbeitung sendet. Aller
Voraussicht nach, wird sich der Server im LAN befinden, oder aber per
VPN angebunden sein.
Die Frage, ob ich nun TCP oder UDP benutze, habe ich noch nicht
endgültig entschieden. Da es nicht ganz so schlimm ist, wenn mal ein
Code verloren geht, bin ich geneigt UDP zu benutzen. Für den Fall, dass
ich TCP benutze, bin ich mir nicht ganz sicher, ob ich die Verbindung
aufgebaut lassen sollte, oder jedesmal eine neue Verbindung aufbaue.
Letzteres scheint mir etwas robuster zu sein.
Da die Dokumentation im Manual über Sockets etwas sparsam ist, habe ich
zu ausprobieren mal etwas Code aus dem Manual benutzt und ein wenig
getestet:

function tcpServer($portD44,$address = '0.0.0.0') {

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

if (socket_bind($sock, $address, $port) false) {
echo "socket_bind() failed: reason: " .
socket_strerror(socket_last_error($sock)) . "";
}

if (socket_listen($sock, 5) false) {
echo "socket_listen() failed: reason: " .
socket_strerror(socket_last_error($sock)) . "";
}

do {
if (($msgsock = socket_accept($sock)) false) {
echo "socket_accept() failed: reason: " .
socket_strerror(socket_last_error($sock)) . "";
break;
}
do {
if (false ($buf = socket_read($msgsock, 2048,
PHP_NORMAL_READ))) {
echo "socket_read() failed: reason: " .
socket_strerror(socket_last_error($msgsock)) . "";
break ;
/*
Hier stand ursprünglich break 2, aber damit beendet sich der Service
komplett, wenn der Client abgebrochen wird. Funktioniert aber noch nicht
zufriedenstellend.
*/
}
if (!$buf = trim($buf)) {
continue;
}
if ($buf == 'quit') {
break;
}
if ($buf == 'shutdown') {
socket_close($msgsock);
break 2;
}
$talkback = "Scan:".$buf.".";
socket_write($msgsock, $talkback, strlen($talkback));
echo "$buf";
} while (true);
socket_close($msgsock);
} while (true);
socket_close($sock);
}

Obiger Service hat nun einige Nachteile. Zum einen nimmt der Service nur
eine Verbindung entgegen (was aber nicht so schlimm wàre, da es sowieso
geplant ist, pro Scanner einen eigenen Port zu benutzen), zum anderen
ist der Service nicht robust, wenn die Verbindung vom Client
unterbrochen wird.


Da ich leider bisher nichts wirklich aufschlussreiches zu dem Thema
gefunden habe, bin ich für Vorschlàge zur Verbesserung dankbar.
 

Lesen sie die antworten

#1 Peter Blancke
01/03/2012 - 10:37 | Warnen spam
Am 2012-03-01, Stefan Dreyer schrieb:

Da ich leider bisher nichts wirklich aufschlussreiches zu dem
Thema gefunden habe, bin ich für Vorschlàge zur Verbesserung
dankbar.



Aehnliches Problem bei mir mit einer anderen Anwendung. Ich habe
allerdings den xinetd dafuer hergenommen:

,-
| service mein_service
| {
| disable = no
| socket_type = stream
| protocol = tcp
| wait = no
| user = blancke
| env = HOME=/home/blancke
| server = /home/blancke/bin/mein_service_programm.php
| }
`-

Das angegebene Programm bekommt die Daten mit der Zeile:

,-
| $data=trim(fgets(STDIN));
`-

Gegen offen gelassene Verbindungen schuetzt ein Signalhaendler, der
nach einer Verweilzeit von 30 Sekunden die Verbindung kappt,
sinngemaesz:

,-
| declare (ticks=1);
|
| function signal_handler($signal)
| {
| if (SIGALRM$signal)
| {
| die();
| }
| } // function signal_handler($signal)
|
| pcntl_signal(SIGALRM, "signal_handler");
| pcntl_alarm(30);
|
| pcntl_alarm(0);
`-

Das laeuft hier sehr stabil seit einigen Jahren.

Grusz,

Peter Blancke

Hoc est enim verbum meum!

Ähnliche fragen