Bonjour,
Depuis que j'ai appris l'existence des Websockets, je me suis rendu compte que l'un de mes projets majeurs n'allait plus du tout être viable car développé en AJAX, ce qui était bien trop lent. J'ai donc regardé quelques tutoriels de base sur les websockets mais malheureusement sans réel succès...
La majeure partie de ces derniers conseillent "PhpWebsocket" (http://code.google.com/p/phpwebsocket/), je suis donc allé sur le site et ai tenté d'en suivre les instructions. Là, j'apprends qu'il me faut créer deux fichiers, que je crée alors et place sur mon serveur dans le dossier /var/www/mon_site/websocket
Le premier, client.php :
Le second, server.php :
Je change le port indiqué dans le fichier, ajoute l'exception au Linux Firewall (est-ce vraiment nécessaire, en fait ?), place les deux fichiers en FTP dans le dossier et ouvre chrome. Là, je m'aperçois que dans le fichier client.php j'ai une ligne qui contient ws://localhost:12345/websocket/server.php. Je me dis alors que je devrais sûrement la renommer mais que devrais-je y placer ? Est-ce que je devrais mettre quelque chose du genre ws://monsite.com/websocket/server.php ? Est-ce que je devrais mettre quelque chose du genre ws://88.553.(ip):12345/var/www/mon_site/websocket/server.php ? En fait, je n'y connais rien et je sais pas trop où mène ce port et comment le configurer... Dois-je toucher à qqch de la config Apache ou je ne sais quoi ?
Sinon, encore une petite question pour l'activation du serveur websocket. J'avais bien sûr préalablement lancé la commande php -f /var/www/mon_site/websocket/server.php mais que se passe-t-il si je modifie le fichier server.php, par exemple par FTP ? Dois-je relancer le serveur ? Et si je souhaite ajouter des fonctionnalités au serveur, suis-je obligé à chaque fois de modifier l'intégralité du fichier et de le relancer ?
Merci d'avance de votre grande aide
7804j
Depuis que j'ai appris l'existence des Websockets, je me suis rendu compte que l'un de mes projets majeurs n'allait plus du tout être viable car développé en AJAX, ce qui était bien trop lent. J'ai donc regardé quelques tutoriels de base sur les websockets mais malheureusement sans réel succès...
La majeure partie de ces derniers conseillent "PhpWebsocket" (http://code.google.com/p/phpwebsocket/), je suis donc allé sur le site et ai tenté d'en suivre les instructions. Là, j'apprends qu'il me faut créer deux fichiers, que je crée alors et place sur mon serveur dans le dossier /var/www/mon_site/websocket
Le premier, client.php :
Code:
<html>
<head>
<title>WebSocket</title>
<style>
html,body{font:normal 0.9em arial,helvetica;}
#log {width:440px; height:200px; border:1px solid #7F9DB9; overflow:auto;}
#msg {width:330px;}
</style>
<script>
var socket;
function init(){
var host = "ws://localhost:12345/websocket/server.php";
try{
socket = new WebSocket(host);
log('WebSocket - status '+socket.readyState);
socket.onopen = function(msg){ log("Welcome - status "+this.readyState); };
socket.onmessage = function(msg){ log("Received: "+msg.data); };
socket.onclose = function(msg){ log("Disconnected - status "+this.readyState); };
}
catch(ex){ log(ex); }
$("msg").focus();
}
function send(){
var txt,msg;
txt = $("msg");
msg = txt.value;
if(!msg){ alert("Message can not be empty"); return; }
txt.value="";
txt.focus();
try{ socket.send(msg); log('Sent: '+msg); } catch(ex){ log(ex); }
}
function quit(){
log("Goodbye!");
socket.close();
socket=null;
}
// Utilities
function $(id){ return document.getElementById(id); }
function log(msg){ $("log").innerHTML+="<br>"+msg; }
function onkey(event){ if(event.keyCode==13){ send(); } }
</script>
</head>
<body onload="init()">
<h3>WebSocket v2.00</h3>
<div id="log"></div>
<input id="msg" type="textbox" onkeypress="onkey(event)"/>
<button onclick="send()">Send</button>
<button onclick="quit()">Quit</button>
<div>Commands: hello, hi, name, age, date, time, thanks, bye</div>
</body>
</html>
Le second, server.php :
Code:
<?php /* >php -q server.php */
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$master = WebSocket("localhost",12345);
$sockets = array($master);
$users = array();
$debug = false;
while(true){
$changed = $sockets;
socket_select($changed,$write=NULL,$except=NULL,NULL);
foreach($changed as $socket){
if($socket==$master){
$client=socket_accept($master);
if($client<0){ console("socket_accept() failed"); continue; }
else{ connect($client); }
}
else{
$bytes = @socket_recv($socket,$buffer,2048,0);
if($bytes==0){ disconnect($socket); }
else{
$user = getuserbysocket($socket);
if(!$user->handshake){ dohandshake($user,$buffer); }
else{ process($user,$buffer); }
}
}
}
}
//---------------------------------------------------------------
function process($user,$msg){
$action = unwrap($msg);
say("< ".$action);
switch($action){
case "hello" : send($user->socket,"hello human"); break;
case "hi" : send($user->socket,"zup human"); break;
case "name" : send($user->socket,"my name is Multivac, silly I know"); break;
case "age" : send($user->socket,"I am older than time itself"); break;
case "date" : send($user->socket,"today is ".date("Y.m.d")); break;
case "time" : send($user->socket,"server time is ".date("H:i:s")); break;
case "thanks": send($user->socket,"you're welcome"); break;
case "bye" : send($user->socket,"bye"); break;
default : send($user->socket,$action." not understood"); break;
}
}
function send($client,$msg){
say("> ".$msg);
$msg = wrap($msg);
socket_write($client,$msg,strlen($msg));
}
function WebSocket($address,$port){
$master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed");
socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed");
socket_bind($master, $address, $port) or die("socket_bind() failed");
socket_listen($master,20) or die("socket_listen() failed");
echo "Server Started : ".date('Y-m-d H:i:s')."\n";
echo "Master socket : ".$master."\n";
echo "Listening on : ".$address." port ".$port."\n\n";
return $master;
}
function connect($socket){
global $sockets,$users;
$user = new User();
$user->id = uniqid();
$user->socket = $socket;
array_push($users,$user);
array_push($sockets,$socket);
console($socket." CONNECTED!");
}
function disconnect($socket){
global $sockets,$users;
$found=null;
$n=count($users);
for($i=0;$i<$n;$i++){
if($users[$i]->socket==$socket){ $found=$i; break; }
}
if(!is_null($found)){ array_splice($users,$found,1); }
$index = array_search($socket,$sockets);
socket_close($socket);
console($socket." DISCONNECTED!");
if($index>=0){ array_splice($sockets,$index,1); }
}
function dohandshake($user,$buffer){
console("\nRequesting handshake...");
console($buffer);
list($resource,$host,$origin,$strkey1,$strkey2,$data) = getheaders($buffer);
console("Handshaking...");
$pattern = '/[^\d]*/';
$replacement = '';
$numkey1 = preg_replace($pattern, $replacement, $strkey1);
$numkey2 = preg_replace($pattern, $replacement, $strkey2);
$pattern = '/[^ ]*/';
$replacement = '';
$spaces1 = strlen(preg_replace($pattern, $replacement, $strkey1));
$spaces2 = strlen(preg_replace($pattern, $replacement, $strkey2));
if ($spaces1 == 0 || $spaces2 == 0 || $numkey1 % $spaces1 != 0 || $numkey2 % $spaces2 != 0) {
socket_close($user->socket);
console('failed');
return false;
}
$ctx = hash_init('md5');
hash_update($ctx, pack("N", $numkey1/$spaces1));
hash_update($ctx, pack("N", $numkey2/$spaces2));
hash_update($ctx, $data);
$hash_data = hash_final($ctx,true);
$upgrade = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" .
"Upgrade: WebSocket\r\n" .
"Connection: Upgrade\r\n" .
"Sec-WebSocket-Origin: " . $origin . "\r\n" .
"Sec-WebSocket-Location: ws://" . $host . $resource . "\r\n" .
"\r\n" .
$hash_data;
socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0)));
$user->handshake=true;
console($upgrade);
console("Done handshaking...");
return true;
}
function getheaders($req){
$r=$h=$o=null;
if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; }
if(preg_match("/Host: (.*)\r\n/" ,$req,$match)){ $h=$match[1]; }
if(preg_match("/Origin: (.*)\r\n/",$req,$match)){ $o=$match[1]; }
if(preg_match("/Sec-WebSocket-Key2: (.*)\r\n/",$req,$match)){ $key2=$match[1]; }
if(preg_match("/Sec-WebSocket-Key1: (.*)\r\n/",$req,$match)){ $key1=$match[1]; }
if(preg_match("/\r\n(.*?)\$/",$req,$match)){ $data=$match[1]; }
return array($r,$h,$o,$key1,$key2,$data);
}
function getuserbysocket($socket){
global $users;
$found=null;
foreach($users as $user){
if($user->socket==$socket){ $found=$user; break; }
}
return $found;
}
function say($msg=""){ echo $msg."\n"; }
function wrap($msg=""){ return chr(0).$msg.chr(255); }
function unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); }
function console($msg=""){ global $debug; if($debug){ echo $msg."\n"; } }
class User{
var $id;
var $socket;
var $handshake;
}
?>
Je change le port indiqué dans le fichier, ajoute l'exception au Linux Firewall (est-ce vraiment nécessaire, en fait ?), place les deux fichiers en FTP dans le dossier et ouvre chrome. Là, je m'aperçois que dans le fichier client.php j'ai une ligne qui contient ws://localhost:12345/websocket/server.php. Je me dis alors que je devrais sûrement la renommer mais que devrais-je y placer ? Est-ce que je devrais mettre quelque chose du genre ws://monsite.com/websocket/server.php ? Est-ce que je devrais mettre quelque chose du genre ws://88.553.(ip):12345/var/www/mon_site/websocket/server.php ? En fait, je n'y connais rien et je sais pas trop où mène ce port et comment le configurer... Dois-je toucher à qqch de la config Apache ou je ne sais quoi ?
Sinon, encore une petite question pour l'activation du serveur websocket. J'avais bien sûr préalablement lancé la commande php -f /var/www/mon_site/websocket/server.php mais que se passe-t-il si je modifie le fichier server.php, par exemple par FTP ? Dois-je relancer le serveur ? Et si je souhaite ajouter des fonctionnalités au serveur, suis-je obligé à chaque fois de modifier l'intégralité du fichier et de le relancer ?
Merci d'avance de votre grande aide

7804j