Vom Server gesendete Ereignisse und php - was löst Ereignisse auf dem Server aus?
Alle,
HTML5 Rocks hat ein schönes Anfänger-tutorial auf Server-sent-Events (SSE):
http://www.html5rocks.com/en/tutorials/eventsource/basics/
Aber, ich verstehe nicht, ein wichtiges Konzept, das - was löst das Ereignis auf dem server, der bewirkt, dass eine Nachricht gesendet werden?
In anderen Worten - in der HTML5-Beispiel - der server sendet einen timestamp einmal:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); //recommended to prevent caching of event data.
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
$serverTime = time();
sendMsg($serverTime, 'server time: ' . date("h:i:s", time()));
Wenn ich Gebäude ein praktisches Beispiel, z.B. ein Facebook-Stil "Wand" oder ein Aktien-ticker, in dem der server ein "push" eine neue Nachricht an den client jedes mal ein Stück von Datenänderungen, wie funktioniert das?
In anderen Worten... Funktioniert das PHP-Skript eine Schleife, die kontinuierlich läuft, prüft eine änderung der Daten, dann das senden einer Nachricht jedes mal, wenn er eine findet? Wenn ja, wie wollen Sie wissen, Wann Sie zu Ende dieses Prozesses?
Oder - macht das PHP-script senden Sie einfach die Nachricht, dann Ende, (wie der Fall zu sein scheint, in der HTML5Rocks Beispiel)? Wenn ja - wie bekommen Sie kontinuierliche updates? Ist der browser einfach polling die PHP-Seite in regelmäßigen Abständen? Wenn ja - wie ist das ein "server-sent-event"? Wie unterscheidet er sich vom schreiben einer setInterval-Funktion in JavaScript, die verwendet AJAX-Aufruf eine PHP-Seite, die in regelmäßigen Abständen?
Sorry - das ist wahrscheinlich eine unglaublich naive Frage. Aber keines der Beispiele habe ich in der Lage zu finden, machen dies deutlich.
[UPDATE]
Ich denke, meine Frage war schlecht formuliert, deshalb hier einige Klarstellungen.
Sagen wir mal ich habe eine web-Seite, die sollte dir die neueste Preis der Apple-Aktie.
Wenn der Benutzer die Seite öffnet, wird die Seite schafft eine EventSource, die mit der URL von meinem "Bach."
var source = new EventSource('stream.php');
Meine Frage ist - wie sollen "stream.php" Arbeit?
So? (pseudo-code):
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); //recommended to prevent caching of event data.
function sendMsg($msg) {
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
flush();
}
while (some condition) {
//check whether Apple's stock price has changed
//e.g., by querying a database, or calling a web service
//if it HAS changed, sendMsg with new price to client
//otherwise, do nothing (until next loop)
sleep (n) //wait n seconds until checking again
}
?>
In anderen Worten - tut "stream.php" bleiben so lange offen, wie der client "connected"?
Wenn dem so ist - bedeutet das, dass Sie so viele threads stream.php
wie Sie gleichzeitige Nutzer? Wenn dem so ist - ist das aus der Ferne machbar, oder eine geeignete Weg, um eine Anwendung zu erstellen? Und wie wissen Sie, wenn Sie können ENDE eine Instanz von stream.php
?
Meiner naiven Eindruck ist, dass, wenn dies der Fall ist, PHP nicht eine geeignete Technologie für diese Art von server. Aber alle demos die ich bisher gesehen habe, bedeuten, dass PHP gerade für diese feine, das ist, warum ich bin so verwirrt...
InformationsquelleAutor der Frage mattstuehler | 2013-01-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Server-sent events sind für Echtzeit-update von der server-Seite die client-Seite. Im ersten Beispiel wird die Verbindung vom server nicht gehalten und der client versucht, die Verbindung wieder alle 3 Sekunden und macht den server-sent-events keinen Unterschied zu ajax polling.
So, damit die Verbindung bestehen, müssen Sie wickeln Sie Ihren code in einer Schleife und nach updates suchen ständig.
PHP thread-basiert und mehrere angeschlossene Nutzer wird dem server die Ressourcen ausgehen. Dieses Problem kann gelöst werden, durch die Kontrolle des script-execution-time und end das Skript, wenn es über eine Zeit (z.B. 10min). Die
EventSource
API wird automatisch die Verbindung wieder, so dass die Verzögerung in einem akzeptablen Bereich.Schauen Sie sich auch meine PHP-Bibliothek für Server-sent eventskönnen Sie verstehen mehr über, wie man server-sent-events in PHP und machen es einfacher zu Programmieren.
InformationsquelleAutor der Antwort Licson
Ja, und Ihre pseudo-code ist ein vernünftiger Ansatz.
In der typischste Fall, dies passiert, wenn der user verlässt Ihre Website. (Apache erkennt der socket geschlossen, und tötet die PHP-Instanz.) Die wichtigste Zeit, die Sie möglicherweise schließen Sie den sockel von der server-Seite ist, wenn Sie wissen, dass es keine Daten für eine Weile; die Letzte Nachricht, die Sie senden, die den client, um Ihnen zu sagen, um zurück zu kommen zu einer bestimmten Zeit. E. g. in Ihrem Lager-streaming-Fall, könnte man schließen, die Verbindung zu 8pm, und sagen Kunden zum wieder kommen in 8 Stunden (bei NASDAQ ist offen für Angebote von 4 Uhr morgens bis 8 Uhr abends). Freitag Abend, Sie sagen, Sie kommen zurück am Montag morgen. (Ich habe ein demnächst erscheinendes Buch auf SSE, und widmen ein paar Abschnitte zu diesem Thema.)
Nun, die Leute behaupten, dass PHP nicht eine geeignete Technologie für den normalen web-Seiten, und Sie haben Recht: Sie könnten, tun Sie es mit weit weniger Speicher und CPU-Zyklen, wenn Sie ersetzt Ihren gesamten LAMP-stack mit C++. Doch trotz dieser, PHP Befugnisse, die meisten Websites gibt, einfach nur gut. Es ist eine sehr produktive Sprache für die web-Arbeit, durch eine Kombination von einer bekannte C-ähnliche syntax und so viele Bibliotheken, und eine beruhigende für Führungskräfte wie viel PHP-Programmierer zu mieten, viele Bücher und andere Ressourcen, und einige große Anwendungsfälle (z.B. Facebook und Wikipedia). Im Grunde sind das die gleichen Gründe, die Sie wählen könnten, PHP als Ihre streaming-Technologie.
Das typische setup wird nicht gehen, um eine Verbindung zu NASDAQ pro PHP-Instanz. Anstatt Sie gehen zu müssen, einem anderen Prozess mit einem einzigen Anschluss an der NASDAQ, oder vielleicht eine einzelne Verbindung von jeder Maschine im cluster ist an der NASDAQ. Das treibt die Preise in einem SQL - /NoSQL-server, oder ins shared memory. Dann PHP nur Umfragen, dass der freigegebene Speicher (oder die Datenbank), und schiebt die Daten raus. Oder haben eine Datenerfassungs-server, und jede PHP Instanz öffnet eine socket-Verbindung zu diesem server. Die Datenerfassungs-server schiebt die updates auf die einzelnen PHP-clients, wie er Sie empfängt, und Sie wiederum drücken aus, dass die Daten Ihrer Kunden.
Den wichtigsten Skalierbarkeit Problem mit Apache+PHP, die für das streaming ist der Speicher, der für jeden Apache-Prozess. Wenn Sie erreichen das memory limit der hardware, machen die business-Entscheidung zum hinzufügen weiterer Rechner zum cluster, geschnitten oder Apache aus der Schleife heraus, und schreiben Sie einen dedizierten HTTP-server. Letztere kann man in PHP so alle Ihre vorhandenen Kenntnisse und code wiederverwendet werden können, oder schreiben Sie die ganze Anwendung in eine andere Sprache. Die reinen Entwickler in mich zu schreiben, wäre eine dedizierte, optimierte HTTP-server in C++. Der manager in mir würde fügen Sie ein weiteres Feld.
InformationsquelleAutor der Antwort Darren Cook
Habe ich bemerkt, dass die sse-techink sendet alle paar delay-Daten an den client (somtething wie die Umkehrung der Bündelung von Daten techink von der client Seite-e.x. Ajax-pooling-Daten). also, dieses problem zu überwinden, ich habe diese bei einer sseServer.php Seite :
und die sse.php ist :
Feststellen, dass bei den sseSerer.php ich starte eine Sitzung und über eine session-variable! um das problem zu überwinden.
Außerdem rufe ich die sseServer.php via Ajax (Buchung und legen Wert auf
variable message
) jedes mal, wenn ich auf "update" angezeigt.Jetzt auf jQuery (javascript -) sowas mache ich :
1.) ich deklariere eine Globale variable var timeStamp=0;
2.) ich benutze das nächste Algorithmus :
In der Zeile von :
$.notify("Please refresh "+event.data, "info");
dort können Sie die Meldung verarbeiten.
Für meinen Fall, die ich verwendet, um senden Sie eine jQuery Benachrichtigen.
Können Sie verwenden Sie POSIX-PIPES oder eine DB-Tabelle statt durch die "Meldung" per POST, da die sseServer.php hat so etwas wie eine "Endlosschleife".
Mein problem zur Zeit ist, dass der obige code NICHT SENDET DIE "Nachricht" an alle Kunden, sondern nur für die paar (client, dass heißt der sseServer.php arbeitet als Individuum zu jedem paar), so werde ich ändern die technik und ein DB-update von der Seite, die ich auslösen wollen, das "Nachricht" und dann die sseServer.php stattdessen bekommen die Mitteilung per POST erhalten Sie von der DB-Tabelle.
Ich hoffe, dass ich helfen!
InformationsquelleAutor der Antwort c.chasapis
Dies ist wirklich eine strukturelle Frage zu Ihrer Anwendung. Echtzeit-Ereignisse sind etwas, dass Sie wollen, darüber nachzudenken, von Anfang an, also können Sie Ihre Anwendung um ihn herum. Wenn Sie haben eine Anwendung geschrieben, die läuft einfach ein Haufen zufälliger
mysql(i)_query
Methoden mit string Abfragen und nicht passieren Sie durch keine Art von Vermittler, dann viele Male haben Sie keine Wahl aber entweder umschreiben, viel von Ihrer Anwendung, oder machen die ständigen server-Seite abrufen.Wenn, jedoch, Sie verwalten Ihre Entitäten werden als Objekte und übergeben Sie Sie durch eine Art von Vermittler-Klasse, können Sie Haken in diesem Prozess. Schauen Sie auf dieses Beispiel:
In Ihrer Anwendung, wenn Sie bereit sind, zu sparen:
Dies ist nicht die anmutigen Beispiel, aber es sollte dazu dienen, eine anständige Baustein. Können Sie Haken in Ihrem eigentlichen Persistenz-Schicht zu behandeln Auslösung dieser Ereignisse. Dann bekommst du Sie sofort (in Echtzeit, wie es bekommen kann) ohne hämmern deinem server (da haben Sie keine Notwendigkeit, ständig Abfragen Ihrer Datenbank und sehen Sie, wenn die Dinge verändert).
Du offensichtlich nicht durchsetzen manuelle änderungen an der Datenbank auf diese Weise - aber wenn Sie etwas manuell in Ihre Datenbank mit einer beliebigen Frequenz, sollten Sie entweder:
InformationsquelleAutor der Antwort Colin M
Grundsätzlich ist PHP nicht geeignet techonology für diese Art von Sachen.
Ja, Sie können es schaffen, aber es wird eine Katastrophe auf highload. Wir führen stockservers, senden Sie stock-change-Signale über websockets zu Dutzenden tausenden von Benutzern - und die hätten wir php, dass... Nun, wir könnten, aber diese hausgemachte Zyklen - ist nur ein Alptraum. Jede einzelne Verbindung wird ein separater Prozess auf dem server, oder Sie haben, um verbindungen von irgendeiner Art von Datenbank.
Verwenden Sie einfach nodejs und socket.io. Es wird lassen Sie Sie einfach starten und haben einen Laufenden server in paar Tagen. Nodejs hat, die eigenen Grenzen auch, aber für websockets (und SSE) - verbindungen jetzt seine die meisten powerfull-Technologie.
- Und auch die - SSE ist nicht so gut, wie es scheint. Der Vorteil für websockets ist, dass Pakete gzipped nativ (ws ist nicht gzipped), aber der Nachteil an der Sache ist, dass die SSE ist eine serverseitige Verbindung. Sie Benutzer, wenn er will, weitere hinzufügen, stock symbol, um subscripton, haben wird, um die ajax-Anfrage (inklusive aller Probleme mit origin Kontrolle, und die Anforderung wird langsam). In websockets client und Server kommunizieren in beide Richtungen in einer einzelnen geöffneten Verbindung, sodass, wenn der Benutzer sendet eine trading-signal oder bezieht, zu zitieren, er senden Sie einfach eine Zeichenfolge in bereits geöffneten Verbindung. Und es ist schnell.
InformationsquelleAutor der Antwort Prosto Trader