Muzes pouzit i real-time-komunikaci nebo web-socket. Ale server ti to musi podporovat a dovolit. Tam pak musi bezet php trvale jako server. Bezne ma php soubor nastaveny casovy limit, kdy ho php vypne, totiz.
A druha nevyhoda je, ze to podporuje zatim jen FF.
Takovy php web-socket vypada asi takto
Principialne
$this->serverStop();
$this->run = true;
while($this->run)
{
$this->serverRun();
}
}
public function serverRun()
{
$write_null = null;
$except_null = null;
$changed = $this->sockets_db->table;
//var_dump($changed);
socket_select($changed,$write_null,$except_null,0,10);
foreach($changed as $socket)
{
if ($socket==$this->master)
{
$user = $this->connect($this->cfg);
}
else {
$bytes = @socket_recv($socket,$buffer,$this->cfg['server']['max_buffer'],0);
if ($bytes === false)
{
$this->writeError('');
$this->disconnect($socket);
}
elseif ($bytes==0)
{
$user = $this->disconnect($socket);
}
else {
$this->run = $this->receive($socket, $buffer);
}
}
}
}
cely kod, ktery pouzivam pro testovani
<title>WS server</title>
<?php
error_reporting(E_ALL);
//set_time_limit(0); // how long run server
//set_time_limit(5); // how long run server
//set_time_limit(20); // how long run server
set_time_limit(10); // how long run server
ob_implicit_flush();
//$MSG = new class_message;
class class_microtime
{
var $time;
public function __construct()
{
$this->time = array();
$this->add();
}
public function read()
{
list($usec,$sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
public function add()
{
$this->time[] = $this->read();
}
public function stop()
{
$this->add();
$arr = array();
$li = count($this->time);
for ($i=1;$i<$li;++$i)
{
$arr[] = $this->time[$i] - $this->time[$i-1];
}
return implode(' | ', $arr);
}
}
$MICRO = new class_microtime();
// ---------------------------------------------------
class classRequest
{
public function isSetX($arr,$key,$def=null)
{
return $arr && isset($arr[$key]) ? $arr[$key] : $def;
}
public function sessionPostGet($key,$def='')
{
return $this->isSetX($_SESSION,$key,$this->isSetX($_POST,$key,$this->isSetX($_GET,$key,$def)));
}
public function postGet($key,$def='')
{
return $this->isSetX($_POST,$key,$this->isSetX($_GET,$key,$def));
}
public function get($key,$def='')
{
return $this->isSetX($_GET,$key,$def);
}
}
$REQ = new classRequest();
// ----------------------
class classRoom
{
var
$index, // unique autoincrement
$name, // name unique
$desc;
}
class classUser {
var
$index, // unique autoincrement
$name, // name+psw unique
$psw;
}
class classRoomlist {
var
$index, // unique autoincrement
$id, // user - unique autoincrement
$name,
$desc;
}
class classUserlist {
var
$index, // unique autoincrement
$id, // user - unique autoincrement
$name,
$psw,
$ip,
$time,
$socket,
$handshake;
}
class classMessage {
var
$type,
$data;
}
// ----
class classDb
{
var $table, $structure;
function __construct($structure)
{
$this->table = array();
$this->structure = $structure;
}
function import($csv) //,$id=false
{
$csv = explode("\n",$csv);// parse csv, str_getcsv()
foreach ($csv as $row)
{
$row = trim($row);
if ($row!='')
{
$row = explode(";",$row);
if (isset($row[0]) && $row[0]!=='' && trim($row[0])!=='')
{
$new_row = new $this->structure;
//$data = array();
$i = 0;
foreach ($new_row as $key=>$value)
{
$new_row->{$key} = isset($row[$i]) ? $row[$i] : '';
++$i;
}
$this->insert($new_row);
}
}
}
}
function insert($data) //,$id=false
{
$index = count($this->table);
$new_row = new $this->structure;
foreach ($new_row as $key=>$value)
{
$new_row->{$key} = isset($data->{$key}) ? $data->{$key} : '';
}
// if ($id && isset($new_row->id)) // for user, duplicate index to id
// {
// $new_row->id = $index;
// }
if (isset($new_row->name))
{
$name = $new_row->name;
$name = $name && $name!=='' ? $name : $index; //name or id
$new_row->name = $name;
}
$new_row->index = $index;
$this->table[$index] = $new_row;
return $new_row;
}
function update($where,$data)
{
$row = $this->select($where); // read
if ($row && is_object($row))
{
foreach($data as $key=>$value)
{
if (!is_null($value) && isset($row->{$key})) // ignore undefined
{
$row->{$key} = $value;
}
}
$this->table[$row->id] = $row; // write
return $row;
}
return false;
}
function delete($data)
{
$row = $this->select($data);
if ($row)
{
unset($this->table[$row->index]);
return $row;
}
return false;
}
function select($where)
{
//var_dump($this->table);
foreach($this->table as $row)
{
$bool = true;
foreach($where as $key => $value)
{
if (!is_null($value) && isset($row->{$key})) // ignore undefined
{
//echo 'T'.$key.' '.$value.' '.$row->{$key};
$bool &= $row->{$key} == $value;
if (!$bool) break;
}
}
//echo $bool*1;
//echo '-';
if ($bool)
{
return $row;
}
}
return false;
}
}
class classSocket {
var
$index, // unique autoincrement
$socket;
}
class classSocketsDb
{
var $table, $structure;
function __construct($structure)
{
$this->table = array();
$this->structure = $structure;
}
function insert($data)
{
$index = count($this->table);
$this->table[$index] = $data;
$new_row = new $this->structure;
$new_row->index = $index;
$new_row->socket = $data;
return $new_row;
}
function delete($data)
{
$row = $this->select($data);
if ($row)
{
unset($this->table[$row->index]);
return $row;
}
return false;
}
function select($data)
{
foreach($this->table as $index=>$value)
{
if ($value==$data)
{
$new_row = new $this->structure;
$new_row->index = $index;
$new_row->socket = $value;
return $new_row;
}
}
return false;
}
}
function extractMsg($msg)
{
global $CHAT,$WS;
$str = '';
$a = isset($msg->type) ? $msg->type : (isset($msg->data->type) ? $msg->data->type : '');
$str .= ' type='.$a;
$a = isset($msg->user) ? $msg->user : (isset($msg->data->user) ? $msg->data->user : (isset($msg->data->user1) ? $msg->data->user1 : ''));
$a = $CHAT->userForPeer($a);
$str .= ' user='.$WS->encode($a);
return $str;
}
class classChat
{
var $room_db, $users_db, $roomlist_db, $userlist_db;
public function __construct($id=0,$name='',$desc='')
{
// $this->rooms_db = new classRoomsDb();
// $this->users_db = new classUsersDb();
$this->rooms_db = new classDb('classRoom');
$this->users_db = new classDb('classUser');
$this->userlist_db = new classDb('classUserlist');
$this->roomlist_db = new classDb('classRoomlist');
$csv_rooms = "
0;room;none
";
$csv_users = "
0;all;all
1;peter;peter
2;host;host
3;test;test
";
$this->rooms_db->import($csv_rooms);
$this->users_db->import($csv_users);
foreach($this->rooms_db->table as $room)
{
$new_room = new classRoomlist;
foreach($new_room as $key=>$value)
{
$new_room->{$key} = isset($room->{$key}) ? $room->{$key} : '';
}
$new_room->id = $room->index;
$this->roomlist_db->insert($new_room);
}
$this->userListAdd('all','all');
// $new_user = new classUserlist;
// $new_user->id = $insert ? $user->index : $user->id;
// $new_user = new classUser;
// $new_user->name = 'all';
// $new_user = $this->users_db->select($new_user);
// $this->userlist_db->insert($new_user);
}
public function userForPeer($user)
{
return array(
'id' => isset($user->id) ? $user->id : null,
'name' => isset($user->name) ? $user->name : null
);
}
public function userForRoom($user)
{
return array(
'id' => isset($user->id) ? $user->id : null,
'name' => isset($user->name) ? $user->name : null,
'ip' => isset($user->ip) ? $user->ip : null,
'time' => isset($user->time) ? $user->time : null
);
}
public function userListFilter($user)
{
// return isset($user->name) && $user->name!=='master' && $user->name!=='all';
return isset($user->name); // && $user->name!=='all'
}
public function userList($room=1)
{
$list = array();
foreach ($this->userlist_db->table as $user)
{
if ($this->userListFilter($user))
{
$list[] = $this->userForRoom($user);
}
}
return $list;
}
function userListAdd($name,$psw,$socket=false)
{
global $WS;
$new_user = new classUser;
$new_user->name = $name;
$new_user->psw = $psw;
$insert = false;
$user = $this->userlist_db->select($new_user);
if (!$user)
{
$user = $this->users_db->select($new_user);
$insert = true;
}
else {
$user1 = $user;
$data = array(
'time' => time(),
'user' => $this->userForRoom($user1)
);
$this->send('allNotUser', $user1, false, 'leave', $data);
$this->send('user', $user1, $user1, 'leaved', $data);
$WS->disconnect($user1->socket);
}
if ($user)
{
$ip = '';
$new_user = new classUserlist;
$new_user->id = $insert ? $user->index : $user->id;
$new_user->name = $user->name;
$new_user->psw = $user->psw;
$new_user->time = time();
if ($socket)
{
socket_getpeername($socket, $ip) or $this->writeError("socket_getpeername()",$socket); //WS
$new_user->ip = $ip;
$new_user->socket = $socket;
}
if ($insert)
{
$user = $this->userlist_db->insert($new_user);
}
else {
$where = $this->userForPeer($new_user);
unset($new_user->name);
unset($new_user->psw);
$user = $this->userlist_db->update($where,$new_user);
}
return $user;
}
return false;
}
public function roomForPeer($room)
{
return array(
'id' => isset($room->id) ? $room->id : null,
'name' => isset($room->name) ? $room->name : null
);
}
public function roomForUser($room)
{
return array(
'id' => isset($room->id) ? $room->id : null,
'name' => isset($room->name) ? $room->name : null,
'desc' => isset($room->desc) ? $room->desc : null
);
}
public function roomList()
{
$list = array();
foreach ($this->roomlist_db->table as $room)
{
$list[] = $this->roomForUser($room);
}
return $list;
}
public function sendFilter($user)
{
// return isset($user->name) && $user->name!=='master' && $user->name!=='all';
return isset($user->name) && $user->name!=='all';
}
function send($type_send, $user1, $user2, $type, $data)
{
var_dump('CHAT::send '.($type?$type:'?').' '.($type_send?$type_send:'?'));
global $WS;
$new_msg = new classMessage;
$new_msg->type = $type;
$new_msg->user = $this->userForPeer($user1);
$new_msg->data = $data;
$msg = $WS->msgEncode($new_msg);
$len = strlen($msg);
switch ($type_send)
{
case 'user':
$WS->send($user2->socket,$msg,$len);
return;
case 'all':
foreach($this->userlist_db->table as $user)
{
if ($this->sendFilter($user))
{
$WS->send($user->socket,$msg,$len);
}
}
return;
case 'allNotUser':
foreach($this->userlist_db->table as $user)
{
if ($this->sendFilter($user) && $user->name!==$user1->name)
{
$WS->send($user->socket,$msg,$len);
}
}
return;
default: break;
}
}
function receive($socket,$msg)
{
if (!(is_object($msg) && isset($msg->type) && isset($msg->data) && isset($msg->user)))
{
var_dump('CHAT::receive '.'?',$msg);
return;
}
var_dump('CHAT::receive '.extractMsg($msg)); //,$msg
$new_user = new classUser;
$new_user->$socket = $socket;
$user = isset($msg->user) && $msg->type!='join' ? $this->userlist_db->select($msg->user) : false;
$user1 = $user;
$user2 = false;
if ($user)
{
//var_dump('CHAT::receive is_user');
switch($msg->type)
{
case 'msg':
if (!(is_object($msg->data) && isset($msg->data->user2) && isset($msg->data->message)))
{
break;
}
$user2 = $this->userlist_db->select($msg->data->user2);
if ($user2)
{
$data = array(
'time' => time(),
'user1' => $this->userForPeer($user1),
'user2' => $this->userForPeer($user2),
'message' => $msg->data->message
);
$type = ($user2->name=='all') ? 'all' : 'user';
$this->send($type, $user1, $user2, $msg->type, $data);
}
break;
case 'rtc':
if (!(is_object($msg->data) && isset($msg->data->user2) && isset($msg->data->message)))
{
break;
}
$user2 = $this->userlist_db->select($msg->data->user2);
if ($user2)
{
$data = array(
'time' => time(),
'user1' => $this->userForPeer($user1),
'user2' => $this->userForPeer($user2),
'message' => $msg->data->message
);
$this->send('user', $user1, $user2, $msg->type, $data);
}
break;
// case 'join':
// $data = array(
// 'user' => $this->users_db->userForRoom($user1)
// );
// $this->send('allNotUser', $user1, false, $msg->type, $data);
// $this->send('user', $user1, $user1, 'joined', $data);
// return;
case 'leave':
$data = array(
'time' => time(),
'user' => $this->userForRoom($user1)
);
$this->send('allNotUser', $user1, false, $msg->type, $data);
$this->send('user', $user1, $user1, 'leaved', $data);
break;
case 'userlist':
if (!(is_object($msg->data) && isset($msg->data->room)))
{
break;
}
$data = array(
'time' => time(),
'room' => $msg->data->room,
'list' => $this->userList($msg->data->room)
);
$this->send('user', $user1, $user1, $msg->type, $data);
//$ROOM->sendUserList($user,$msg->data);
break;
case 'roomlist':
$data = array(
'time' => time(),
'list' => $this->roomList()
);
$this->send('user', $user1, $user1, $msg->type, $data);
break;
// case 'room':
// if (!(is_object($msg->data) && isset($msg->data->room)))
// {
// return;
// }
// $data = $this->roomForUser($this->rooms_db->select($msg->data->room));
// $this->send('user', $user1, $user1, $msg->type, $data);
// return;
default: break;
}
}
else {
switch($msg->type)
{
case 'join':
$user = $this->userListAdd($msg->data->user->name,$msg->data->user->psw,$socket);
/*
//var_dump($msg);
// unset($new_user->socket);
$new_user = new classUser;
$new_user->name = ;
$new_user->psw = $msg->data->user->psw;
$insert = false;
$user = $this->userlist_db->select($new_user);
if (!$user)
{
$user = $this->users_db->select($new_user);
$insert = true;
}
if ($user)
{
socket_getpeername($socket, $ip) or $this->writeError("socket_getpeername()",$socket); //WS
$new_user = new classUserlist;
$new_user->id = $insert ? $user->index : $user->id;
$new_user->name = $user->name;
$new_user->psw = $user->psw;
$new_user->ip = $ip;
$new_user->time = time();
$new_user->socket = $socket;
if ($insert)
{
$user = $this->userlist_db->insert($new_user);
}
else {
$where = $this->userForPeer($new_user);
unset($new_user->name);
unset($new_user->psw);
$user = $this->userlist_db->update($where,$new_user);
}
// $where = $this->userForPeer($user);
// unset($new_user->name);
// unset($new_user->psw);
// $where = $this->userForPeer($user);
// $this->userlist_db->update($where, $new_user);
// $user = $this->users_db->select($new_user);
// $user = $this->users_db->select($new_user);
// foreach ($new_user as $key=>$value)
// {if (!is_null($value)) {$user->{$key} = $value;}}
//var_dump('user',$user);
// $user1 = $user;
// $user = $new_user;
*/
if ($user)
{
$user1 = $user;
$data = array(
'time' => time(),
'user' => $this->userForRoom($user1)
);
$this->send('allNotUser', $user1, false, $msg->type, $data);
$this->send('user', $user1, $user1, 'joined', $data);
}
break;
default: break;
}
//var_dump($_REQUEST);
//var_dump($name,$psw);
// $user = $CHAT->userLogin($name,$psw,$socket,$ip,true);
//$this->userAdd($socket,$ip,true);
// return $this->findUserBySocket($socket); // add user->index
}
}
}
// -----------------
class classWebSocket
{
public $cfg;
public $run;
public $master;
public $sockets_db;
function __construct($cfg)
{
$url = "ws://".$cfg['server']['host'].":".$cfg['server']['port']."/demo/ws_server.php";//RTC-chat/php-ws
$cfg['server']['url'] = $url;
$this->cfg = $cfg;
// $this->sockets_db = new classSocketsDb;
$this->sockets_db = new classSocketsDb('classSocket');
$this->serverCreate();
}
public function writeError($socket,$str)//,
{
if ($socket)
{
$err_code = socket_last_error($socket);
socket_clear_error($socket);
}
else {
$err_code = socket_last_error();
}
$err_msg = socket_strerror($err_code);
$str .= ' Socket error ['.$err_code.'] '.$err_msg.'<br>';
echo $str;
return false;
}
public function encode($obj)
{
return json_encode($obj);
}
public function decode($str)
{
return json_decode($str);
}
//Unmask incoming framed message
function unmask($text,$type=false) {
// $masked = ord($text[1]) >> 7;
$length = ord($text[1]) & 127;
// $length = (ord($text[1]) >= 128) ? ord($text[1]) - 128 : ord($text[1]);
if($length == 126) {
var_dump('unmask 0');
$masks = substr($text, 4, 4);
$data = substr($text, 8);
}
elseif($length == 127) {
var_dump('unmask 1');
$masks = substr($text, 10, 4);
$data = substr($text, 14);
// $masks = substr($text, 4, 4);
// $data = substr($text, 8);
}
else {
var_dump('unmask 2');
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
function unmask2($text,$type=false) {
$masked = ord($text[1]) >> 7;
var_dump($masked);
$length = ord($text[1]) & 127;
if($type==1) {
var_dump('unmask 0');
$masks = substr($text, 4, 4);
$data = substr($text, 8);
}
elseif($type==2) {
var_dump('unmask 1');
$masks = substr($text, 10, 4);
$data = substr($text, 14);
// $masks = substr($text, 4, 4);
// $data = substr($text, 8);
}
else {
var_dump('unmask 2');
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
/*
$length = ord($text[1]) & 127;
if($length == 126) {
$masks = substr($text, 4, 4);
$data = substr($text, 8);
}
elseif($length == 127) {
$masks = substr($text, 10, 4);
$data = substr($text, 14);
}
else {
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
*/
//Encode message for transfer to client.
function mask($text)
{
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCn', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCNN', $b1, 127, $length);
return $header.$text;
}
function msgEncode($msg)
{
return $this->mask($this->encode($msg));
}
function msgDecode($msg)
{
//var_dump('uuu0',$this->unmask2($msg,1));
//var_dump('uuu1',$this->unmask2($msg,2));
//var_dump('uuu2',$this->unmask2($msg,0));
return $this->decode($this->unmask($msg));
}
function send($socket=null,$msg='',$len=0)
{
var_dump('WS::send '.$socket.' '.$msg);
if ($socket && $socket!=$this->master)
{
socket_write($socket,$msg,$len);
}
}
function msgSend($socket,$msg)
{
$msg = mask(json_encode($msg));
$this->send($socket,$this->msgEncode($msg),strlen($msg));
}
public function createHandshake($socked, $received_header, $cfg)
{
//var_dump($received_header);
echo '<pre>'.$received_header.'</pre>';
// read header
$headers = array();
$lines = preg_split("/\r\n/", $received_header); //preg_quote // $lines = preg_split("~".$cfg['header_sep']."~", $received_header); //preg_quote
foreach($lines as $line)
{
$line = chop($line);
if (preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
// write header
$sec_key = isset($headers['Sec-WebSocket-Key']) ? $headers['Sec-WebSocket-Key'] : '';
$accept_key = base64_encode(pack('H*', sha1($sec_key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); // $accept_key = base64_encode(sha1($sec_key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',true));
$a = 'Sec-WebSocket-Protocol';
$b = 'Sec-WebSocket-Extensions'; //permessage-deflate
$headers[$a] = 'chat';
$upgrade = array(
'HTTP/1.1 101 Web Socket Protocol Handshake',
'Upgrade: websocket',
'Connection: Upgrade',
'WebSocket-Origin: ' .$cfg['server']['host'],
'WebSocket-Location: ' .$cfg['server']['url'],
'Sec-WebSocket-Accept: '.$accept_key,
isset($headers[$a]) ? $a.':'.$headers[$a] : '',
//isset($headers[$b]) ? $b.':'.$headers[$b] : '', //no zip compress use
'',
'' );
$upgrade = implode($cfg['header_sep'], $upgrade);
return $upgrade;
}
public function serverCreate()
{
global $CHAT;
$cfg = $this->cfg['server'];
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or writeError("socket_create()",$socket);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1) or writeError("socket_set_option()",$socket);
socket_bind($socket, $cfg['host'], $cfg['port']) or writeError("socket_bind()",$socket);
socket_listen($socket, $cfg['max_conn']) or writeError("socket_listen()",$socket);
$this->master = $socket;
$this->sockets_db->insert($socket);
//socket_set_nonblock($socket);
echo "Server Started : ".date('Y-m-d H:i:s')."\n";
echo "<br>Master socket : ".$socket."\n";
echo "<br>Listening on : address = ".$cfg['host'].", port = ".$cfg['port']."\n\n";
}
public function connect($cfg)
{
global $REQ,$CHAT;
var_dump('WS::connect');
// global $sockets,$users;
$socket = socket_accept($this->master) or $this->writeError("socket_accept()"); //accept new socket
if ($socket)
{
$header = socket_read($socket, 1024) or $this->writeError("socket_read()",$socket); //read data sent by the socket
$msg = $this->createHandshake($socket, $header, $cfg); //perform websocket handshake
$this->send($socket, $msg, strlen($msg));
$this->sockets_db->insert($socket);
/*
var_dump($CHAT->rooms_db);
$room = $CHAT->rooms_db->rooms[1];
$data = array(
'room' => $room,
'list' => $CHAT->userList($room)
);
$new_msg = new classMessage;
$new_msg->type = 'userlist';
$new_msg->data = $data;
$msg = $this->msgEncode($new_msg);
$this->send($socket, $msg, strlen($msg));
*/
}
return false;
}
public function disconnect($socket)
{
global $CHAT;
var_dump('WS::disconnect',$socket);
// $user = $CHAT->userLogout($socket);
$this->sockets_db->delete($socket);
@socket_close($socket);
// return $socket;
}
public function disconnectAll()
{
var_dump('WS::disconnectAll');
foreach ($this->sockets_db->table as $socket)
{
@socket_close($socket);
}
@socket_close($this->master);
}
public function receive($socket,$buffer)
{
var_dump('WS::receive '.$socket,$buffer,$this->unmask($buffer));
// $user = $CHAT->findUserBy('socket',$socket);// if ($WS->receive($user, $buffer)==-999)// {$run = false;}
global $CHAT;
// $received_text = unmask($buffer); //unmask data //var_dump($received_text); // $msg = $this->msgDecode($received_text); //json decode
$msg = $this->msgDecode($buffer);
//var_dump($msg);
// if (is_object($msg) && isset($msg->type) && $msg->type=='stopserver')// {// return false;// }
$CHAT->receive($socket,$msg);
return true;
}
public function serverRestart()
{
$this->serverStop();
$this->run = true;
while($this->run)
{
$this->serverRun();
}
}
public function serverStop()
{
$this->run = false;
}
public function serverRun()
{
$write_null = null;
$except_null = null;
$changed = $this->sockets_db->table;
//var_dump($changed);
socket_select($changed,$write_null,$except_null,0,10);
foreach($changed as $socket)
{
if ($socket==$this->master)
{
$user = $this->connect($this->cfg);
}
else {
$bytes = @socket_recv($socket,$buffer,$this->cfg['server']['max_buffer'],0);
if ($bytes === false)
{
$this->writeError('');
$this->disconnect($socket);
}
elseif ($bytes==0)
{
$user = $this->disconnect($socket);
}
else {
$this->run = $this->receive($socket, $buffer);
}
}
}
}
}
$cfg = array(
'server' => array(
'host' => 'localhost', // host
'port' => '9000', // port
'name' => 'master', // user name
'psw' => 'master', // user psw
'max_conn' => 20,
// 'max_buffer' => 2048,
'max_buffer' => 4096,
'url' => ''
),
//'null' => NULL, //null var
'header_sep' => PHP_EOL ? PHP_EOL : "\r\n"
);
$CHAT = new classChat();
$WS = new classWebSocket($cfg);
//var_dump('table rooms_db', $WS->encode($CHAT->rooms_db->table));
//var_dump('table users_db', $WS->encode($CHAT->users_db->table));
var_dump('roomList', $WS->encode($CHAT->roomList()));
var_dump('userList', $WS->encode($CHAT->userList()));
//var_dump($WS->master);
//var_dump($WS->sockets_db->sockets);
//exit; die();
$WS->serverRestart();
$WS->disconnectAll();
echo '<hr>'.$MICRO->stop();
Ale zatim nevim, kde je problem. Pri delsi zprave mi to FF neumi nejak cist. JS kod k tomu mam tento, je to takovy chat.
var WS;
//
// init
WS = {}
WS.server_url = '';
WS.server_opt = null;
WS.conn = null;
WS.conn_close_timer = null;
WS.cmd = {};
WS.send_buff = [];
WS.close_buff = false;
//WS.send_timer = null;
WS.api = window.WebSocket;
WS.status = function(text) {writeStatus('WS ' + text);};
WS.error = function(text) {writeStatus('WS error ' + text);};
WS.messages = function(text) {writeMessages('WS message ' + text);};
WS.encode = function(obj) {return JSON.stringify(obj);}
WS.decode = function(str) {return JSON.parse(str);}
WS.onopen = function(event)
{
var i, li, key, msg;
WS.status('connection opened');
// CHAT.msgRender('conn_open');
CHAT.msgSend('join');
CHAT.msgSend('userlist');
if (WS.close_buff == true)
{
WS.conn.close();
return;
}
li = WS.send_buff.length;
if (li>0)
{
for (i=0;i<li;i++)
{
msg = WS.send_buff[i];
type = msg.type ? msg.type : '???';
WS.status('send ' + type);
WS.conn.send(WS.encode(msg));
}
}
};
WS.onclose = function(event)
{
WS.status('connection closed');
// CHAT.msgRender('conn_close');
WS.close_buff = false;
// if (WS.conn_close_timer!=null)
// {
// clearInterval(WS.conn_close_timer);
// }
//CHAT.status(CHAT.encode(CHAT.messages_db.table));
};
WS.onerror = function(event)
{
event = event || window.event;
WS.error(WS.encode(event.data || event));
};
WS.receiveMessage = function(event)
{
WS.status('receive');
//alert(123)
var msg, key;
event = event || window.event;
//pos = 9; // '{"type":"'.length+1;
msg = event && event.data ? (event.data!='' ? WS.decode(event.data) : '') : '';
CHAT.receive(msg);
};
//WS.key_func_rtc = {
// rtc : function(data) {PEER.receiveOfferAnsfer(data);}
// candidate: function() {},
// answer : function() {},
// offer : function() {}
// };
WS.construct = function(cfg)
{
WS.server_url = cfg.server_ex.url;
WS.server_opt = cfg.server_ex.opt;
};
WS.cmd.support = function()
{
var api;
api = 'WebSocked';
if (WS.api) {RTC.status(api+' supported');} else {RTC.error(api+' not supported');}
api = 'JSON';
if (JSON) {RTC.status(api+' supported');} else {RTC.error(api+' not supported');}
};
WS.cmd.connect = function()
{
// var query;
// query = 'name=' + CHAT.user.name + '&psw=' + CHAT.user.psw;
// if (WS.close_buff == true)
CHAT.userlist.clear();
CHAT.messages.clear();
WS.close_buff == false
WS.checkCloseTimer();
WS.status('connecting...');
// WS.conn = new WS.api(WS.server_url+'?'+query, WS.server_opt); // + CFG.server_ex.room
WS.conn = new WS.api(WS.server_url, WS.server_opt); // + CFG.server_ex.room
WS.conn.onopen = WS.onopen;
WS.conn.onclose = WS.onclose;
WS.conn.onerror = WS.onerror;
WS.conn.onmessage = WS.receiveMessage;
};
WS.checkCloseTimer = function()
{
if (WS.close_buff == true)
{
WS.conn_close_timer = setInterval(WS.tryConnClose,500);
}
else {
if (WS.conn_close_timer!=null)
{
clearInterval(WS.conn_close_timer);
WS.conn_close_timer = null;
}
}
}
WS.cmd.disconnect = function()
{
WS.tryConnClose();
WS.checkCloseTimer();
};
WS.cmd.send = function(msg)
{
var type = msg.type ? msg.type : '???';
if (WS.conn && WS.conn.readyState==1)
{
WS.status('send ' + type);
WS.conn.send(WS.encode(msg));
}
else {
WS.status('try send ' + type);
WS.send_buff[WS.send_buff.length] = msg;
}
};
//WS.cmd.sendText = function(text)
// {
// WS.cmd.send({type:'chat',key:'msg',data:{message:text}});
// }
WS.cmd.sendStop = function()
{
WS.cmd.send({
type:'stopserver',
data:''
}); //stop php socket server
}
WS.tryConnClose = function()
{
if (WS.conn && WS.conn.readyState==1) // if open
{
WS.status('close');
WS.conn.close(); // tohle nejak uplne nefunguje, odpoji to, az kdyz server nefakci
}
else {
WS.status('try close');
WS.close_buff = true;
}
}