Okay i created a HTTP Ajax chat a while back and its really hitting my web server hard, its created using memcache to store the data in but still hits the server hard.
Im wanting to create a php socket run it on my server then either use java or flash for the users to connect to the socket since javascript dont support sockets(annoying !)
I quickly found content on php sockets to be somewhat outdated and quickly tried to create a class based on the functions to give me catchable methods instead of functions which just error….
[code=php]<?php
interface iSocket {
public static function create($domain, $type, $protocol);
public static function bind($socket, $address, $port);
public static function listen($socket);
public static function write($socket, $uffer);
public static function close($socket);
public static function read($socket, $length);
public static function accept($socket);
public static function select(array &$read, array &$write, array &$except, $tv_sec);
public static function getpeername($socket, &$ip, &$port=null);
}
class socket implements iSocket {
/**
*
* @param <static> $domain
* @param <static> $type
* @param <static> $protocol
* @return <resource>
*/
public static function create($domain, $type, $protocol) {
$resource = @socket_create($domain, $type, $protocol);
if (self::_isResource($resource)) {
return $resource;
}
throw new Exception(‘Failed to create socket on ‘ . $domain . ‘, type ‘ . $type . ‘, protocol ‘ . $protocol . “nn”);
}
/**
*
* @param <resource> $socket
* @param <string> $address
* @param <integer> $port
* @return <bool>
*/
public static function bind($socket, $address, $port) {
if (self::_isResource($socket)) {
$status = @socket_bind($socket, $address, $port);
if ($status) {
return (bool) true;
}
}
throw new Exception(‘Failed to bind socket to ‘ . $address . ‘ on port ‘ . $port . “nn”);
}
/**
*
* @param <resource> $socket
* @return <bool>
*/
public static function listen($socket) {
if (self::_isResource($socket)) {
$status = @socket_listen($socket);
if ($status) {
return $status;
}
}
throw new Exception(‘Failed to listen’);
}
/**
*
* @param <resource> $socket
* @return <bool>
*/
public static function close($socket) {
if (self::_isResource($socket)) {
@socket_shutdown($socket, 2);
return (bool) @socket_close($socket);
}
return (bool)false;
}
/**
*
* @param <resource> $socket
* @param <string> $buffer
* @return <bool>
*/
public static function write($socket, $buffer) {
if (self::_isResource($socket)) {
$return = @socket_write($socket, $buffer, strlen($buffer));
if ($return) {
return (bool) true;
}
}
return (bool) false;
}
/**
*
* @param <resource> $socket
* @param <integer> $length
* @return <mixed>
*/
public static function read($socket, $length) {
if (self::_isResource($socket)) {
@socket_recv($socket, $data, $length, MSG_DONTWAIT);
if ($data != null) {
return $data;
}
}
return (bool) false;
}
/**
*
* @param <resource> $socket
* @return <mixed>
*/
public static function accept($socket) {
if (self::_isResource($socket)) {
$return = @socket_accept($socket);
if (is_resource($socket)) {
return $return;
}
}
return (bool) false;
}
/**
*
* @param <array> $read
* @param <array> $write
* @param <array> $except
* @param <integer> $tv_sec
* @return <mixed>
*/
public static function select(array &$read, array &$write, array &$except, $tv_sec=0) {
$return = @socket_select($read, $write, $except, $tv_sec);
if ((is_numeric($return)) && ($return > 0)) {
return (int) $return;
}
return (bool) false;
}
/**
*
* @param <resource> $socket
* @param <mixed> $ip
* @param <integer> $port
* @return <bool>
*/
public static function getpeername($socket, &$ip, &$port = null) {
if (self::_isResource($socket)) {
$return = @socket_getpeername($socket, $ip, $port);
if($return){
return (bool)true;
}
}
return (bool)false;
}
/**
*
* @param <resource> $socket
* @return <bool>
*/
private static function _isResource($socket){
if(is_resource($socket)){
return (bool)true;
}
return (bool)false;
}
}
?>
So once i had created those static methods i then played with the class but had some very odd results, sometimes it would work yet others would just fail…im using a VPS server on debian i setup myself PHP is complied with sockets.
I came up with this…but its not very stable its working sometimes but other times its not.
[code=php]<?php
class chatServer {
private $_socket;
private $_clients;
private $_maxConnections;
private $_position;
public function __construct($bind, $port, $maxConnections=10) {
try {
$this->_socket = socket::create(AF_INET, SOCK_STREAM, SOL_TCP);
socket::bind($this->_socket, ‘127.0.0.1’, 5190);
socket::listen($this->_socket);
$this->_clients = array($this->_socket);
$this->_position = 1;
$this->_maxConnections = $maxConnections;
} catch (Exception $e) {
die($e->getMessage());
}
}
public function listen() {
$read = $this->_clients;
$status = socket::select($read, $write=array(), $except=array(), 0);
if($status){
if (in_array($this->_socket, $read)) {
$this->_clients[$this->_position] = new stdClass();
$this->_clients[$this->_position]->socket = socket_accept($this->_socket);
socket::write($this->_clients[$this->_position]->socket, “Connectedn”);
socket::getpeername($this->_clients[$this->_position]->socket, $this->_clients[$this->_position]->address);
$key = array_search($this->_socket, $read);
unset($read[$key]);
$this->_position++;
}
}
sort($this->_clients);
$clients = count($this->_clients);
for($i=1;$i<$clients;++$i){
if(is_object($this->_clients[$i])){
$data = socket::read($this->_clients[$i]->socket, 256);
if($data){//found data
foreach($this->_clients as $client){//send data to all current clients
if(is_object($client)){
socket::write($client->socket, trim($data).”n”);
}
}
}else{
socket::close($this->_clients[$i]->socket);
unset($this->_clients[$i]);
}
}
}
return count($this->_clients).”n”;
}
}
?>
The class is mainly built with bits around the internet but sadly that was all PHP4…im finding the documentation somewhat lacking aswell
Can anyone help ive also just noticed stream_socket_server() which came into PHP5 is this some kind of new versions ?