[PHP] windows asynchrone mail()

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Skidmarks
  • Registratie: Februari 2001
  • Laatst online: 19-09 15:42
Is er op windows apache php een mogelijkheid om mail() asynchroon te laten werken?

Momenteel moet als reactie op een actie die een gebruiker via de browser doet een mail verstuurd worden. Het versturen van die mail kan echter nogal lang duren afhankelijk van de grote van de bijlage of de traagheid van de opgegeven smtp server. Aangezien de webbrowser van de gebruiker daar niet op hoeft te wachten zou ik het mail process graag asynchroon willen doen.

Het beste wat ik kan verzinnen is een ajax call die de browser zou doen zodat het asynchroon wordt verstuurd. Maar ik wil niet dat het versturen van de e-mail afhangt van een request die de client al dan wel of niet verstuurd. De trigger voor het versturen van de mail is eigenlijk een db verandering en in dat stuk server code wil ik het mail process starten maar dan asynchroon.

Ik heb zitten kijken naar pcntl_fork() maar dat werkt niet onder windows. Het moet een betrouwbare manier zijn die op verschillende windows ossen werkt (2000, XP, 2003, 2008 zowel 32bit als 64bit).

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Draai op localhost een SMTP server die dient als relay naar de echte SMTP server. Je kunt binnen een paar milliseconden je mail naar de localhost SMTP server sturen en vervolgens kan je applicatie in PHP gewoon verder. Op de achtergrond zal de SMTP relay dan verbinding zoeken met de echte SMTP server om de boel te versturen.

Acties:
  • 0 Henk 'm!

  • Skidmarks
  • Registratie: Februari 2001
  • Laatst online: 19-09 15:42
Het product waar ik momenteel aan werk wordt compleet geleverd aan de klant, dus een setup die zowel php, apache, mysql als de php code bij de klant op zijn windows (server) systeem in een keer installeert. Daardoor ben ik qua mogelijkheden wat beperkt. Sommige klanten zullen al een SMTP server op die machine hebben draaien en dus dit probleem niet hebben. Maar sommige gebruiken een externe SMTP server die vertragend werkt.

Ik begrijp dat ik een SMTP server zou kunnen mee installeren en dat dat het probleem inderdaad zou oplossen. Dit zou echter nogal wat wijzigingen vergen aan de huidige setup onder andere qua beheer en instellingen voor die mee te leveren SMTP server en ook nog qua licenties. Ik zal deze oplossing in gedachte houden maar ik hoop dat er voor deze situatie een makkelijkere oplossing bestaat.

Acties:
  • 0 Henk 'm!

  • Luqq
  • Registratie: Juni 2005
  • Laatst online: 19-09 14:23
Kan je de mail niet in een mysql database zetten, en dan met een cronjob elke 5minuten die DB doorspitten ?

Acties:
  • 0 Henk 'm!

  • Skidmarks
  • Registratie: Februari 2001
  • Laatst online: 19-09 15:42
cronjob werkt niet onder windows er is wel de windows schedule service die je via at met de command line kan instellen, die als het goed is iets soortgelijks bied. Dit zou ook nog een optie zijn maar dan zou ik uitgebreid moeten testen hoe betrouwbaar dat werkt onder alle host besturingssystemen die ik moet ondersteunen.

Acties:
  • 0 Henk 'm!

  • McKaamos
  • Registratie: Maart 2002
  • Niet online

McKaamos

Master of the Edit-button

Luqq's idee is wel een strak plan idd.
Onder windows heb je alleen geen Crontab, maar gelukkig wel een scheduling agent die hetzelfde doel heeft ;)

Mocht je toch met een lokale SMTP server gaan werken, dan kan je overwegen om hMailserver te gebruiken. Gratis en doet simpelweg relaying naar een andere server.

Iemand een Tina2 in de aanbieding?


Acties:
  • 0 Henk 'm!

  • ixi
  • Registratie: December 2001
  • Laatst online: 27-08 23:59

ixi

Je zou vanuit je script een (asynchrone) HTTP call kunnen doen, naar een ander script dat de mail daadwerkelijk gaat versturen. Deze methode gebruik ik om een bulkmailing vanuit PHP te doen, en voorkomt dat de gebruiker zelf het proces nog kan verstoren. Wel is het natuurlijk een beetje vies :)

