Newsletter Versand - 1 Sek META Refresh - HTTP Zusatandsl. Prot.
H.W.
- programmiertechnik
Hallo!
Ein Newsletter der via WEB Oberfläche im Browser versendet wird
hat sehr viele Abbonenten.
Der Server hat einen Timeout von 10 Sekunden.
Jede Mail soll einzeln gesendet werden wg. TO: Feld.
CC und BCC soll _NICHT_ genutzt werden (wg. SPAM Verdacht)
Werden alle User in einer Schleife durchlaufen,
bekommen nichtmal ein Viertel eine Mail,
weil der der Server nach 10 Sekunden ein Timeout gibt.
Es sollte ja gehen,
das Script aufzurufen mit einem Parameter: newsletter.php?user=1-20
und beim nächsten Aufruf newsletter.php?user=21=40
und dann ?user=41-60 etc, etc, etc ....
Theoretisch ist ja HTTP ein Zustandloses Protokoll.
Wenn ich was sende, und dann Abbreche,
merkt das der Server nicht (oder?)
Getesteter Weise sitze ich 10 Sekunden vorm PC,
bis die 20 Mails gesendet sind.
Das sah ich als ich die Schleife beim Senden einzeln die
Emails auf dem Bildschirm ausgeben ließ als sie gesendet wurden.
Nun wäre es aber ein Schwachsinn,
bei 20 Mails 10 Sekunden Server Timeout abzuwarten bis
die 20 Mails sicher gesendet sind, wenn der Server das eh nicht merkt.
Also könnte ich ja eigentlich ein Script schreiben,
das einen META Refresh von _1_Sekunde_(!!!) hat,
und sich dann gleich mit dem Parameter für die nächsten 20 Mails aufruft,
auch wenn in der 1 Sekunde NICHT alle 20 Mails gesendet wurden,
weil auch nach dem Abbrechen(!) des Ladens nach der 1 Sekunde META Refresh
die anderen Mails noch weiter gesendet werden.
Wenn ich z.B. 600 User habe, also auch 600 Mails zu versenden,
und je 10 Sekunden 20 Mails versenden kann,
müsste ich - wenn ich jedesmal die 10 Sekunden ABWARTE (!)
(wie es normalerweise glaub ich gemacht wird)
insgesamt 35 Aufrufe X (mal) 10 Sekunden warten,
bis alle Mails durch sind. (== 350 Sekunden == knapp 6 Minuten)
Mit meiner Methode dass ich das Script nur kurz aufrufe
mit jeweils 20 Mails, und gleich nach 1 Sekunde das Laden
abbreche(!!) und das Script wiederum mit den nächsten 20 Mails aufrufe, (META REFRSH) und so weiter,
würde ich nur 35 Aufrufe x 1 Sekunde (==35 Sekunden == HALBE Minute)
vor dem Bildschirm sitzen. (viel Kürzer!)
Die Frage ist nur, ob der Server wirklich brav die 20 Mails sendet,
auch wenn ich nach 1 Sekunde das Laden abbreche.
Wenn das nicht so ist, müsste ich wirklich immer die 10 Sekunden warten
bis die 20 Mails durch sind (die Zeit hab ich gestoppt)
und dann das Script erst neu aufrufen mit den nächsten 20....
Was sagt ihr dazu?
Bitte um Hilfe, das Thema ist mir sehr wichtig,
da es nicht sein darf dass ich falsch denke und aufgrund meines
Verschuldens Abbonenten keine Post bekommen.
Vielen Dank,
H.W.
PS.: Es handelt sich ehrlich um erwünschte Zusendungen und NICHT um Spam! (Ehrlich!)
Hello,
ist der Safe_mode aktiviert?
Welche PHP-Version ist im Einsatz?
Du könntest die Sache mittels JavaScript-->submit() oder Metarefresh vom Client aus steuern.
In der Datenbank würdest Du vermerken, welche Mails versandt sind. Dafür durchläust Du eine "Schleife":
lock table $tablename
select $fieldlist from $tablename where $filter and mailcode < $mailcode order by $order limit 1
mailversenden()
update $tablename set mailcode = $mailcode where ID = $letzteermittelte ID
unlock tables
putHTML
Wenn man das Risiko eingehen will, dass der Mailversand dann nicht unbedingt wirklich angestoßen werden konnte, aber die Datenbankperformane nicht kaputtmachen will, kann man das auch anders herum anordnen:
lock table $tablename
select $fieldlist from $tablename where $filter and mailcode < $mailcode order by $order limit 1
update $tablename set mailcode = $mailcode where ID = $letzteermittelte ID
unlock tables
mailversenden()
putHTML
Wie es zu codieren ist, probier erstmal selber aus. Die Schleife entsteht durch den Dialog von Server und Client. Wenn der Auftrag erledigt ist, wird das das Stückchen JavaScript mir dem Submit()einfach nicht mehr mitgesandt und stattdessen der Statusbericht gesendet.
Du kannst das Ganze natürlich auch immer für 10 emails aufbauen. Dann muss das Script eben noch eine echte Schleife bekommen für den Mailversand.
lock table $tablename
select $fieldlist from $tablename where $filter and mailcode < $mailcode order by $order limit 10
update $tablename set mailcode = $mailcode where ID = $letzteermittelte ID
unlock tables
i = numrows
while i > 0 -->
mailversenden()
i--
<--
putHTML
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
Ich gehe mal davon aus, dass du PHP laufen hast. Ansonsten ist es prinzipiell gleich:
Ein Newsletter der via WEB Oberfläche im Browser versendet wird hat sehr viele Abbonenten.
Der Server hat einen Timeout von 10 Sekunden.
Diese eingestellten 10 Sekunden beziehen sich meist auf verbrauchte Prozessorzeit. Wenn ein Script warten muss, weil grad ein anderer Prozess an der Reihe ist oder weil es schläft, verbraucht es auch keine Zeit (Probier das mal aus!). Wenn das bei deinem Provider nicht so ist, dann ist das zum einen ungerecht und zum andern kann dir dann jeder beliebige andere Prozess dazwischenfunken. Du solltest dir dann überlegen, den Provider zu wechseln...
Werden alle User in einer Schleife durchlaufen, bekommen nichtmal ein Viertel eine Mail,
weil der der Server nach 10 Sekunden ein Timeout gibt.
Es sollte ja gehen, das Script aufzurufen mit einem Parameter: newsletter.php?user=1-20
und beim nächsten Aufruf newsletter.php?user=21=40
und dann ?user=41-60 etc, etc, etc ....
Angenommen, die 10 Sekunden gelten wie oben beschrieben nur für eine einzige Instanz deines aufgerufenen Scripts, kannst du auch mehrere quasi gleichzeitig anstoßen und in jeweils einer eigenen Browserinstanz laufen lassen. Sie erhalten dann jeweils ihre 10 Sekunden.
Theoretisch ist ja HTTP ein Zustandloses Protokoll.
Wenn ich was sende, und dann Abbreche, merkt das der Server nicht (oder?)
Zustandslos ist es von Applikationen aus betrachtet, die mehrere Webseiten umfassen. HTTP ist ein TCP und jeder Request + Response hat damit einen definierten Beginn, ein Ende und kann zwischendrin abgebrochen werden, sowohl durch Client als auch Server oder Timeout.
Getesteter Weise sitze ich 10 Sekunden vorm PC, bis die 20 Mails gesendet sind.
Das sah ich als ich die Schleife beim Senden einzeln die
Emails auf dem Bildschirm ausgeben ließ als sie gesendet wurden.
mit flush() nach jeder Mail und Stoppuhr oder mit Zeitmessung im Script (z.B. microtime()) getestet?
Nun wäre es aber ein Schwachsinn, ... [den] Server Timeout abzuwarten ..., wenn der Server das eh nicht merkt.
Ob er das merkt kommt ganz drauf an ... siehe weiter unten.
Also könnte ich ja eigentlich ein Script schreiben,
das einen META Refresh von _1_Sekunde_(!!!) hat,
und sich dann gleich mit dem Parameter für die nächsten 20 Mails aufruft,
auch wenn in der 1 Sekunde NICHT alle 20 Mails gesendet wurden,
weil auch nach dem Abbrechen(!) des Ladens nach der 1 Sekunde META Refresh
die anderen Mails noch weiter gesendet werden.
Der Refresh wird erst dann ausgeführt, wenn die Übertragung vollständig ist, sprich: wenn dein Script fertig abgearbeitet oder abgebrochen wurde. Im zweiten Fall aber nur, wenn der refresh-meta-Tag bereits im Browser gelandet ist. Das passiert ja nicht immer sofort, da der Webserver die Ausgabe zwischenspeichert, um nicht so viele kleine Pakete zu senden.
Alternativ zum meta-refresh und browserunabhängig kann man auch einen Location-Header schicken.
Die Frage ist nur, ob der Server wirklich brav die 20 Mails sendet,
auch wenn ich nach 1 Sekunde das Laden abbreche.
Da gibt es Einstellmöglichkeiten, wie PHP auf Abbruch durch den User reagieren soll. Ob das zuverlässig funktioniert weiß ich nicht.
Wenn das nicht so ist, müsste ich wirklich immer die 10 Sekunden warten
bis die 20 Mails durch sind (die Zeit hab ich gestoppt)
und dann das Script erst neu aufrufen mit den nächsten 20....
Mehrere Fenster öffnen oder den meta-Refresh bzw. Location-Header das nacheinander tun lassen.
Ich würde das zusammen mit Toms Vorschlag, die versendeten Mails in der Datenbank zu markieren, und einem Meta-Refresh/Location-Header zu lösen versuchen.
Prinzip-Skizze:
if SELECT COUNT(*) from ... WHERE unversendet {
Location-Header (PHP_SELF)
flush();
while ( SELECT ID,... FROM ... WHERE unversendet LIMIT 1 ) {
Mail senden
UPDATE versendet WHERE ID=id
}
}
echo fertig
Hallo dedlfix!
Danke für Deine Antowrt!
Ich verwende Perl und versteh die Sachen mit PHP nicht!
Was ist der trick den Du verwendest?
Ich seh nichts was den timeout umgeht!
Wie gesagt - Perl!
Ist der trick in flush() oder wie?
Das mit dem Header und wie bei Abbruch verhalten und so
ist in perl sicher auch anders wie in Perl.
Danke,
HW
Ich verwende Perl und versteh die Sachen mit PHP nicht!
Das sollte doch kein grundlegendes Problem sein. Lies dir die Funktionsweise der von mir genannten PHP-Funktionen durch und suche nach etwas gleichwertigem in Perl.
Was ist der trick den Du verwendest?
Ich seh nichts was den timeout umgeht!
Ich umgehe ihn nicht. Ich lasse mich nur nicht von ihm ärgern und mache da weiter, wo der Timeout zugeschlagen hat.
Wie gesagt - Perl!
Ist der trick in flush() oder wie?
Beim Programmieren gibt es keine Tricks, nur Vorgehensweisen.
Du musst den Refresh (egal ob als Location-Header oder als meta-refresh) zum Browser senden. flush sorgt dafür, dass die Daten nicht im Sende-Puffer vergammeln. (Ich weiß leider nicht, ob das in Perl so geht... kann mir aber auch nicht vorstellen dass das da prinzipiell nicht so gehen soll. Perl und PHP kochen ja beide auch nur mit Wasser.) Ausgeführt wird der Refresh vom Browser erst, wenn entweder dein Script fertig ist oder der Timeout zugeschlagen hat. Ansonsten habe ich den Programmablauf in der Prinzip-Skizze beschrieben.
Das mit dem Header und wie bei Abbruch verhalten und so
ist in perl sicher auch anders wie in Perl.
Da muss man ja für die Header komplett selber sorgen. Aber ansonsten musst du eigentlich nur den Location-Header hinzufügen, oder du machst das mit dem Meta-Refresh, wenn dir der besser vertraut ist.
Zum Abbruchverhalten von Perl kann ich nichts sagen. Das ist aber hier egal, weil du ja (als User) nicht vorhast das Script abzubrechen.