[PHP/Socket]Oneidig luisteren naar een poort

Pagina: 1
Acties:
  • 473 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Jochemmol
  • Registratie: Augustus 2004
  • Laatst online: 07-05-2014
Ik heb een programma waarmee ik de mogelijkheig wil bieden dat een gebruiker een bericht kan typen en alle andere gebruikers dit bericht in hun scherm krijgen.

Ik kan dit op twee manieren doen:
- AJAX laten pollen
- Socket luisteren

Ik koos voor Socket omdat met AJAX blijft hij pollen met een interval. Dat is niet handig in dit geval. Pollen is een process dat bezig blijft. Dat wil ik niet.

Ik heb het volgende gemaakt.
PHP:
1
2
3
4
5
6
$socket = stream_socket_server('tcp://127.0.0.1:1234', $errno, $errstr);

$conn = @stream_socket_accept($socket);
            
$message= fread($conn, 1024);
echo  $message.'<BR>';

Dit werkt perfect. Als je maar 1 bericht stuurt. Om dat na 1x lezen stopt hij met lezen. Om hem weer aan de praat te krijgen moet ik de pagina herladen. Dat is niet handig.

Nu kan ik wel een while loop doen.
PHP:
1
2
3
4
5
while($conn = @stream_socket_accept($socket))
{
$message= fread($conn, 1024);
echo  $message.'<BR>';
}

Dit werkt. Nu gebruikt hij de default timeout. 60s. Ik kan een eigen timeout meegeven. Dit kan ik bv op 3600 zetten of langer.

Het nadeel is van een while loop dat de pagina blijft laden. Ik kom niet tot een oplossing voor het oneindig luisteren zonder dat de pagina blijft laden

Kan dat geen kwaad? Is dit de juiste oplossing? Wat is jullie mening/ervaring _/-\o_

[ Voor 6% gewijzigd door Jochemmol op 07-01-2008 13:46 . Reden: Oneindig laden ]

Jochemmol


Acties:
  • 0 Henk 'm!

  • rrrandy
  • Registratie: Juli 2005
  • Laatst online: 27-06 13:00
Zoek met google eens naar 'http push'. Er zijn genoeg mensen die met dit probleem hebben geworsteld / nog steeds mee worstelen.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Jochemmol schreef op maandag 07 januari 2008 @ 13:41:
Het nadeel is van een while loop dat de pagina blijft laden. Ik kom niet tot een oplossing voor het oneindig luisteren zonder dat de pagina blijft laden
Php draait op de server, de webbrowser draait op de client. Zolang het phpscript draait en dus nog niet klaar is met alle gegevens terug te sturen naar de client zal de verbinding dus open blijven dus blijft de pagina laden. De pagina stopt met laden zodra de verbinding verbroken wordt en dat gebeurt pas wanneer php klaar is.

Op deze manier oneindig blijven luisteren zonder paginaladen is dus geoon niet mogelijk. Dat je daarvoor geen oplossing vindt is dan ook logisch.

Bedenk verder dat het http protocol (en ook php) eigenlijk helemaal niet bedoeld is om open te blijven/te blijven draaien.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Jochemmol
  • Registratie: Augustus 2004
  • Laatst online: 07-05-2014
Dat is logisch.

Maar pollen is ook niet alles 8)7 Ik ga eens kijken of ik het anders kan doen.

Jochemmol


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Pollen is minder zwaar dan een connection open houden. Zorg gewoon dat je niet te vaak polled en dat de zo klein mogelijk zijn (bv een leeg antwoord wanneer er niks veranderd is).

Wat zijn trouwens je bezwaren tegen pollen? Het openhouden van een socket is ook niet gratis. Zeker in een webomgeving. Dezen zijn over het algemeen eerder geoptimaliseerd voor vele kort openstaande verbindingen.

