Précédent   Forum des professionnels en informatique > Applications > Développement réseaux
Développement réseaux Forum d'entraide sur le développement réseaux, sockets, etc...
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 22/12/2011, 21h00   #1
Invité régulier
 
Inscription : juillet 2008
Messages : 18
Détails du profil
Informations forums :
Inscription : juillet 2008
Messages : 18
Points : 7
Points : 7
Par défaut Problème PHP Socket

Bonjour à tous

Je vais expliquer ce que j'ai fait et ce qui ne fonctionne pas.

En raison d'un projet personnel, j'ai voulu créer un Mini-Chat en PHP géré par les sockets en local. En premier lieu, l'utilisateur (client) s'identifie, il est redirigé vers une page une page contenant deux Frames (InterfaceClient.php).

Le premier Frame contient l'adresse du serveur et du port, en l'occurrence, il s'agit de l'adresse : "127.0.0.1" associé à un port supérieur à 5000. Celui-ci est censé recevoir les messages postés par les utilisateurs.

Le second Frame (send.php) permet de poster les messages vers le serveur.

Le serveur exécuté en PHP-CLI (console), nommé (Serveurchat.php) se contente de lire les messages postés par send.php, il ajoute les clients dans une table de ressource. Un pointeur du tableau s'occupe d'associer l'id ressource actuel avec l'id ressource du tableau pour vérifier la correspondance des ressources.
Dès qu'un nouveau client se connecte, l'en-tête http est vérifié pour voir si il s'agit d'un envoi de message ou une d'une nouvelle connexion.

Pour le premier cas, le message envoyé est ajouté dans le conteneur "content" spécifié par un "innerHTML" à l'aide d'un script codé en javascript.

Pour le second cas, une en-tête HTML est envoyée pour générer une page web avec un conteneur qui s'identifie par "content".

Ainsi fait, le message posté précédemment par (send.php) est envoyé vers tous les utilisateurs connectés.

Venons-en maintenant au problème, lorsque j'envoie un message, celui-ci est bien traité par le serveur mais il n'est pas envoyé vers le client. Ce qui fait qu'aucun message ne s'affiche dans le cadre supérieur. Aucune erreur n'est générée.

Je vous remercie d'avance pour l'aide que vous m'apporterez.

Cordialement,

Cracko'

Voici les fichiers sources :

Serveurtchat.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
 require_once('../htdocs/configChat.php');
//Permet l'exécution du script indéfiniment
set_time_limit(0);
/* Active le vidage implicite des buffers de sortie, pour que nous
* puissions voir ce que nous lisons au fur et à mesure. */  
ob_implicit_flush();  
//contiendra la socket du serveur
$socket=NULL;
//contiendra l'id du client
$client=NULL;
//contiendra les données de l'en-tête
$input=NULL;
//contiendra la chaine retournée par la fonction socket_read()
$chaine=NULL;

// Function qui démarre le serveur. Elle reçoit en paramètre l'adresse du serveur ainsi que son port, généralement, il s'agit du port 80.

