[PHP] Ftp verbinding alive houden

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 18-08 18:12
Ik heb een script waarvoor ik een ftp verbinding lang open heb, rond 5 minuten.
Ik ben opzoek naar een manier om de ftp verbinding open te houden, maar een echt goede oplossing heb ik nog niet. Met een manier bedoel ik ftp commando's die je om de ongeveer 90 seconde geeft zodat de verbinding alive blijft.
Deze mogelijkheden heb ik al bekeken:

- ftp_pwd(), werkt snel maar php cashed het resultaat dus onbetrouwbaar
- ftp_nlist(), werkt om de verbinding alive te houden, maar langzaam
- ftp_rawlist(), nog langzamer dan ftp_nlist()
- ftp_raw(), hierbij krijg je geen resultaat terug

Acties:
  • 0 Henk 'm!

Verwijderd

Ik zou van Noop gebruik maken. Daar is het commando uiteindelijk ook voor bedoeld geweest, dat de connecties alive blijven (als ik smartFTP mag geloven).

Acties:
  • 0 Henk 'm!

  • Spockz
  • Registratie: Augustus 2003
  • Laatst online: 21-09 10:08

Spockz

Live and Let Live

PHP heeft geen functie die dat verzorgt. Je zult dus iets moeten doen als:
PHP:
1
ftp_raw($this->handle, "NOOP");


Ervanuit gaande dat je een FTPConnectieObject hebt.

Denk er wel aan dat als je script eindigt al je openstaande verbindingen ook worden afgesloten.

Edit: En je kunt testen of je NOOP hebt door te kijken of je 200 OK terugkrijgt als je het NOOP commando gebruikt hebt.

[ Voor 18% gewijzigd door Spockz op 26-08-2007 11:07 ]

C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Niet alle servers ondersteunen NOOP, omdat ze juist willen dat de verbinding time-out als er geen activiteit is. Mcht dat zo zijn kun je misschien zelf een functie-tje maken die een bestand van een paar byte put of get.

Acties:
  • 0 Henk 'm!

Verwijderd

afgezien van een eigen client schrijven op basis van pfsockopen() lijkt ftp_* nog cURL weinig opties te hebben om persistent te zijn.

het probleem is dat zodra je script eindigt, alle resources dus ook tcp connecties worden verwijderd. pfsockopen lost dit op door de connectie resource niet aan het script maar aan de webserver te geven. de volgende keer dat php het script parsed kijkt deze of er al een resource is. zo ja dan pakt deze de verbinding weer terug. zo niet dan wordt er een nieuwe gemaakt.

het gevaar zit er in dat dus alle php scripts deze resource delen. de resource is immers van de webserver. de script's lenen hem alleen even. zolang de webserver leeft en de resource niet aan 1 of beide kanten is gesloten zal de connectie alive blijven. je zult hem expliciteit moeten sluiten. gelukkig zijn veel server's aan de andere kant van de lijn ook niet gek en sluiten de connectie als er niks gebeurd voor een bepaalde tijd. ook php heeft een beveiliging om vergeten resources te sluiten.

een andere punt is, ftp hoeft niet persistent te zijn. je kunt de laatste directory of een file transfer qeue ook perfect client-side doen. je open gewoon een nieuwe connectie, switched meteen naar de goede directory of begint gewoon de tranfser nadat je bent ingelogd. ftp is command-driven in de zin dat je gewoon connect, inlogt en je commando's afvuurt en afhandeld. daar is geen persistente connectie voor nodig alhoewel het voor performance wel handig zou zijn natuurlijk. vooral grote files kunnen een probleem zijn dus vergeet niet de timelimiet en geheugenlimiet bij-te-stellen.

[ Voor 5% gewijzigd door Verwijderd op 26-08-2007 13:19 ]


Acties:
  • 0 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

^^ PHP hoeft niet perse op een webserver te draaien ;)

Sommige servers negeren NOOP of ondersteunen het niet. Filezilla lost dat op door de hele tijd TYPE A , TYPE I en nog een aantal commando's willekeurig te versturen.

Acties:
  • 0 Henk 'm!

Verwijderd

Radiant schreef op zondag 26 augustus 2007 @ 13:50:
^^ PHP hoeft niet perse op een webserver te draaien ;)

Sommige servers negeren NOOP of ondersteunen het niet. Filezilla lost dat op door de hele tijd TYPE A , TYPE I en nog een aantal commando's willekeurig te versturen.
weet ik, als de TS het van de CLI draaie had hij dit probleem ook waarschijnlijk niet dus ging er even van uit dit een typisch resource probleem is dat veel website's hebben. gewoon van de CLI starten zou idiaal zijn omdat je dan gewoon net zoals Filezilla of WS_FTP een echte client hebt een niet een serie van client's.

WS_FTP8 lost het trouwens op door gewoon een nieuwe connectie te maken en ik geloof dat dat wel zo server vriendelijk is omdat servers gewoon een x aantal resources per connectie aanmaken en zodra een connectie inactief blijkt deze resources ook gewoon weer worden verwijderd. door commando's naar de server te gaan sturen alleen maar om de connectie niet inactief te laten gaan is de server onnodig belasten met het verwerken van informatie. en dat terwijl FTP helemaal geen constant actieve connectie vereist. het is zelf een resource verspilling aan beide kanten om een connectie actief te houden en er eigenlijk niks mee doen. sluiten en een nieuwe maken wanneer dat nodig is is dan een veel nettere manier. ik kan zo geen reden bedenken waarom je een connectie niet inactief wilt laten gaan. iemand een idee waarom je dat zou willen?