Acties:
  • 0 Henk 'm!

  • Skidmarks
  • Registratie: Februari 2001
  • Laatst online: 19-09 15:42
Die HTTP Post vanuit een php script doe je dan neem ik aan via curl. Ik zie zo gauw geen optie om curl asynchroon te laten werken of doet curl dat al standaard?

Acties:
  • 0 Henk 'm!

  • ixi
  • Registratie: December 2001
  • Laatst online: 27-08 23:59

ixi

Dit gebruik ik:

PHP:
1
2
3
4
5
6
7
8
9
10
11
$socket = fsockopen("site.nl",80);
$header = "GET /url HTTP/1.1\r\n";
$header .= "Host: site.nl\r\n";
$header .= "User-Agent: PHP\r\n";
$header .= "Accept: */*\r\n";
$header .= "Connection: close\r\n";
$header .= "Keep-Alive: 300\r\n";
$header .= "Accept-Charset: utf-8\r\n";
$header .= "Accept-Encoding: gzip,deflate\r\n";
$header .= "\r\n";
fwrite($socket,$header);


Om te zorgen dat het mail-script nooit direct wordt aangeroepen check ik de user-agent, hoewel dat natuurlijk ook te faken valt. Een veiligere methode is natuurlijk ook makkelijk gemaakt. Ook kan fsockopen natuurlijk falen, dat zou je kunnen afvangen.

Als je POST data erbij wilt gooien zou je even de HTTP specs erbij moeten pakken. Dat is verder ook niet lastig, tenzij je de POST data als multipart erbij wilt zetten.

[ Voor 16% gewijzigd door ixi op 23-02-2009 14:47 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Het makkelijkste lijkt me om gewoon met behulp van register_shutdown_function() aan het eind van het script je mails te versturen.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

En op welke manier zorgt dit dat de bezoeker niet hoeft te wachten op het versturen van de mail?

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Nu online

orf

Check ook even ignore_user_abort() om er zeker van te zijn dat executie niet gestopt wordt op het moment dat een request wordt afgebroken.

Acties:
  • 0 Henk 'm!

  • Skidmarks
  • Registratie: Februari 2001
  • Laatst online: 19-09 15:42
Ik zal die twee functies (register_shutdown_function() en ignore_user_abort()) binnenkort testen die zijn op dit moment het makkelijkste te implementeren in de huidige code, aangezien het versturen van de e-mail maar één functie aanroep is en die mag als allerlaatste worden aangeroepen.

Acties:
  • 0 Henk 'm!

  • ixi
  • Registratie: December 2001
  • Laatst online: 27-08 23:59

ixi

CodeCaster schreef op maandag 23 februari 2009 @ 15:44:
[...]
En op welke manier zorgt dit dat de bezoeker niet hoeft te wachten op het versturen van de mail?
Omdat het versturen in een ander script gebeurt, en er verder geen blocking optreed bij het aanroepen van dat script (alleen bij het maken van de verbinding naar de webserver, maar dat gaat meestal toch vrij rap).

Register_shutdown_function kende ik nog niet, ik ga daar ook eens naar kijken :)

[ Voor 8% gewijzigd door ixi op 23-02-2009 16:30 ]


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Ik zou inderdaad gewoon een scheduled-script pakken die gewoon om de 5 minuten een queue van openstaande mails afhandelt.

Jouw php-script gooit dan alleen iets in de queue. Heeft de klant dan een snelle mailserver dan kan je het scheduled mail-script gelijk aanroepen na je eigen script. Heeft de klant extreem weinig bandbreedte dan kan je je script schedulen om alleen tussen 17:00 en 08:00 te werken.

Geeft imho de meeste flexibiliteit om aan de klant de keuze te laten wanneer wat verstuurd wordt. Ik ga er vanuit dat de meeste klanten wel weten hoe een scheduler werkt op hun eigen OS.
En dit zijn echt klantspecifieke problemen laat dat dan ook zoveel mogelijk door de klant oplossen.

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Gomez12 schreef op maandag 23 februari 2009 @ 19:35:
Ik zou inderdaad gewoon een scheduled-script pakken die gewoon om de 5 minuten een queue van openstaande mails afhandelt.

