Sujet : Hoa_Websocket et démo
Hey
,
Hoa_Websocket se trouve dans le trunk.
On trouve une vidéo de démonstration : http://j.mp/websocket_w (webm) et http://j.mp/websocket_m (mov).
Je vous laisse apprécier
.
« La structure de toute “chose”, qu'il s'agisse d'un langage, d'une maison, d'une machine etc., se résume à des relations. » — Alfred Korzybski
Vous n'êtes pas logué. Veuillez vous loguer ou vous enregistrer.
Hoa Forum » Actualités » Hoa_Websocket et démo
Vous devez vous loguer ou vous enregistrer pour poster une réponse
Hey
,
Hoa_Websocket se trouve dans le trunk.
On trouve une vidéo de démonstration : http://j.mp/websocket_w (webm) et http://j.mp/websocket_m (mov).
Je vous laisse apprécier
.
Yep,
C'est sympa, ça éviterais de se poser trop de questions pour faire du pull en js/curl etc...
Quelques questions:
-Je me doute que ça reste compatible seulement avec les dernières versions de dev de firefox et chrome?
-Si j'ai bien pigé, il y a un "processus" php qui tourne dans le vide pour le serveur? J'ai toujours entendu que php n'était pas fait pour tourner comme ça? qu'en est-il des perfs à ce niveau là?
-On pourrait avoir un aperçu du code js utilisé pour la démo? (ou carrément la démo en ligne
-limité à 5 utilisateurs si tu ne veux pas plier ton server
-
Chouette en tout cas!
Compatible Firefox, Chrome, Opera et Safari. Que demande le peuple ?
Un processus, oui bien sûr hein
. Tu as une boucle active et une boucle passive :
while(true)
foreach($server->select() as $node)
… // et on appelle $server->compute(…) à ce moment là. La méthode select() ne fait qu'appeler la fonction select() des sockets en C. C'est là que tu as une boucle passive, c'est du bas-niveau. Sans expliquer comment fonctionne select(), je peux te rassurer en te disant que ça ne mange pas 100% du processus
. Je viens de faire un petit test très rapide, on ne dépasse pas 1% du processus à chaque échange de message, et pendant qu'il n'y a pas d'échange, c'est 0%. Je pense que ça devrait répondre à ta question.
Oui la démo est en ligne et donc le code Javascript aussi : http://lab.hoa-project.net/Websocket/. Voici le code du serveur :
<?php
set_include_path('/var/hoa/Core/' .
PATH_SEPARATOR .
get_include_path());
require_once 'Core.php';
import('Socket.Internet.DomainName');
import('Websocket.Server');
class Chat extends Hoa_Websocket_Server {
protected function compute ( $sourceNode, $message ) {
$id = $sourceNode->getId();
$nodes = $this->getNodes();
$count = count($nodes);
foreach($nodes as $i => $node)
if(true === $node->isFirstMessage()) {
$this->send($node, $count . ';' . $message);
$node->setFirst(false);
}
elseif($node->getId() != $id)
$this->send($node, $count . ';' . $message);
return;
}
}
$ip = new Hoa_Socket_Internet_DomainName(
'lab.hoa-project.net', 8889, 'tcp'
);
$ws = new Chat($ip);5 utilisateurs, pas vraiment, on peut aller à plus que ça. Paul Rouget a fait un test de WebSocket sur un serveur basique et il est monté à 350/360 connexions simulatannées. Et ce n'était pas optimisé pour.
Merci pour les précisions!
(par contre j'arrive pas à faire marcher ça sous chrome? (dernière version 6.*) et j'ai la flemme de télécharger une béta de firefox ![]()
Oui, j'ai tué le serveur. Je fais des tests
.
Venez sur http://lab.hoa-project.net/Websocket/ pour tester
.
J'aime bien ^^
Je ne sais pas si c'est utile, mais voici ce que j'ai extrait pour mieux comprendre le fonctionnement de tout le bazar.
C'est un standalone du serveur sans Hoa. Inspiration pour le ->select() et recopiage pour le ->handshake().
<?php
class Server {
protected $clients = array();
protected $master = array();
function __construct($uri = 'tcp://0.0.0.0:8000') {
$this->master = stream_socket_server($uri, $errno, $errstr);
if (!$this->master) {
echo "$errstr ($errno)<br />\n";
} else {
while (true) {
foreach($this->select() as $client) {
$buffer = $client->read(2048);
if (!$client->handshake($buffer)) {
continue;
}
$this->compute($client, substr($buffer, 1, -1));
}
}
fclose($this->master);
}
}
function compute($clientFrom, $message) {
echo "Received $message from $clientFrom->socket\n";
echo count($this->clients)." connected\n";
foreach($this->clients as $clientTo) {
echo "Dispatching to $clientTo->socket\n";
$clientTo->send(chr(0).$message.chr(255));
}
}
function select() {
$read = array_map(function($client) {
return $client->socket;
}, $this->clients);
$read[] = $this->master;
$write = null;
$except = null;
stream_select($read, $write, $except, 30);
$found = array();
foreach ($read as $current) {
if ($current == $this->master) {
$socket = stream_socket_accept($current);
$client = new Client($socket, $this);
$this->clients[(string) $socket] = $client;
$found[] = $client;
} else {
$found[] = $this->clients[(string) $current];
}
}
return $found;
}
function onClientClose($client) {
echo "Client $client->socket closed\n";
unset($this->clients[(string) $client->socket]);
}
function close() {
foreach ($this->clients as $client) {
$client->close();
}
@fclose($this->master);
}
function __destruct() {
$this->close();
}
}
class Client {
public $socket;
protected $server;
protected $handshake = false;
function __construct($socket, $server) {
$this->socket = $socket;
$this->server = $server;
}
function send($message) {
echo "Sending $message to $this->socket\n";
return stream_socket_sendto($this->socket, $message);
}
function read($length) {
$message = @stream_socket_recvfrom($this->socket, $length);
if ($message == '') {
$this->close();
}
return $message;
}
function close() {
$this->server->onClientClose($this);
@fclose($this->socket);
}
public function handshake($buffer) {
if ($this->handshake) {
return true;
}
$x = explode("\r\n", $buffer);
$h = array();
for($i = 1, $m = count($x) - 3; $i <= $m; ++$i)
$h[strtolower(substr($x[$i], 0, strpos($x[$i], ':')))] =
trim(substr($x[$i], strpos($x[$i], ':') + 2));
if(0 !== preg_match('#GET (.*) HTTP#', $buffer, $match))
$h['resource'] = $match[1];
$key1 = $h['sec-websocket-key1'];
$key2 = $h['sec-websocket-key2'];
$key3 = $x[count($x) - 1];
$keynumb1 = (int) preg_replace('#[^0-9]#', '', $key1);
$keynumb2 = (int) preg_replace('#[^0-9]#', '', $key2);
$spaces1 = substr_count($key1, ' ');
$spaces2 = substr_count($key2, ' ');
$part1 = pack('N', $keynumb1 / $spaces1);
$part2 = pack('N', $keynumb2 / $spaces2);
$challenge = $part1 . $part2 . $key3;
$response = md5($challenge, true);
$this->send(
'HTTP/1.1 101 WebSocket Protocol Handshake' . "\r\n" .
'Upgrade: WebSocket' . "\r\n" .
'Connection: Upgrade' . "\r\n" .
'Sec-WebSocket-Origin: ' . $h['origin'] . "\r\n" .
'Sec-WebSocket-Location: ws://' . $h['host'] .
$h['resource'] . "\r\n" .
"\r\n" .
$response . "\r\n"
);
$this->handshake = true;
return false;
}
function __destruct() {
$this->close();
}
}
new Server('tcp://0.0.0.0:8080');C'est l'idée oui. Mais sinon, tu prends Hoa\Stream, Hoa\Socket et Hoa\Websocket et le tour est joué. Ça fait toujours un standalone aussi, et tu as toute la puissance des flux. Mais tu as pris l'essentiel il me semble, je n'ai pas vu de chose qu'il manquait.
Euh sauf un truc peut-être. select() retourne ce qui s'est ouvert … hmm, je pense qu'il y aura des cas où tu auras du « lag », une sorte de décalage voire des oublis de connexions. Il faudrait réfléchir à ça.
Hum. Je viens de revérifier avec ton code, et effectivement, ton select() ne retourne pas directement les nouvelles connexions. Il suffirait juste de supprimer la ligne
$found[] = $client;, non ?
Le client est ajouté, donc il serait traité au prochain select(). Tout simplement. ^^
Posts [ 1 to 10 of 13 ]
Vous devez vous loguer ou vous enregistrer pour poster une réponse
Hoa Forum » Actualités » Hoa_Websocket et démo
Powered by PunBB
Currently used extensions: pun_repository, pun_bbcode, pun_pm, pun_quote, pun_antispam. Copyright © 2008 PunBB
[ Généré en 0.092 secondes, 24 requêtes exécutées ]