Acties:
  • 0 Henk 'm!

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 18-08 18:12
Het sturen van NOOB, TYPE A , TYPE I gaat met ftp_raw() en deze functie geeft niet het resultaat terug, dus weet je niet zeker of je de verbinding wel echt alive houd. Ook kan je hiermee niet checken of de verbinding nog alive is. Of zie ik dat verkeerd?

Ik gebruik de ftp functies van PHP om de verbinding te maken. Zoals iemand hierboven al zei kan het ook met een socket, is een socket verbinding stabielen dan met de ftp functies? Overigens heb ik geen persistent verbinding nodig, als het script klaar is mag de verbinding sluiten.

Over de reden waarom ik hem wil openhouden: een ftp_nlist() commando kost 0.2 seconde, terwijl verbinding maken 10 seconde duurt. Als je 30x verbinding moet maken is dat 5 minuten.
Een tweede reden: het commando dient ook om te kijken of de verbinding dood is, om daarna weer een nieuwe verbinding te maken.

Acties:
  • 0 Henk 'm!

Verwijderd

een socket is 'lijn' waarover bytes van het ene IP address naar het andere gaan en vica-versa.
FTP is een protocol wat zegt welke bytes je wanneer mag sturen en wat het antwoord moet zijn.
de ftp_* functies implementeeren dit protocol zodat jij je niet druk hoeft te maken over wanneer je welke bytes moet sturen en hoe jij de antwoorden vande FTP server moet interpeteeren. de ftp_* functies gebruiken intern gewoon een socket zoals elke netwerk applicatie dat doet.

met pfsockopen() kun je dus een nivo lager gaan zitten. maar dan moet je dus met het FTP protocol op het byte-nivo werken en niet op het functie nivo zoals met de ftp_* functies. ftp_connect creert een socket de resource die wordt terug gegeven is eigenlijk een resource-id. een manier waarop jij aan php kunt zeggen welke resource je bedoelt. de werkelijke socket blijft achter de schermen. als je dan ftp_nlist() aanroept stuur deze functies de commando's naar de server een leest het antwoord van de server weer terug en geeft de interpertatie weer aan jouw als een array. in de meeste ftp clients kun je in een console of een log window zien wat er wordt verstuurt. ftp_nlist() doet dit dus voor jouw zodat jij dit met een fwrite() etc niet hoeft te doen. gelukkig is ftp niet zo heel complex. elk commando staat op zijn eigen regel en de antwoorden van de server beginnen altijd met een nummer gevolgd door wat informatie zoals '200 command ok' wat aangeeft dat je laaste command successvol was.

als php eindigt wat dus na elke keer dat de webpagina is geladen automatisch gebeurt worden alle resources die php heeft vernietigd. ook de socket die achter de schermen bij de ftp_* functies aan het werk is. elke keer dat jij je pagina laadt moet er dus weer een nieuw socket worden gemaakt en het protocol weer opnieuw worden uitgevoerd. pfsockopen() lost dit op door de resource aan de webserver te geven i.p.v het zelf te houden. zodra php eindigt bestaat de socket dus nog en waneer php weer opstart kan het deze weer terug 'lenen'. maar de ftp_* functies zoals ftp_connect() en dus ook ftp_nlist() gebruiken dit niet.

dus eigenlijk heb je de keuze: of je maakt je eigen functies opgebouwed rond pfsockopen() wat betekent dat je op het byte-nivo moet gaan lezen en schrijven. of je vindt iemand die een ftp implementatie heeft gemaakt die wel pfsockopen() gebruikt want die die standaard met PHP komt doet dat dus niet maar er zijn open-source project die zoiets vast al eens hebben gedaan. of je probeert het aantal connect terug te brengen door bijvoorbeeld te cachen. dit kan in een database waar je bijvoorbeeld het resultaat van de recentste ftp_nlist() bewaart.

je zou bijvoorbeeld een functie kunnen maken die ftp_nlist_cached() heet en naast de ftp-resource en directory ook een mysql-resource ontvangt en tijds-limiet. de functie kijkt dan eerst in de database of er een resultaat bestaat wat bij die directory hoort en vergelijkt dan de tijd dat dat resultaat is ingevoerd met de huidige tijd en als dat meer is dan de tijds-limiet dan pas connect deze naar de ftp-server. haalt een resultaat op en voegt deze in de database met de huidige timestamp. door een tijds-limiet van 0 op te geven kun je dus een resultaat forceeren om zich te verversen. als je daarna een tijds-limiet van bijvoorbeeld 90 opgeeft wordt er slechts 1x per 90 seconden een up-to-date resultaat opgehaald per directory.

dit kan het aantal connects naar de server verlagen en is vrij simpel te implementeeren met mysql_query(), time(), en serialize() om de array die ftp_nlist() terug geeft om te zetten naar een string. als je het resultaat dan uit de database leest i.p.v de ftp server hoef je het veld te lezen en dan unserialize() te doen om de array weer terug te krijgen. deze geeft je dan uiteindelijk terug en de aanroepende functie weet niet eens of je het nou uit de database of van de ftp-server hebt gehaald.
Pagina: 1