IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Précision sur les sockets


Sujet :

Langage PHP

  1. #1
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut Précision sur les sockets
    Bonsoir,

    je me pose 2-3 question sur les sockets et pour cause : je ne les ai jamais utilisés !

    En fait je me demande si les sockets pourraient être utile dans le cadre d'un développement d'un jeu. Je précise mes attentes :

    Peuvent ils être utiles pour :

    1) Permettre aux utilisateurs d'avoir l'heure serveur en temps réel rafraichie toutes les x secondes (delta de 1s maxi par rapport à l'heure serveur) ?
    2) Permettre l'affichage instantané sur un navigateur d'un utilisateur d'un événement provoqué par un autre utilisateur (ex: attaque, envoi d'un message, ...) ?

    Mon but est de surtout éviter les requêtes cycliques toutes les x secondes afin de voir si un événement s'est produit et qui sont utiles dans 10% des cas.

    Je cherche donc à savoir si l'envoi d'une socket utilisateur peut se répercuter uniquement sur une autre socket utilisateur par le biais du serveur ?

    Merci de m'éclairer

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Points : 608
    Points
    608
    Par défaut
    Pas en PHP/HTTP standard :-)

    On peut le simuler avec du polling, mais ce n'est pas vraiment ce que tu cherches.

  3. #3
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Les sockets ne permettent pas d'envoyer aux clients connectés une information à fréquences d'intervales réguliers par exemple ?

    Pas possible qu'une socket n'interfère une autre socket particulière également en encodant le paquet de tel type qu'elle incorpore le destinataire ? Je dis n'importe quoi mais quelque chose du type :

    entete-userId-message
    XXXX-38-un message !
    Ainsi le serveur pourrait identifier la socket à appeler (38) et lui enverrais le message à lui uniquement ? Un peu à l'instar je dirais des chats privés je dirais.

    ...Possible ca ?

    EDIT: ...polling ?

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Points : 608
    Points
    608
    Par défaut
    Euh, je dirais "pas si tes clients sont des navigateurs web" ;-)

    polling : http://en.wikipedia.org/wiki/Polling...ter_science%29

  5. #5
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    ok merci pour les infos.

    Je vais continuer à me documenter pour choisir la meilleure option pour mon projet

  6. #6
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Afin d'effectuer mes tests sur les sockets, j'ai besoin de faire des echos dans une boucle infinie (principe du socket quoi).

    Je bosse avec wamp sous windows mais il semblerait que le flush() sous windows pose problème. j'ai testé 2-3 modifs dans php.ini mais je n'arrive toujours pas à afficher quelque chose dans une boucle infinie.

    Quelqu'un connait-il la solution sous windows ?

    Merci

  7. #7
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 255
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 255
    Points : 8 551
    Points
    8 551
    Billets dans le blog
    17
    Par défaut
    Tu passes bien par la console ?
    Pour moi pas de soucis de buffer de sortie.

  8. #8
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Je...non

    Je pensais que cela revenait au même via le browser.
    En testant en mode console, voici ce que j'obtiens :

    Call to undefined function socket_create...
    En lancant via firefox, pas d'erreur de script mais en mode console c'est comme si j'avais pas activé l'extension des sockets qui pourtant est activée (phpinfo me le confirme).

    J'ai rajouté ca en haut de mon serveur pour être sur :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if(function_exists('socket_create'))
    	echo "oui";
    else
    	echo "non";
     
    exit;

    via firefox -> oui
    via cmd -> non

    J'ai donc pensé que j'avais éventuellement plusieurs versions de php installées (notamment avec zend) mais mes variables d'env sont correctement positionnées et si je vais chercher php.exe en absolu, c'est pareil.

    D'où cela peut il venir ?

  9. #9
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 243
    Points
    20 243
    Par défaut
    En mode console , le .ini utilisé n'est généralement pas le même.
    Tu peux choisir le fichier de config avec php -c de mémoire.
    php -h te donneras toutes les infos.

  10. #10
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Exact je suis tombé sur ce post mais mon php.ini trouvé à la même config que l'autre au niveau des sockets.

    Je vais faire une recherche de tous les php.ini sur mon pc pour voir

  11. #11
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    J'ai dis n'importe quoi !

    En fait, j'ai bien, trouvé le bon fichier ini pour le mode console et l'extension était pas activé. C'est bon ca marche je vais pouvoir continuer mes tests sur les sockets merci

    EDIT: c'est bon ca flush bien

  12. #12
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 255
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 255
    Points : 8 551
    Points
    8 551
    Billets dans le blog
    17
    Par défaut
    Citation Envoyé par Madfrix Voir le message
    Je pensais que cela revenait au même via le browser.
    Ah non, chaque intermédiaire peut bufferiser : PHP, le serveur web, le navigateur.

    EDIT: c'est bon ca flush bien
    Cool

  13. #13
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Bonjour,

    je continue sur mes sockets mais je me heurte à un soucis...J'ai bien établi la connexion entre la socket client et le serveur. Maintenant, je cherche (pour tester) à envoyer toutes les 5 secondes par exemple à tous les clients connectés un message. Ce que je n'arrive à faire, c'est une boucle infinie avec un sleep inclu dedans. En soit, rien de compliqué sauf que mon serveur contient déjà une boucle imbriquée afin d'écouter les sockets entrantes...

    J'ai pas réussi à créer 2 boucles infinies dans une même classe et je pense pas que cela soit possible...J'ai donc cherché à instancier une nouvelle classe pour dispatcher l'événement en récupérant d'un tableau statique les sockets actives mais rien n'y fait je n'arrive pas à instancier 2 serveurs...

    Warning: socket_bind() [function.socket-bind]: unable to bind address [0]: Une seule utilisation de chaque adresse de socket (protocole/adresse réseau/port) est habituellement autorisée. in C:\wamp\www\socket\Serveur.php on line 22
    Ma seule solution reste pour le moment d'inclure le dispatch du message dans ma boucle infinie de lecture des sockets entrantes mais il n'apparaitra que si un client se connecte alors que je souhaite afficher un message à intervalles réguliers.

    Mes classes :

    Client :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    set_time_limit(0);
    ob_implicit_flush();
     
    class Client{
     
    	private $_socket;
    	private $_host;
    	private $_port;
     
    	public function __construct($host, $port){
    		$this->_host = $host;
    		$this->_port = $port;
    	}
     
    	public function send(){
    		$this->_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    		socket_connect($this->_socket, $this->_host, $this->_port);
            $paquet = 'un message';
            socket_write($this->_socket, $paquet, strlen($paquet));
     
    		while(true){
    			$input = socket_read($this->_socket, $this->_port);
    			echo $input . "\n";
    			//socket_close($this->_socket);
    		}
    	}
     
    }
     
    $client = new Client('127.0.0.1', 15182);
    $client->send();

    Serveur :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    set_time_limit(0);
    ob_implicit_flush();
     
     
    class Serveur{
     
    	private $_socket;
    	private $_host;
    	private $_port;
    	private $_paquet;
    	public static $_socketsClients = array();
     
    	public function __construct($host, $port){
    		$this->_host = $host;
    		$this->_port = $port;
    	}
     
    	public function launch(){
    		$this->_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    		socket_bind($this->_socket, $this->_host, $this->_port) or die('Port déjà utilisé\n');
    		socket_listen($this->_socket);
     
    		do{
    			$client = socket_accept($this->_socket);
    			self::$_socketsClients[] = $client;	
    		} while(true);
    	}	
     
    }
     
     
    $serveur = new Serveur('127.0.0.1', 15182);
    $serveur->launch();

    Dispatcher:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    set_time_limit(0);
    ob_implicit_flush();
     
    require_once 'Serveur.php';
     
    class Dispatcher{
     
    	public function __construct(){
    		$this->dispatch();
    	}
     
    	private function dispatch(){
     
    		while(true){
     
    			foreach(Serveur::$_socketsClients as $cle=>$socketClient){
    				$retour = date('H i s ');
    				if(!socket_write($socketClient, $retour, strlen($retour))){
    					unset($this->_socketsClients[$cle]);
    					echo 'Le client à l\'offset ' .$cle. ' s\'est déconnecté' . "\n";
    				}
    			}
     
    			sleep(5);
     
    		}
     
    	}
     
    }
     
    $dispatcher = new Dispatcher();

    Quelqu'un voit-il une solution à mon problème ?

    Merci

  14. #14
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 255
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 255
    Points : 8 551
    Points
    8 551
    Billets dans le blog
    17
    Par défaut
    J'ai bien établi la connexion entre la socket client et le serveur. Maintenant, je cherche (pour tester) à envoyer toutes les 5 secondes par exemple à tous les clients connectés un message
    sleep( ) n'est pas une bonne solution car le serveur reste en suspens.

    Ce que je ferais...

    client.php :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
     
    $client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) ;
    socket_connect($client, '127.0.0.1', 4567) ;
     
    while ( TRUE ) {
        $line = socket_read($client, 512) ;
        if ( $line ) {
            echo $line ;
        }
    }
    server.php :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?php
     
    $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) ;
    socket_bind($server, '127.0.0.1', 4567) ;
    socket_listen($server) ;
    socket_set_nonblock($server) ;
     
    $interval = 5 ; // Message à envoyer toutes les 5s
    $clients = array( ) ;
    $last = time( ) ;
     
    while ( TRUE ) {
        $client = @socket_accept($server) ;
        if ( $client !== FALSE ) {
            $clients[ ] = $client ;
            printf("[%s] Une nouvelle connexion\r\n", date('Y-m-d H:i:s')) ;
        }
        $now = time( ) ;
        if ( $now >= $last + $interval ) {
            foreach ( $clients as $client ) {
                socket_write($client, sprintf("[%s] La notif des %ds...\r\n",
                                              date('Y-m-d H:i:s', $now),
                                              $interval)) ;
            }
            $last = $now ;
        }
    }

  15. #15
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Bonsoir Séb et merci beaucoup

    Effectivement ta version marche comme je le désirerais

    Sauf qu'elle consomme 50% de mon UC

    c'est le socket_set_nonblock($server) (que je ne connaissais pas) qui fait monter en charge car le while se comporte comme une "vraie" boucle infinie et le script ne dort plus sur le socket_accept()...

    Je vais essayer de voir si je peux pas monter une version sans monter en charge

Discussions similaires

  1. [WinSock] Question sur les sockets (accept)
    Par Grey dans le forum MFC
    Réponses: 3
    Dernier message: 09/01/2006, 11h37
  2. Cours sur les sockets
    Par sorry60 dans le forum Réseau
    Réponses: 8
    Dernier message: 05/11/2005, 14h19
  3. Précisions sur les recordset DAO
    Par Igricheff dans le forum VBA Access
    Réponses: 2
    Dernier message: 18/01/2005, 17h16
  4. Précision sur les sauvegarde à chaud
    Par alxkid dans le forum Administration
    Réponses: 2
    Dernier message: 09/08/2004, 18h55
  5. Questionsssss sur les sockets?
    Par Nino dans le forum Développement
    Réponses: 5
    Dernier message: 01/04/2003, 21h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo