JeuWeb - Crée ton jeu par navigateur
Serveur Socket PHP - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Serveur Socket PHP (/showthread.php?tid=3525)



Serveur Socket PHP - Hakushi - 12-01-2009

Voici un petit serveur Socket en PHP construit dans l'objectif d'interagir avec Flash (via XMLSocket).

Il se constitue de deux classes: SocketServer et Logger.

SocketServer gere le server en tant que tel, les methods sont simples, et pour le "customiser" il suffit d'ajouter sa gestion de requete dans la method parseRequest (l'idéal etant d'avoir une classe pour le faire)

Code PHP :
<?php   
class SocketServer
{
var
$ip;
var
$port;

var
$masterSocket;

var
$logger;

private
$currentSockets;

function
__construct($ip, $port)
{
$this->ip = $ip;
$this->port = $port;

$this->logger = Logger::getInstance();

$this->initSocket();
$this->currentSockets = array();

$this->currentSockets[] = $this->masterSocket;

$this->listenToSockets();
}

private function
initSocket()
{

if ((
$this->masterSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0)
{
$this->logger->log("[SocketServer] "."socket_create() failed, reason: " . socket_strerror($this->masterSocket));
}

socket_set_option($this->masterSocket, SOL_SOCKET,SO_REUSEADDR, 1);

if ((
$ret = socket_bind($this->masterSocket, $this->ip, $this->port)) < 0) {

$this->logger->log("[SocketServer] "."socket_bind() failed, reason: " . socket_strerror($ret));

}


if ((
$ret = socket_listen($this->masterSocket, 5)) < 0) {

$this->logger->log("[SocketServer] "."socket_listen() failed, reason: " . socket_strerror($ret));
}
}

private function
parseRequest($socket, $data)
{
if(
substr($data,0, 22) == "<policy-file-request/>")
{
echo
"POLICY FILE REQUEST\n";
$crossFile = file("crossdomain.xml");
$crossFile = join('',$crossFile);
$this->sendMessage(array($socket),$crossFile);
return;
}
else
{
//Here you handle the request
}
}

public function
sendMessage( $message)
{
$message .= "\0";

foreach(
$this->currentSockets as $socket)
{
if(
$socket === NULL)
continue;

socket_write($socket, $message, strlen($message));
socket_getpeername($socket, $newClientAddress);
$this->logger->log("[SocketServer] Wrote : ".$message." to ". $newClientAddress);

}
}
public function
closeConnection()
{
foreach(
$this->currentSockets as $socket)
{
if (
$socket != $this->masterSocket) {
socket_getpeername($socket, $newClientAddress);
$this->logger->log("[SocketServer] "."REMOVING CLIENT ". $newClientAddress);
socket_close($socket);
}
}
$this->logger->close();
exit;
}

private function
listenToSockets()
{
while (
true) {

$changed_sockets = $this->currentSockets;

$num_changed_sockets = socket_select($changed_sockets, $write = NULL, $except = NULL, NULL);

foreach(
$changed_sockets as $socket)
{
if (
$socket == $this->masterSocket) {
if ((
$client = socket_accept($this->masterSocket)) < 0) {
$this->logger->log("[SocketServer] "."socket_accept() failed: reason: " . socket_strerror($socket));
continue;
} else {
// NEW CLIENT HAS CONNECTED
$this->currentSockets[] = $client;
socket_getpeername($client, $newClientAddress);
$this->logger->log("[SocketServer] "."NEW CLIENT ".$client." [IP: ".$newClientAddress."]");

}
} else {
$bytes = socket_recv($socket, $buffer, 4096, 0);

if (
$bytes == 0) {

// CLIENT HAS DISCONNECTED
socket_getpeername($client, $newClientAddress);
$this->logger->log("[SocketServer] "."REMOVING CLIENT ". $newClientAddress);
$index = array_search($socket, $this->currentSockets);

// Remove Socket from List
unset($this->currentSockets[$index]);


socket_close($socket);
//exit;

}else{
// CLIENT HAS SENT DATA
$this->parseRequest($socket, $buffer);
}
}
}
}
}
}
?>

La classe Logger (en Singleton comme on ne veut qu'un seul Log), on ecrit dans un txt, mais ca peut se changer facilement:
Code PHP :
<?php
class Logger
{
private static
$instance;
var
$Fnm;
var
$inF;
var
$ptr;

public static function
getInstance()
{
if(!isset(
$instance))
$instance = new Logger();

return
$instance;
}

function
__construct()
{
$this->Fnm = 'log.txt';
$this->inF = fopen($this->Fnm, 'w');
$this->ptr = ftell($this->inF);
}

function
log($message)
{
$message = "[".date('Y-m-d at h:i:s')."] ".$message."<br/>\n";

fputs($this->inF, $message);

}

function
close()
{
fclose($this->inF);
}
}
?>

Et pour demarrer le serveur :
Code PHP :
<?php
require_once('SocketServer.php');
require_once(
'Logger.php');

$mySocketServer = new SocketServer('192.168.1.4','1986');

Quand je rentre chez moi ce soir, je posterais le coté Flash (AS3)


RE: Serveur Socket PHP - Harparine - 13-01-2009

Merci de faire partager !


RE: Serveur Socket PHP - mdcarter - 13-01-2009

Et quid de la possibilité d'utiliser ce serveur de socket php, avec php ? ^^


RE: Serveur Socket PHP - wild-D - 13-01-2009

tu peux Smile


RE: Serveur Socket PHP - Ruz - 13-01-2009

...
[HS]autre question: zauriez des hébergeurs qui gèrent ca sur du mutualisé, ou truc du genre? (pas payant actuellement, pour les tests)[/HS]

Sinon, me pencherai un peu sur ca à l'occasion... (version full PHP)
Merci pour le code ^^


RE: Serveur Socket PHP - Cartman34 - 19-01-2009

Non Ruz, c'est impossible sur des hébergements gratuits pour des raisons de sécurité.