function DemarrerServeur($adress, $port)
{
	
	$donnees='';
	$longueur='1500';
	$message='';
	$message_complet='';
	$i='0';
	$html= "<html><head></head>";
	$html .="<body> <div id=\"content\" style=\"position:absolute;left:10%;width:70%;height:280px;top:10%;border:solid 1px;background-color:#E7F2F8;overflow:auto;\"></div> </body>";
	$html .="</html>"; 
	$tabClient=Array();
	if (($socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
	{
		echo "socket_create () a échoué : raison : " . socket_strerror(socket_last_error($socket)) . "\n";
	}
	//on lie la ressource sur laquelle le serveur va écouter si il y a une erreur, on ferme la socket.
	if ((socket_bind($socket, $adress, $port)) === FALSE)
	{
		echo "socket_bind () a échoué : raison : " . socket_strerror(socket_last_error($socket)) . "\n";
	}
	//on écoute les nouvelles ressources
	socket_listen($socket) OR DIE ("ERREUR:".socket_strerror(socket_last_error($socket)));
	
	echo "Le socket est en ecoute\r\n";
	//Premiere boucle infinie qui stoppe le serveur et ferme le script.
	while(true)
	{
		//accepte toutes les connexions.
		$client=socket_accept($socket) OR DIE("ERREUR Socket_accept". socket_strerror(socket_last_error($client)));  //il est arrêté tant qu'un client n'est pas connecté...
		
		if($client !== FALSE)
		{
			$i++;
			echo "le".$i."client est connecte\r\n";
			
			//mets l'id dans le tableau 
			$tabClient[]= $client;
		}
		//permets d'aficher le tableau de ressources
		for($j=0;$j<$i;$j++)
		{
			echo $tabClient[$j];
			
		}
		//Lis	l'en-tête du fichier html de l'utilisateur qui vient de se connecter
		$message=socket_read($client, 1024);//lis le messagé que le client vient d'envoyer en le récupérant dans la variable message
		
		if(substr_count($message, 'GET') > 0)
		{
			
			if(substr_count($message, 'pseudo') > 0)
			{
				socket_write($client, $html, strlen($html));
				echo $message;
				socket_close($client);
			}
			
		}
		else
			{
			
			
				$message_complet="<script language=\"javascript\">document.getElementById(\"content\").innerHTML+=\"".$message."\"</script>";
				
				while ($value = current($tabClient)) 
				{
					  if(is_resource($value))
					  {
						
							  
							  if((socket_write($value,$message_complet,strlen($message_complet))!==false))
							  {
								
									echo "message envoye".$value;
							  }

					}
					next($tabClient);
            
				}
				/*echo $message_complet;
				
				if(FALSE !==(socket_write($client, $message_complet, strlen($message_complet))))//envoie cette valeur précédemment lue vers le client
				{
					echo "r\nle client ".$i." a ecrit le message\r\n";
				}*/
		
			}
		
			

		
		//socket_close($client);
	}
	
	socket_close($socket);
}


DemarrerServeur($adresse,$port);

?>
InterfaceClient.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
28
29
30
31
32
<html><?php
 require_once('configChat.php');
if(isset($_GET['pseudo']))
{
	$pseudo=$_GET['pseudo'];
}


?>


<head>
<style>

</style>


</script>
</head>
<frameset rows="80%,*" border="1">



<frame noresize src="http://<? echo $adresse.':'.$port;?>?Pseudo=<? echo urlencode($pseudo);?>"> ">
<frame noresize src="send.php?Pseudo=<?php echo $pseudo;?> ">
</frameset>
<body>


</body>
</html>
ConnexionPseudo.php
Code :
1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
</head>
<body>
	<form method="GET" action="InterfaceClient.php" >
		Veuillez saisir un pseudo : 
		<input type="text" name="pseudo" />
		<input type="submit" value="envoyer" />
	</form>
</body>
</html>
configChat.php
Code :
1
2
3
4
5
6
7
8
<?

	$adresse='127.0.0.1';
	$port='20015';
	
	
?>
send.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 <html>
<head>
</head>
<body>
<FORM  NAME="formMessage" method="POST">
<textarea style="background-color:#E7F2F8;color:#AF00AF;" rows="2" cols="50" name="message"></textarea>
<input type="submit" Value="Envoyer" />
</form>

</body>
</html>
 <?php 
 require_once('configChat.php');
 //Cette fonction consiste a envoyer des données (message) vers le serveur, elle retourne ce que le serveur lui a envoyé.. autrement dit le message précédemment envoyé.
function envoiDesDonnees($adresse, $port)
{
	$retour='';//contiendra la chaine envoyée par le serveur
	$len=0;

	
	if (isset($_POST['message']))
	{
		$message=$_POST['message'];
		//$len=strlen($message);
		
		$socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) OR DIE ("ERREUR : la socket ne peut être cree");
		
		socket_connect($socket, $adresse, $port) OR DIE ("ERREUR : la socket ne peut se connecter ->". socket_strerror( socket_last_error($socket)) );
		
		//$connex=socket_read($socket, 1024);//Lis le message envoyé par le serveur lors de la connexion d'un client
		
		socket_write($socket, $message, strlen($message));//Envoi le message au serveur 
		
		//$retour=socket_read($socket, 1024);//Lis le message précédemment envoyé que le serveur renvoi
		
		socket_close($socket);//ferme la connexion
		
		ecritureFichier($retour);//ecriture dans le fichier texte
		
		
		//echo $retour; //permet de savoir si le serveur est connecté
	}
	
}

envoiDesDonnees($adresse, $port);


?>
Voici quelques screens pour que vous puissiez voir par vous même.



Crackozor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2011, 20h12   #2
Invité régulier
 
Inscription : juillet 2008
Messages : 18
Détails du profil
Informations forums :
Inscription : juillet 2008
Messages : 18
Points : 7
Points : 7
Je me permets de ré-actualiser l'annonce étant donné le peu d'activité avant Noël.
Crackozor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2012, 11h09   #3
Invité régulier
 
Inscription : juillet 2008
Messages : 18
Détails du profil
Informations forums :
Inscription : juillet 2008
Messages : 18
Points : 7
Points : 7
Ca fait beaucoup de sujets, je m'en excuse mais j'ai trouvé la solution. Je souhaite la faire partager !

J'ai travaillé d'une autre façon, j'ai re-codé de manière à ce que ce soit codé orienté objet et ce toujours en PHP.
Ce qui a été modifié :

ServeurtchatObjet.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
class Serveur
{
	 
	//contiendra la socket du serveur
	private $socket=NULL;
	//contiendra l'id du client
	private $client=NULL;
	//contiendra les données de l'en-tête
	private $input=NULL;
	//contiendra la chaine retournée par la fonction socket_read()
	private $chaine=NULL;
	
	private $tabClient=Array();
	
	
	private $donnees='';
	private $longueur='1500';
	private $message='';
	private $message_complet='';
	private $i='0';
	private $etat='1';
	
	// Function qui démarre le serveur. Elle reçoit en paramètre l'adresse du serveur ainsi que son port, généralement, il s'agit du port 80.

	public function DemarrerServeur($adress, $port)
	{
		
		
		if (($this->socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
		{
			echo "socket_create () a échoué : raison : " . socket_strerror(socket_last_error($this->socket)) . "\n";
		}
		
		//on lie la ressource sur laquelle le serveur va écouter si il y a une erreur, on ferme la socket.
		if ((socket_bind($this->socket, $adress, $port)) === FALSE)
		{
			echo "socket_bind () a échoué : raison : " . socket_strerror(socket_last_error($this->socket)) . "\n";
		}
		//on écoute les nouvelles ressources
		socket_listen($this->socket) OR DIE ("ERREUR:".socket_strerror(socket_last_error($this->socket)));
		
		echo "Le socket est en ecoute\r\n";
		//Premiere boucle infinie qui ne stoppe pas le serveur.
		while(true)
		{
		
		//accepte toutes les connexions.
		$this->client=socket_accept($this->socket) OR DIE("ERREUR Socket_accept". socket_strerror(socket_last_error($this->client)));  //il est arrêté tant qu'un client n'est pas connecté...
			
	
		//Lis	l'en-tête du fichier html de l'utilisateur qui vient de se connecter
		$this->message=socket_read($this->client, 5);//lis le messagé que le client vient d'envoyer en le récupérant dans la variable message
			
			if(substr_count($this->message, 'GET') > 0)
			{
				$this->i++;
				echo "le".$this->i."client est connecte\r\n";
				
					//mets l'id dans le tableau 
				$nick=urldecode(socket_read($this->client,23));
				$nick=trim(substr($nick,(strpos($nick,'=')+1),15));//On isole le pseudo
				echo "le pseudo".$nick;
				$this->tabClient[$nick]= $this->client;
			
				$this->Ecrire_aux_clients();
				/*if((socket_write($this->client, $this->html, strlen($this->html)))!==FALSE)
				{
					echo "l'en-tete a ete envoye \n\r".$this->message;
					
				}*/
				
				socket_getpeername($this->client,&$adress,&$port);
				
				echo "nouveau client ". $adress .":". $port;
			
				//socket_close($this->client);
			}
			
			else
			{
				echo "post envoye";
				
					//$this->message=socket_read($this->client, 1024);//lis le messagé que le client vient d'envoyer en le récupérant dans la variable message
				$paquet=socket_read($this->client,intval(substr($this->message,0,2))+intval(substr($this->message,2,3)));
				$pseudo=substr($paquet,0,intval(substr($this->message,0,2)));
				$message_final=substr($paquet,intval(substr($this->message,0,2)),intval(substr($this->message,2,3)));
				
				$full_client_msg="<font color='#FF0000'> [$pseudo a ecrit:]</font><font color='#AF00AF'>$message_final</font><br>";
			   
					
					//$full_client_msg="<font>$this->message</font><br>";
					
					$this->message_complet="<script language=\"javascript\">document.getElementById('content').innerHTML+=\"".$full_client_msg."\"</script>";
					
					reset($this->tabClient);
					while ($value = current($this->tabClient)) 
					{
						  if(is_resource($value))
						  {
							
								  
								if(($retourEcriture=socket_write($value,$this->message_complet,strlen($this->message_complet))!==false))
								  {
										echo "\r\n longueur du texte \r\n ".$retourEcriture;
										echo "message envoye \r\n".$this->message_complet;
										
								  }

						}
						next($this->tabClient);
				
					}
			}
		
			//socket_close($this->client);
			
		}
		
		socket_close($this->socket);
	}

	//methode qui envoie aux clients tous ceux qui sont connectés
	public function Ecrire_aux_clients()
	{
			reset($this->tabClient);
			
			while ($value = current($this->tabClient)) 
			{
				  if(is_resource($value))
				  {
						$msg.="<script language=javascript>add_opt(\"".key($this->tabClient)."\",\"".key($this->tabClient)."\")</script>";
				  }

				  next($this->tabClient);
			}
			
			$full_msg=$this->html.$msg;
			@socket_write($this->client,$full_msg,strlen($full_msg));
	}
}
?>
ce que j'ai ajouté :

configChat.php

Code :
1
2
3
4
5
6
7
8
9
10
11
12
$adresse='127.0.0.1';
	$port='20028';
	
	$html="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">";
	$html.="<html><head><style>body{background-image:url(http://localhost/stephaneey_chat/images/background.jpg);}</style><script language=\"JavaScript\">function add_opt(textval,valueval){document.getElementById('pseudos')";
	$html.=".options.add(new Option(textval,valueval));}function remove_opt(valueval){for(i=0;i<document.getElementById('pseudos')";
	$html.=".length;i++){if(document.getElementById('pseudos').options[i].value == valueval){document.getElementById('pseudos')";
	$html.=".options[i]=null;}}}\n<!--\n\n//-->\n</script>\n</head>\n<body>";
	$html.="<div id=\"content\" style=\"position:absolute;left:10%;width:70%;height:280px;top:10%;border:solid 1px;background-color:#E7F2F8;overflow:auto;\"></div>";
	$html.="<div id=\"info_board\" style=\"position:absolute;top:0;left:0px;width:550px;background-color:#4075BD;color:#FFFFFF;text-align:center\">Bienvenue sur le chat</div>";
	$html.="<select style=\"position:absolute;left:80%;width:18%;height:280px;top:10%;color:#AF00AF;font:verdana bold;background-color:#E7F2F8\" multiple id='pseudos'></select>";
startchat.php
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

	require_once('configChat.php');
	require_once('../php/ServeurtchatObjet.php');
	//Permet l'exécution du script indéfiniment
	ini_set("max_execution_time",0);
	
	//instanciation de la classe
	$chat=new Serveur();
	
	$chat->html=$html;
	
	$chat->DemarrerServeur($adresse, $port);
	
	
	
?>
Le problème était tout simplement ridicule, je devais envoyer une page complète en HTML lorsqu'un nouvel utilisateur se connecte. une balise style, etc.., en somme un code HTML plus complet.

Merci quand même pour l'aide.....
Crackozor est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h55.


 
 
 
 
Partenaires

Hébergement Web