Jouw php-script gooit dan alleen iets in de queue. Heeft de klant dan een snelle mailserver dan kan je het scheduled mail-script gelijk aanroepen na je eigen script. Heeft de klant extreem weinig bandbreedte dan kan je je script schedulen om alleen tussen 17:00 en 08:00 te werken.

Geeft imho de meeste flexibiliteit om aan de klant de keuze te laten wanneer wat verstuurd wordt. Ik ga er vanuit dat de meeste klanten wel weten hoe een scheduler werkt op hun eigen OS.
En dit zijn echt klantspecifieke problemen laat dat dan ook zoveel mogelijk door de klant oplossen.
Ik weet niet met hoeveel klanten jij al te maken hebt gehad, maar dat soort dingen kun je meestal echt niet verwachten van een klant :D. Daarnaast slaat "klantspecifieke problemen moet de klant zelf oplossen" natuurlijk ook als een tang op een varken. De klant vraagt jou om een applicatie te maken, maar alle problemen die daarbij optreden moet de klant zelf maar oplossen?

Als er klant-specifieke problemen zijn, dan moet dat in de configuratie van de applicatie worden opgevangen. Dus niet laten oplossen door de klant, maar een oplossing bieden die de klant zelf naar wens kan configureren door wat instellingen aan te passen. Iets als "elke x minuten mailen" of "alleen mailen tussen 17:00 en 08:00" moet je gewoon kunnen instellen. Daar moet de klant zelf niets ander voor hoeven doen.

Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 21:01
McKaamos schreef op maandag 23 februari 2009 @ 14:24:
Mocht je toch met een lokale SMTP server gaan werken, dan kan je overwegen om hMailserver te gebruiken. Gratis en doet simpelweg relaying naar een andere server.
Als je een 'wachtwoord vergeten'-mailtje verstuurd is het wat lame om je gebruiker minuten te laten wachten op het mailtje... Het hangt er dus een beetje vanaf wat voor soort mailtje het is.

Als je toch al een database server en een webserver meelevert lijkt het me een kleine moeite ook een smtp-server mee te leveren. Daarmee zijn je problemen opgelost. Dan hoef je bij installatie alleen maar een doel-smtp-server op te geven, in je applicatie kun je altijd mailen naar localhost en hoef je je om het versturen niet druk te maken.

[ Voor 8% gewijzigd door Kalentum op 24-02-2009 09:05 ]


Acties:
  • 0 Henk 'm!

  • Skidmarks
  • Registratie: Februari 2001
  • Laatst online: 19-09 15:42
T-MOB schreef op maandag 23 februari 2009 @ 15:40:
Het makkelijkste lijkt me om gewoon met behulp van register_shutdown_function() aan het eind van het script je mails te versturen.
Dit heb ik nu getest maar de browser blijft nog steeds wachten tot het mailtje echt verstuurd is. Ik heb een ob_flush() en ob_end_flush() gedaan wat er voor zorgt dat de volgende pagina al wel zichtbaar is maar de browser blijft daarna nog steeds wachten tot de php server de connectie verbreekt en dat gebeurt pas na het afhandelen van de e-mail. Dus deze oplossing lijkt niet te werken.

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Skidmarks schreef op dinsdag 24 februari 2009 @ 14:30:
[...]


Dit heb ik nu getest maar de browser blijft nog steeds wachten tot het mailtje echt verstuurd is. Ik heb een ob_flush() en ob_end_flush() gedaan wat er voor zorgt dat de volgende pagina al wel zichtbaar is maar de browser blijft daarna nog steeds wachten tot de php server de connectie verbreekt en dat gebeurt pas na het afhandelen van de e-mail. Dus deze oplossing lijkt niet te werken.
Volgens mij staat dat ook in de documentatie van die functie:
Since PHP 4.1, the shutdown functions are called as the part of the request so that it's possible to send the output from them.
De shutdown functie is een onderdeel van het request geworden en het request zal dus ook wachten op het afronden van de shutdown functie.
Pagina: 1