[ Voor 37% gewijzigd door Janoz op 07-01-2008 15:05 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Een connectie open houden per bezoeker is simpelweg geen optie omdat je daarmee vrij gemakkelijk een DOS mogelijk maakt. Ik hoeft alleen maar 10 minuten mij F5 toets ingedrukt te houden en je webserver is down (alle source porten zijn dan bezet en dus zal je webserver geen connecties meer accepteren).

Wat betreft het pollen. De output is waarschijnlijk voor elke bezoeker hetzelfde, dus kun je een algemene response bijhouden. Response 1-op-1 wegschrijven naar een div (met overflow enabled). Op de server hoef je dan slechts per 15 seconde je database te checken.

Een andere oplossing dan pollen is een iframe naar een dynamisch aangemaakt bestand. Elke 15 seconden zorg je dat jouw website een chat.html aanmaakt met een meta refresh naar zichzelf. Dat werkt ook in browsers zonder javascript support.

Zelf ben geen voorstander van frames dus zou ik voor de eerste methode kiezen (pollen via ajax)

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Ik zit hier ook een beetje mee. Ik heb een AJAX chatbox gemaakt, waarbij de gebruiker elke halve seconden om nieuwe berichten vraagt. Dat heet pollen, als ik het goed begrijp.

Dat werkt prima maar het vergt per gebruiker een mysql connectie, een (eenvoudige) mysql query, en het versturen van een paar honderd bytes informatie (indien nieuwe berichten), en dat dus tweemaal per seconde. Bij enkele tientallen gebruikers loopt dat waarschijnlijk uit de klauwen.

Volgens mij gebruiken 'grote' sites over het algemeen een Java applet voor dit soort dingen?

edit: die http push ziet er veelbelovend uit, maar lijkt mij toch een verkapte manier van polling omdat ik meteen iets lees over setInterval. Na de tentamenweken zal ik er eens beter naar kijken :|

[ Voor 15% gewijzigd door Bozozo op 07-01-2008 16:21 ]

TabCinema : NiftySplit


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Java kan overweg met Comet (buzzword van http push zegmaar) maar Python bijv ook (het Twisted framework wordt vaak genoemd als je zoekt op Comet en Python). PHP is hier echt niet geschikt voor zoals Janoz al goed heeft beschreven. Overigens is 2 keer per seconde updaten best wel veel imo.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Bozozo schreef op maandag 07 januari 2008 @ 16:13:
Ik zit hier ook een beetje mee. Ik heb een AJAX chatbox gemaakt, waarbij de gebruiker elke halve seconden om nieuwe berichten vraagt. Dat heet pollen, als ik het goed begrijp.

Dat werkt prima maar het vergt per gebruiker een mysql connectie, een (eenvoudige) mysql query, en het versturen van een paar honderd bytes informatie (indien nieuwe berichten), en dat dus tweemaal per seconde. Bij enkele tientallen gebruikers loopt dat waarschijnlijk uit de klauwen.

Volgens mij gebruiken 'grote' sites over het algemeen een Java applet voor dit soort dingen?

edit: die http push ziet er veelbelovend uit, maar lijkt mij toch een verkapte manier van polling omdat ik meteen iets lees over setInterval. Na de tentamenweken zal ik er eens beter naar kijken :|
Dan zoud ge waarschijnlijk eens moeten kijken naar de mysql_p functies, die zijn persistent, dus die blijven openstaan tot het einde van de sessie

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • djiwie
  • Registratie: Februari 2002
  • Laatst online: 17-09 16:35

djiwie

Wie?

mysql_p functies hebben betrekking op de verbinding met de database server, niet op de verbinding met de client.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
Of je gebruikt memcache, je gooit een array met bijvoorbeeld de laatste 15 regels in het werkgeheugen van je server, je laat de client een request sturen met het laatste ID wat'ie heeft en vervolgens stuur je alle array keys met een ID groter dan dat terug. Zit toevallig sinds een paar dagen er wat mee te spelen (zie ook m'n blog) en tot nu toe bevalt het super :)

Let er trouwens wel op dat als je zoiets doet sommige clients (ie, IE) geheugen soms niet goed vrijgeven met als gevolg dat een simpele chatfunctie na een paar uur honderden megabytes browsergeheugen in beslag neemt. Kwam dit tegen toen ik met Fai zat te testen, nu is dat slechts een testprojectje waarbij het me weinig kon interesseren maar als je het wat serieuzer op wilt zetten kan het geen kwaad goed te letten op memory-leaks ;)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Waarom elke 500 ms opnieuw pollen? De gebruikes ervaring is echt niet zoveel anders als je elke 5 seconden gaat pollen. Realtime is 'slechts' een definitie. Onze html (support) chat ververst zelfs elke 15 seconden. Dat werkt al bijna 2 jaar op deze manier. Nog nooit hebben wij een klacht gekregen dat de chat traag was. Daarbij zorgt de poll bij ons nooit zelf voor de database aktie.

Het is juist de invoer van een gebruiker welke de database akties starten. Een gebruiker voert zijn tekst in en verstuur deze vervolgens. Vervolgens wordt direct daar achteraan een select op de database gedaan om alle teksten als een html bestand weg te schrijven onder het chatid. De poll zorgt er alleen voor dat {chatid}.html opnieuw wordt ingeladen. Ofwel een push cache systeem.

Het chat systeem is hiermee geen super zware load voor onze webserver (database).

