Moteur PHP5 gestion de socket.

Moteur PHP5 gestion de socket. - PHP - Programmation

Marsh Posté le 11-10-2007 à 16:35:41    

Bonjour j utilise le moteur php pour créer un petit programme pouvant recevoir des socket exterieur,
jusqu a la tout va bien, il me renvoi bien la donnée sur le client l'envoyant;
 
Mon besoin étant de renvoyer toutes les informations issus de n'importe quels clients vers tout les utilisateurs connectés.
 
exemple 3 CX en simultanées,  
un d'une des connexions envoie "1", les trois connection devront recevoir le "1" envoyé par la connection.
 
Merci de de votre aide
 

Code :
  1. <?php
  2. // On se replace dans le répertoire où est stocké le script
  3. chdir(dirname(__FILE__));
  4. // On initialise un tableau contenant la liste des sockets à surveiller
  5. $watchSockets = array();
  6. // On initialise un tableau contenant les sockets clients
  7. $clients = array();
  8. // On initlialise un tableau contenant les sockets threads
  9. $threads = array();
  10. // On initialise un tableau contenant les données temporaires à envoyer à un nouveau thread
  11. $threadsTemp = array();
  12. // -----------------------------------
  13. // On crée la socket "externe"
  14. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  15. // On la lie, ici sur le port 10000
  16. socket_bind($socket, '0.0.0.0', 10000);
  17. // On la fait écouter
  18. socket_listen($socket, 5);
  19. // On ajoute la socket du serveur dans la liste des sockets à surveiller (pour les nouvelles connexions)
  20. $watchSockets[] = $socket;
  21. // -----------------------------------
  22. // On crée la socket "interne" pour la communication avec les threads
  23. $threadSocket = socket_create(AF_UNIX, SOCK_STREAM, NULL);
  24. // On la lie, ici sur la socket /tmp/monserveur.socket
  25. socket_bind($threadSocket, '/tmp/monserveur.socket');
  26. // On la fait écouter
  27. socket_listen($threadSocket);
  28. // On ajoute la socket du serveur interne dans la liste des sockets à surveiller (pour les nouveaux threads)
  29. $watchSockets[] = $threadSocket;
  30. // Boucle infinie
  31. while (TRUE)
  32. {
  33. // Surveillance des sockets en attente de données à lire
  34. // Si pas de données à lire : on relance la boucle
  35. $toRead = $watchSockets; // Parce que socket_select() modifie le tableau passé en paramètre et que l'on veut garder notre variable $watchSockets
  36. if (!@socket_select($toRead, $write = NULL, $except = NULL, 0)) continue;
  37. // Il y a des données à lire
  38. // Le socket d'écoute éxtérieur a-t-il reçu des données ?
  39. if (in_array($socket, $toRead))
  40. {
  41.  // Oui : il s'agit d'une nouvelle connexion
  42.  // Acceptons-la
  43.  $newConnection = socket_accept($socket);
  44.  // Ajoutons-la à la liste des clients
  45.  $clients[] = $newConnection;
  46.  // Ajoutons-la à la liste des sockets à surveiller
  47.  $watchSockets[] = $newConnection;
  48.  // Créons un thread qui s'occupera de ce client
  49.  // ATTENTION : vérifiez que le chemin vers PHP est correct
  50.  // On passe en outre l'ID du client dans le tableau de correspondance pour que l'on puisse identifier le thread lors de sa connexion plus tard
  51.  // Les caractères étranges de la fin de la commande assurent l'éxécution en arrière-plan
  52.  exec('/usr/local/bin/php thread.php '.strval(count($clients) - 1).' 2>/dev/null >&- <&- >/dev/null &');
  53.  // Supprimons la socket d'écoute de la liste des sockets à lire
  54.  // (pour éviter d'interférer avec la suite)
  55.  $key = array_search($socket, $toRead);
  56.  unset($toRead[$key]);
  57. }
  58. // Le socket d'écoute interne (threads) a-t-il reçu des données ?
  59. if (in_array($threadSocket, $toRead))
  60. {
  61.  // Oui : un thread est prêt et tente de se connecter
  62.  // Acceptons la connexion
  63.  $newConnection = socket_accept($threadSocket);
  64.  // Récupérons l'ID du thread
  65.  $data = socket_read($newConnection, 4, PHP_BINARY_READ);
  66.  var_dump($data);
  67.  $id = unpack('lid', $data); $id = $id['id'];
  68.  // NOTE : cette méthode n'est en théorie pas optimale au niveau perfs, socket_read() pouvant bloquer un court instant
  69.  // Pour éviter cela, il faut récupérer l'ID en surveillant le socket (en attendant il faut placer le socket client dans une pile temporaire)
  70.  // Cette dernière variante n'est pas utilisée ici pour ne pas compliquer le code mais ne présente pas de difficulté majeure
  71.  // Ajoutons-la à la liste des threads
  72.  $threads[$id] = $newConnection;
  73.  // Ajoutons-la à la liste des sockets à surveiller
  74.  $watchSockets[] = $newConnection;
  75.  // A-t-on des données à lui passer, qui ont été stockées temporairement ?
  76.  if (strlen($threadsTemp[$id]))
  77.  {
  78.   // Oui : passons les
  79.   for ($writed = 0; $writed < strlen($threadsTemp[$id]); $writed += socket_write($newConnection, substr($threadsTemp[$id], $writed)));
  80.   unset($threadsTemp[$id]);
  81.  }
  82.  // Supprimons la socket d'écoute de la liste des sockets à lire
  83.  // (pour éviter d'interférer avec la suite)
  84.  $key = array_search($threadSocket, $toRead);
  85.  unset($toRead[$key]);
  86. }
  87. // Parcourons la liste des sockets clients et threads ayant reçu des données
  88. foreach ($toRead as $oneSocket)
  89. {
  90.  if (in_array($oneSocket, $clients))
  91.  {
  92.   // Il s'agit d'un client externe
  93.   // Client >> SCRIPT >> thread
  94.   // Obtenons l'ID client correspondant
  95.   $key = array_search($oneSocket, $clients);
  96.   // Lisons la socket sur disons... 1024 octets
  97.   // (un choix purement arbitraire, peut néanmoins influer sur les performances, pensez à faire des tests)
  98.   $data = socket_read($oneSocket, 1024);
  99.   if (!strlen($data))
  100.   {
  101.    // La connexion avec le client s'est interrompue
  102.    // Fermons le socket client
  103.    socket_close($oneSocket);
  104.    // Fermons le socket thread
  105.    @socket_close($threads[$key]);
  106.    // On coupe tout
  107.    unset($clients[$key]);
  108.    unset($threads[$key]);
  109.    $watchKey = array_search($oneSocket, $watchSockets);
  110.    unset($watchSockets[$watchKey]);
  111.   }
  112.   else
  113.   {
  114.    // Le thread associé est-il prêt et connecté ?
  115.    if (isset($threads[$key]))
  116.    {
  117.     // Oui : passons lui les données
  118.     for ($writed = 0; $writed < strlen($data); $writed += socket_write($threads[$key], substr($data, $writed)));
  119.    }
  120.    else
  121.    {
  122.     // Non : on les stocke temporairement
  123.     $threadsTemp[$key] .= $data;
  124.    }
  125.   }
  126.  }
  127.  elseif (in_array($oneSocket, $threads))
  128.  {
  129.   // Il s'agit d'un thread
  130.   // Thread >> SCRIPT >> client
  131.   // Obtenons l'ID du thread correspondant
  132.   $key = array_search($oneSocket, $threads);
  133.   // Lisons la socket sur disons... 1024 octets
  134.   // (un choix purement arbitraire, peut néanmoins influer sur les performances, pensez à faire des tests)
  135.   $data = socket_read($oneSocket, 1024);
  136.   if (!strlen($data))
  137.   {
  138.    // La connexion avec le thread s'est interrompue (autrement dit, il veut fermer la connexion avec le client)
  139.    // Fermons le socket client
  140.    socket_close($clients[$key]);
  141.    // Fermons le socket thread
  142.    socket_close($oneSocket);
  143.    // On coupe tout
  144.    unset($clients[$key]);
  145.    unset($threads[$key]);
  146.    $watchKey = array_search($oneSocket, $watchSockets);
  147.    unset($watchSockets[$watchKey]);
  148.   }
  149.   else
  150.   {
  151.    // Passons les données au client correspondant
  152.    for ($writed = 0; $writed < strlen($data); $writed += socket_write($clients[$key], substr($data, $writed)));
  153.   }
  154.  }
  155. }
  156. }
  157. ?>

Reply

Marsh Posté le 11-10-2007 à 16:35:41   

Reply

Marsh Posté le 11-10-2007 à 20:03:24    

Quelle est la question ?

Reply

Marsh Posté le 15-10-2007 à 09:40:17    

Olivier51 a écrit :

Quelle est la question ?


*je souhaite avoir un perroquet tout ce qui recu par un socket et renvoyé sur tout les sockets connectés

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed