Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016
-
27 avril 2011 à 19:40
katsankat
Messages postés571Date d'inscriptionvendredi 30 décembre 2005StatutMembreDernière intervention12 juillet 2012
-
27 mai 2012 à 09:06
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
katsankat
Messages postés571Date d'inscriptionvendredi 30 décembre 2005StatutMembreDernière intervention12 juillet 20123 27 mai 2012 à 09:06
en PHP il n'y a pas de threads mais apparemment il existe un autre modèle d'I/O : select() qui permet de gérer plusieurs sockets sans bloquer sur read ou write. Select() est un appel système très puissant permettant le multiplexages d'entrées/sorties asynchrones. En C c'est un régal.
Morphinof
Messages postés255Date d'inscriptionvendredi 20 avril 2007StatutMembreDernière intervention 9 août 20134 2 mai 2011 à 19:26
Oui seulement il n'y a pas de gestion native des thread en PhP :(
Par contre on peu utiliser pcntl_fork puis créer une thread pool mais ca aurai rendu la source trop complexe, mon but c'est de laisser implémenter le comportement:)
Gigatrappeur
Messages postés226Date d'inscriptionlundi 6 mai 2013StatutMembreDernière intervention 3 juillet 20141 2 mai 2011 à 19:11
Code intéressant !
petite remarque :
la méthode loop de ton client : tu fais un appel récursif sur $this->loop
le problème est que lorsque tu fais un appel récursif, il empile sur le tas tes appels les un après les autres.
Et à un moment donné, ta mémoire sera pleine --> et crack !
il vaut mieux utiliser une boucle while...
public function loop()
{
while ($this->continue)
{
...
$this->listen();
...
}
}
autre remarque :
généralement, sur ce genre de code (qui existe plus en java), on utilise des threads.
Cordialement,
Gigatrappeur
Morphinof
Messages postés255Date d'inscriptionvendredi 20 avril 2007StatutMembreDernière intervention 9 août 20134 28 avril 2011 à 15:53
Ahh peu être que ton hébergeur bloque l'ouverture de on port alors non ?
Moi je teste en local alors forcement ca marche mais je suis pas sur que tu puisse ouvrir une socket serveur sur n'importe quel port chez un hébergeur classique enfin c'est une idée ^^
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 28 avril 2011 à 15:49
Je teste sur un hébergement, pas en local.
Donc pas de Cygwin pour moi.
Mais bon on va trouver ... je suis confiant ^^
Morphinof
Messages postés255Date d'inscriptionvendredi 20 avril 2007StatutMembreDernière intervention 9 août 20134 28 avril 2011 à 15:47
Normalement tout se ferme correctement soit par la fonction timeout soit en fermant le script, personnellement en utilisant Cygwin je n'ai pas eu ce genre de soucis alors je pense pas ^^
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 28 avril 2011 à 15:41
Du coup je peux plus relancer le serveur.
Peut être qu'on ne ferme pas la socket proprement et que le port reste utilisé ?
Morphinof
Messages postés255Date d'inscriptionvendredi 20 avril 2007StatutMembreDernière intervention 9 août 20134 28 avril 2011 à 15:40
Hum je viens juste de vérifier a priori si il n'arrive pas a lire ca génère un warning et on peu pas l'empêcher, pour éviter ca mets un @ devant socket_accept ca enlèvera ce warning et de toute façon ce qui nous intéresse c'est de tester l'état false, sinon ca viens pas de socket_set_nonblock que j'ai mit justement pour permettre des connections simultanées de plusieurs clients.
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 28 avril 2011 à 15:21
Pour info ->
En supprimant nonblock j'ai toujours le même warning (toutes les 5 secondes)
Morphinof
Messages postés255Date d'inscriptionvendredi 20 avril 2007StatutMembreDernière intervention 9 août 20134 28 avril 2011 à 15:14
Ah bizarre ca me fait pas ca chez moi, unable to accept incoming connection je dirait que soit ca viens du port que tu utilise soit ca viens peu être de ce bug : http://bugs.php.net/bug.php?id=29560 mais je suis pas sur a 100%, en tout cas au niveau de la structure c'est comme ca qu'il faut faire, tu peux essayer d'enlever le mode non bloquant des socket (socket_set_nonblock(self::$socket)) pour essayer de voir si ca change quelque chose.
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 28 avril 2011 à 14:54
/*
* Boucle infinie du serveur, attente des connections
*/
public function loop()
{
if(($client = socket_accept(self::$socket)) !== false)
{
echo 'New client '.$client.' has connected'.BR;
self::$clients[] = $client;
}
$this->listen();
ob_flush();
usleep(SERVER_LOOP_SLEEP);
if ($this->continue)
$this->loop();
}
J'ai une erreur avec cette ligne : if(($client = socket_accept(self::$socket)) !== false)
même lorsque le serveur tourne seul (personnes de connecté)
Je vois ça dans le fichier error_log :
socket_accept() [['function.socket-accept function.socket-accept]]: unable to accept incoming connection [11]
Morphinof
Messages postés255Date d'inscriptionvendredi 20 avril 2007StatutMembreDernière intervention 9 août 20134 28 avril 2011 à 14:29
Cette fonction réponds au client que si le client envoi un message comme suit : if (($datas = $this->read($client))) alors je reponds.
A priori ca devrai donc marcher, mais je n'ai pas pu tester avec plusieurs connections, est ce que le serveur te dit qu'il y a 2 connectés et si oui est ce que tes deux clients envoient bien un message au serveur ?
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 28 avril 2011 à 13:49
Autre précision :
Quand on connecte plusieurs clients, la fonction listen semble ne pas renvoyer les datas à tous les clients connectés.
(J'ai plein de choses à apprendre avec cette source ... elle est vraiment super)
Morphinof
Messages postés255Date d'inscriptionvendredi 20 avril 2007StatutMembreDernière intervention 9 août 20134 28 avril 2011 à 08:49
Hello !
Quand on lance le serveur celui ouvre une socket sur un port et écoutes toutes les connections client qui arrivent sur le dit port.
Le client lui ouvre une sockect qui se connecte via ce port au serveur.
Lorsqu'un client se connecte le serveur stocke ce client dans un tableau de client, le serveur envois régulièrement aussi un message "live" a sa liste pour retirer les clients déconnectes.
Voila ^^
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 27 avril 2011 à 19:40
Bonjour
Ca semble fonctionner ^^
C'est possible d'avoir plus d'infos ? sur le fonctionnement !
27 mai 2012 à 09:06
2 mai 2011 à 19:26
Par contre on peu utiliser pcntl_fork puis créer une thread pool mais ca aurai rendu la source trop complexe, mon but c'est de laisser implémenter le comportement:)
2 mai 2011 à 19:11
petite remarque :
la méthode loop de ton client : tu fais un appel récursif sur $this->loop
le problème est que lorsque tu fais un appel récursif, il empile sur le tas tes appels les un après les autres.
Et à un moment donné, ta mémoire sera pleine --> et crack !
il vaut mieux utiliser une boucle while...
public function loop()
{
while ($this->continue)
{
...
$this->listen();
...
}
}
autre remarque :
généralement, sur ce genre de code (qui existe plus en java), on utilise des threads.
Cordialement,
Gigatrappeur
28 avril 2011 à 15:53
Moi je teste en local alors forcement ca marche mais je suis pas sur que tu puisse ouvrir une socket serveur sur n'importe quel port chez un hébergeur classique enfin c'est une idée ^^
28 avril 2011 à 15:49
Donc pas de Cygwin pour moi.
Mais bon on va trouver ... je suis confiant ^^
28 avril 2011 à 15:47
28 avril 2011 à 15:41
Peut être qu'on ne ferme pas la socket proprement et que le port reste utilisé ?
28 avril 2011 à 15:40
28 avril 2011 à 15:21
En supprimant nonblock j'ai toujours le même warning (toutes les 5 secondes)
28 avril 2011 à 15:14
28 avril 2011 à 14:54
* Boucle infinie du serveur, attente des connections
*/
public function loop()
{
if(($client = socket_accept(self::$socket)) !== false)
{
echo 'New client '.$client.' has connected'.BR;
self::$clients[] = $client;
}
$this->listen();
ob_flush();
usleep(SERVER_LOOP_SLEEP);
if ($this->continue)
$this->loop();
}
J'ai une erreur avec cette ligne : if(($client = socket_accept(self::$socket)) !== false)
même lorsque le serveur tourne seul (personnes de connecté)
Je vois ça dans le fichier error_log :
socket_accept() [['function.socket-accept function.socket-accept]]: unable to accept incoming connection [11]
28 avril 2011 à 14:29
A priori ca devrai donc marcher, mais je n'ai pas pu tester avec plusieurs connections, est ce que le serveur te dit qu'il y a 2 connectés et si oui est ce que tes deux clients envoient bien un message au serveur ?
28 avril 2011 à 13:49
Quand on connecte plusieurs clients, la fonction listen semble ne pas renvoyer les datas à tous les clients connectés.
(J'ai plein de choses à apprendre avec cette source ... elle est vraiment super)
28 avril 2011 à 08:49
Quand on lance le serveur celui ouvre une socket sur un port et écoutes toutes les connections client qui arrivent sur le dit port.
Le client lui ouvre une sockect qui se connecte via ce port au serveur.
Lorsqu'un client se connecte le serveur stocke ce client dans un tableau de client, le serveur envois régulièrement aussi un message "live" a sa liste pour retirer les clients déconnectes.
Voila ^^
27 avril 2011 à 19:40
Ca semble fonctionner ^^
C'est possible d'avoir plus d'infos ? sur le fonctionnement !
Merci d'avance