Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 28/11/2010, 18h35   #1
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
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
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/11/2010, 19h25   #2
Membre éclairé
 
Inscription : octobre 2004
Messages : 235
Détails du profil
Informations forums :
Inscription : octobre 2004
Messages : 235
Points : 360
Points : 360
Pas en PHP/HTTP standard :-)

On peut le simuler avec du polling, mais ce n'est pas vraiment ce que tu cherches.
Joker-eph est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/11/2010, 19h43   #3
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
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 :

Citation:
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 ?
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/11/2010, 20h14   #4
Membre éclairé
 
Inscription : octobre 2004
Messages : 235
Détails du profil
Informations forums :
Inscription : octobre 2004
Messages : 235
Points : 360
Points : 360
Euh, je dirais "pas si tes clients sont des navigateurs web" ;-)

polling : http://en.wikipedia.org/wiki/Polling...ter_science%29
Joker-eph est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/11/2010, 20h36   #5
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
ok merci pour les infos.

Je vais continuer à me documenter pour choisir la meilleure option pour mon projet
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/11/2010, 10h35   #6
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
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
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/11/2010, 18h07   #7
Expert Confirmé
 
Avatar de Séb.
 
Inscription : mars 2005
Messages : 2 815
Détails du profil
Informations personnelles :
Âge : 34
Localisation : France

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

Informations forums :
Inscription : mars 2005
Messages : 2 815
Points : 3 440
Points : 3 440
Tu passes bien par la console ?
Pour moi pas de soucis de buffer de sortie.
__________________
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
Séb. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 11h05   #8
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
Je...non

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

Citation:
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 :
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 ?
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 11h20   #9
Expert Confirmé
 
Avatar de grunk
 
Homme Olivier
Développeur Web
Inscription : août 2003
Messages : 1 834
Détails du profil
Informations personnelles :
Nom : Homme Olivier
Âge : 27
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Industrie

Informations forums :
Inscription : août 2003
Messages : 1 834
Points : 3 312
Points : 3 312
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.
grunk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 11h32   #10
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
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
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 11h40   #11
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
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
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2010, 19h37   #12
Expert Confirmé
 
Avatar de Séb.
 
Inscription : mars 2005
Messages : 2 815
Détails du profil
Informations personnelles :
Âge : 34
Localisation : France

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

Informations forums :
Inscription : mars 2005
Messages : 2 815
Points : 3 440
Points : 3 440
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.

Citation:
EDIT: c'est bon ca flush bien
Cool
__________________
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
Séb. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2010, 10h46   #13
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
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...

Citation:
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 :
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 :
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 :
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
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2010, 18h43   #14
Expert Confirmé
 
Avatar de Séb.
 
Inscription : mars 2005
Messages : 2 815
Détails du profil
Informations personnelles :
Âge : 34
Localisation : France

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

Informations forums :
Inscription : mars 2005
Messages : 2 815
Points : 3 440
Points : 3 440
Citation:
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 :
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 :
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 ;
    }
}
__________________
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
Séb. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2010, 21h19   #15
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
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
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h24.


 
 
 
 
Partenaires

Hébergement Web