(ps. Voordat wij gebruik maakte van ajax werd deze techniek ook al gebruikt, alleen werd de html toen in een iframe geladen waarbij het ingeladen html een meta refresh tag bevatten waardoor elke 15 seconden alsnog de pagina werd ververst).

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Poll interval is geheel afhankelijk van de toepassing en er is eigenlijk weinig zinnigs over te zeggen zonder de daadwerkelijke toepassing te kennen.

Een chat kan genoeg hebben aan 15 seconden, maar het zou in een druk kanaal best kunnen zijn dat gebruikers het wel als storend gaan ervaren. Voor beurs applicaties hebben ze het liefst een zo klein mogelijke interval terwijl het bij een lijstje met nieuwsfeitjes misschien wel helemaal niet opvalt wanneer het maar eens in de 5 minuten ververst wordt.

Polltijden zijn gewoon geheel afhankelijk van de toepassing en onderdeel van de functionele specificaties. Vanaf hier is het dan ook voor ons onmogelijk om aan te geven wat de juiste interval tijd is omdat we daarvoor te weinig over de daadwerkelijke toepassing weten.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

De TS had het over een applicatie waarbij een bezoeker een bericht kan typen en andere dat krijgen te zien. Dat vind ik een zeer accurate beschrijving van een chat applicatie.

Omdat bezoekers dus zelf voor de berichtenzorgen, is het dus zeker niet nodig om elke 500 ms te pollen. Vandaar mijn voorstel of elke 5 of zelfs 15 seconden te pollen.

Aangezien de berichten in een database wordt bijgehouden is het ook niet erg lastig om de gemiddelde interval tussen de berichten te berekenen. Berichten met een interval hoger dan 120 seconden kun je het beste buiten de berekening houden. Dan heb je dus de minimale ververs interval. Vermeningvuldig de gemiddelde interval met 4 en dan heb je een betrouwbare interval om te pollen.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 15:19

voodooless

Sound is no voodoo!

Naast dat het nogal duur is om verbindingen open te houden heb je nog problemen dat iedere browser de afhandeling weer anders doet. Sommigen geven pas data weer nadat je meerdere KB's hebt gestuurd. Ga je dan ook nog Ajaxen dan zul je erachter komen dat niet alle browsers content streamen via Ajax zullen ondersteunen (readyState=3). Kortom: 't suckt ;)

De pol interval kun je natuurlijk enigszins regelen aan de hand van de interval waarmee de berichten binnenkomen. Zo kun je een beetje voorstellen hoe snel je moet pollen en je polling interval hierop dynamisch aanpassen :) Dat werkt natuurlijk pas achteraf, maar zal wel de chatbeleving ten goede komen.

Do diamonds shine on the dark side of the moon :?


Acties:
  • 0 Henk 'm!

  • Toolskyn
  • Registratie: Mei 2004
  • Laatst online: 22-06 11:01

Toolskyn

€ 500,-

[misbruikmodus]

Om heel even terug te komen op de topicstart, in principe kun je een script oneindig laten draaien met dit soort code, en de functies ignore_user_abort en set_time_limit, bijvoorbeeld op deze manier:
PHP:
1
2
3
4
5
6
7
8
<?php
set_time_limit(0);
ignore_user_abort(true);

while(iets) {
    doeIets();
}
?>


Alleen dit soort dingen via de webserver doen vind ik persoonlijk niet netjes. Via de CLI zo'n soort script is eventueel nog te begrijpen, maar via de webbrowser een script oneindig laten draaien (ook nadat je op 'Stop' in je browser hebt gedrukt) is wat mij betreft gewoon misbruik maken van de functies die je hebt.

[/misbruikmodus]

gewooniets.nl


Acties:
  • 0 Henk 'm!

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Schopje:

http://www.chabotc.com/ge...ototype-first-public-demo

Dit is echt de moeite waard; de oplossing van mijn probleem en dat van de topicstarter, en sowieso een waanzinnig interessante toepassing!

TabCinema : NiftySplit


Acties:
  • 0 Henk 'm!

  • BlackWhizz
  • Registratie: September 2004
  • Laatst online: 08-12-2024
Had op internet gehoord dat er iets van Comet was ofzo, misschien kan je daar wat mee?

Acties:
  • 0 Henk 'm!

  • NielsNL
  • Registratie: Januari 2002
  • Laatst online: 08-09 20:14

NielsNL

DigiCow

Hier staat een simpele chat box met behulp van SAjax (Simple Ajax) Dit script is eenvoudig aan te passen, en voldoet mijns inziens aan je behoeften. Ik ben er in ieder geval zelf een tevreden gebruiker van.

M'n Oma is een site aan het haken.

Pagina: 1