IP messenger using websockets - php

I m trying to build an ip messenger for our college in php using websockets
with some success but when scaled to multiple users it failed .
It's throwing out the error that no socket resource was given in parameter for socket_select but that's not true .
also if somebody could properly explain the process of handshake in depth .thanking you in advance .Here's the code of the php server.
<?php
$host = ''//server ip;
echo $host;
$port = 9000;
if(!($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) )){
$errcode = socket_last_error();
$errormsg = socket_strerror($errcode);
die("couldn't create socket [$errcode]:$errormsg");
}
echo "successfully created the socket \n";
if(!socket_bind($sock, $host,$port)){
$errcode = socket_last_error();
$errormsg = socket_strerror($errcode);
die("couldn't bind socket to ip [$errcode]:$errormsg");
}
echo "successfully binded the socket to given ip\n";
if(!socket_listen($sock,10)){
$errcode = socket_last_error();
$errormsg = socket_strerror($errcode);
die("socket is deaf [$errcode]:$errormsg");
}
echo "socket started listening\n";
echo "waiting for incoming connections...\n";
$clients = array($sock);
$address_clients = array('127.0.0.1');
//start endless loop, so that our script doesn't stop
while (true) {
//manage multiple connections
$changed = $clients;
//returns the socket resources in $changed array
socket_select($changed, $null, $null, 0, 10);
//check for new socket
if (in_array($sock, $changed)) {
$socket_new = socket_accept($sock); //accept new socket
$clients[] = $socket_new; //add socket to client array
$found_socket = array_search($socket_new, $clients);
$header = socket_read($socket_new,1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
socket_getpeername($socket_new, $address,$port); //get ip address of connected socket
$address_clients[$found_socket] = $address;
echo "Client[$address] connected to us on port $port\n";
//make room for new socket
$found_socket = array_search($sock, $changed);
unset($changed[$found_socket]);
}
/*loop through all connected sockets*/
foreach($clients as $socketm){
//check for any incomming data
while(socket_recv($socketm, $buf, 1024, 0) >= 1)
{
$received_text = unmask($buf); //unmask data
$received = explode(',', $received_text);
echo $received[0]."\t".$received[1]."\n";
$found_socket = array_search($received[1], $address_clients);
echo $found_socket; //prepare data to be sent to client
socket_write($clients[$found_socket], mask($received[0]),strlen(mask($received[0])));
break 2; //exit this loop
}
$buf = #socket_read($socketm, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
$found_socket = array_search($socketm, $clients);
socket_getpeername($socketm, $address);
unset($clients[$found_socket]);
echo "Client[$address] disconnected\n";
}
}
}
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-
C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
return $upgrade;
}
function unmask($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;
}
?>
I m actually trying to build a better and more useful social network than facebook(no adds ,no cookies).i am using websockets instead of traditional php,ajax,sql(long -polling ) which is much slower.any help will be greatly appreciated :)

Posting my answer if anybody in the future wants to work with websockets .I hope my answer will help them a lot saving a hard googling time .
<?php
$a = #$_SERVER['SERVER_ADDR'];
$host = $a;
$port = 9000;
if(!($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) )){
$errcode = socket_last_error();
$errormsg = socket_strerror($errcode);
die("couldn't create socket [$errcode]:$errormsg");
}
echo "successfully created the socket \n";
if(!socket_bind($sock, $host,$port)){
$errcode = socket_last_error();
$errormsg = socket_strerror($errcode);
die("couldn't bind socket to ip [$errcode]:$errormsg");
}
echo "successfully binded the socket to given ip\n";
if(!socket_listen($sock,10)){
$errcode = socket_last_error();
$errormsg = socket_strerror($errcode);
die("socket is deaf [$errcode]:$errormsg");
}
echo "socket started listening\n";
echo "waiting for incoming connections...\n";
$clients = array($sock);
$address_clients = array('127.0.0.1');
//start endless loop, so that our script doesn't stop
while (true) {
//manage multiple connections
$changed = $clients;
//returns the socket resources in $changed array
socket_select($changed, $null, $null, 0);
//check for new socket
if (in_array($sock, $changed)) {
$socket_new = socket_accept($sock); //accept new socket
$clients[] = $socket_new; //add socket to client array
$found_socket = array_search($socket_new, $clients);
$header = socket_read($socket_new,1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
socket_getpeername($socket_new, $address,$port); //get ip address of connected socket
$address_clients[$found_socket] = $address;
$found_socket = array_search($sock, $changed);
echo "Client[$address] connected to us on port $port\n";
//make room for new socket
unset($changed[$found_socket]);
for($i=1;$i<count($clients);$i++) {
$message = "Client[$address] connected to us on port $port\n";
socket_write($clients[$i], mask($message),strlen(mask($message)));
}
}
//loop through all connected sockets
foreach($changed as $changed_socket){
//check for any incomming data
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
$received_text = unmask($buf); //unmask data
$received = explode(',', $received_text);
echo $received[0]."\t".$received[1]."\n";
$found_socket = array_search($received[1], $address_clients);
echo $found_socket; //prepare data to be sent to client
socket_write($clients[$found_socket], mask($received[0]),strlen(mask($received[0])));
break 2; //exit this loop
}
$buf = #socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($clients[$found_socket], $address);
unset($clients[$found_socket]);
echo "Client[$address] disconnected\n";
}
}
}
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
return $upgrade;
}
function unmask($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;
}
?>

Related

No such host is known in my PHP socket project

Good day, I am really having a hard time to this PHP when running it. Can you please check the error? Thank you
<?php
define('HOST_NAME',"localhost");
// define('HOST_NAME',"192.168.43.49");
define('PORT',"2306");
$null = NULL;
class _sHandler {
function send($message) {
global $clientSocketArray;
$messageLength = strlen($message);
foreach($clientSocketArray as $clientSocket)
{
#socket_write($clientSocket,$message,$messageLength);
}
return true;
}
function unseal($socketData) {
$length = ord($socketData[1]) & 127;
if($length == 126) {
$masks = substr($socketData, 4, 4);
$data = substr($socketData, 8);
}
elseif($length == 127) {
$masks = substr($socketData, 10, 4);
$data = substr($socketData, 14);
}
else {
$masks = substr($socketData, 2, 4);
$data = substr($socketData, 6);
}
$socketData = "";
for ($i = 0; $i < strlen($data); ++$i) {
$socketData .= $data[$i] ^ $masks[$i%4];
}
return $socketData;
}
function seal($socketData) {
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($socketData);
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.$socketData;
}
function doHandshake($received_header,$client_socket_resource, $host_name, $port) {
$headers = array();
$lines = preg_split("/\r\n/", $received_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$buffer = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host_name\r\n" .
"WebSocket-Location: ws://$host_name:$port/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_socket_resource,$buffer,strlen($buffer));
}
function newConnectionACK($client_ip_address) {
$message = 'New client ' . $client_ip_address.' joined';
$messageArray = array('connection_message'=>$message,'connection_message_type'=>'chat-connection-ack');
$ACK = $this->seal(json_encode($messageArray));
return $ACK;
}
function connectionDisconnectACK($client_ip_address) {
$message = 'Client ' . $client_ip_address.' disconnected';
$messageArray = array('message'=>$message,'message_type'=>'chat-connection-ack');
$ACK = $this->seal(json_encode($messageArray));
return $ACK;
}
}
$_sHandler = new _sHandler();
$socketResource = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($socketResource, 0, PORT);
socket_listen($socketResource);
$clientSocketArray = array($socketResource);
while (true) {
$newSocketArray = $clientSocketArray;
socket_select($newSocketArray, $null, $null, 0, 10);
if (in_array($socketResource, $newSocketArray)) {
$newSocket = socket_accept($socketResource);
$clientSocketArray[] = $newSocket;
$header = socket_read($newSocket, 1024);
$_sHandler->doHandshake($header, $newSocket, HOST_NAME, PORT);
socket_getpeername($newSocket, $client_ip_address);
$connectionACK = $_sHandler->newConnectionACK($client_ip_address);
$_sHandler->send($connectionACK);
$newSocketIndex = array_search($socketResource, $newSocketArray);
unset($newSocketArray[$newSocketIndex]);
}
foreach ($newSocketArray as $newSocketArrayResource) {
while(socket_recv($newSocketArrayResource, $socketData, 1024, 0) >= 1){
$socketMessage = $_sHandler->unseal($socketData);
$messageObj = json_decode($socketMessage);
$_sHandler->send($_sHandler->seal(json_encode($messageObj)));
break 2;
}
$socketData = #socket_read($newSocketArrayResource, 1024, PHP_NORMAL_READ);
if ($socketData === false) {
socket_getpeername($newSocketArrayResource, $client_ip_address);
// $connectionACK = $_sHandler->connectionDisconnectACK($client_ip_address);
$_sHandler->send($connectionACK);
$newSocketIndex = array_search($newSocketArrayResource, $clientSocketArray);
unset($clientSocketArray[$newSocketIndex]);
}
}
}
socket_close($socketResource);
I tried to run it on my end but I received this error
PHP Warning: socket_bind(): Host lookup failed [11001]: No such host is known in C:\xampp\htdocs\queuing\php-sockets.php on line 94
Warning: socket_bind(): Host lookup failed [11001]: No such host is known in C:\xampp\htdocs\queuing\php-sockets.php on line 94
Warning: socket_listen(): unable to listen on socket [10022]: An invalid argument was supplied in C:\xampp\htdocs\queuing\php-sockets.php on line 95
PHP Warning: socket_listen(): unable to listen on socket [10022]: An invalid argument was supplied in C:\xampp\htdocs\queuing\php-sockets.php on line 95

Secure Websockets in php - how to add certificate to script

I'm trying to understand websockets. I have found excelent example on https://phppot.com/php/simple-php-chat-using-websocket/.
But got stuck implementing certificate to use it on wss. The example is based on socket_create() but to socket_set_option() certificate doesnt fit and i din't find how to combine that with stream_context_set_option() or stream_sockte_.... Is socket part of a stream? Am I missing something else.
Sorry not experienced in websockets nor ssl connection... I have googled for almost 2, days and not moved forward... Thank you for anything, that shifts me forward...
how can I combine
define('HOST_NAME',"localhost");
define('PORT',"8090");
$null = NULL;
require_once("class.chathandler.php");
$chatHandler = new ChatHandler();
$socketResource = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($socketResource, 0, PORT);
socket_listen($socketResource);
//with
$opts = array(
'http'=>array(
'local_cert'=>'/usr/local/etc/apache224/ssl.crt/www.mojehra.cz.crt',
'local_pk'=>'/usr/local/etc/apache224/ssl.key/www.mojehra.cz.key'
)
);
$context = stream_context_create($opts);
The full original example is below.
<?php
define('HOST_NAME',"localhost");
define('PORT',"8090");
$null = NULL;
require_once("class.chathandler.php");
$chatHandler = new ChatHandler();
$socketResource = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($socketResource, 0, PORT);
socket_listen($socketResource);
$clientSocketArray = array($socketResource);
while (true) {
$newSocketArray = $clientSocketArray;
socket_select($newSocketArray, $null, $null, 0, 10);
if (in_array($socketResource, $newSocketArray)) {
$newSocket = socket_accept($socketResource);
$clientSocketArray[] = $newSocket;
$header = socket_read($newSocket, 1024);
$chatHandler->doHandshake($header, $newSocket, HOST_NAME, PORT);
socket_getpeername($newSocket, $client_ip_address);
$connectionACK = $chatHandler->newConnectionACK($client_ip_address);
$chatHandler->send($connectionACK);
$newSocketIndex = array_search($socketResource, $newSocketArray);
unset($newSocketArray[$newSocketIndex]);
}
foreach ($newSocketArray as $newSocketArrayResource) {
while(socket_recv($newSocketArrayResource, $socketData, 1024, 0) >= 1){
$socketMessage = $chatHandler->unseal($socketData);
$messageObj = json_decode($socketMessage);
$chat_box_message = $chatHandler->createChatBoxMessage($messageObj->chat_user, $messageObj->chat_message);
$chatHandler->send($chat_box_message);
break 2;
}
$socketData = #socket_read($newSocketArrayResource, 1024, PHP_NORMAL_READ);
if ($socketData === false) {
socket_getpeername($newSocketArrayResource, $client_ip_address);
$connectionACK = $chatHandler->connectionDisconnectACK($client_ip_address);
$chatHandler->send($connectionACK);
$newSocketIndex = array_search($newSocketArrayResource, $clientSocketArray);
unset($clientSocketArray[$newSocketIndex]);
}
}
}
socket_close($socketResource);
?>
class
<?php
class ChatHandler {
function send($message) {
global $clientSocketArray;
$messageLength = strlen($message);
foreach($clientSocketArray as $clientSocket)
{
#socket_write($clientSocket,$message,$messageLength);
}
return true;
}
function unseal($socketData) {
$length = ord($socketData[1]) & 127;
if($length == 126) {
$masks = substr($socketData, 4, 4);
$data = substr($socketData, 8);
}
elseif($length == 127) {
$masks = substr($socketData, 10, 4);
$data = substr($socketData, 14);
}
else {
$masks = substr($socketData, 2, 4);
$data = substr($socketData, 6);
}
$socketData = "";
for ($i = 0; $i < strlen($data); ++$i) {
$socketData .= $data[$i] ^ $masks[$i%4];
}
return $socketData;
}
function seal($socketData) {
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($socketData);
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.$socketData;
}
function doHandshake($received_header,$client_socket_resource, $host_name, $port) {
$headers = array();
$lines = preg_split("/\r\n/", $received_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
{
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
$buffer = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host_name\r\n" .
"WebSocket-Location: ws://$host_name:$port/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_socket_resource,$buffer,strlen($buffer));
}
function newConnectionACK($client_ip_address) {
$message = 'New client ' . $client_ip_address.' joined';
$messageArray = array('message'=>$message,'message_type'=>'chat-connection-ack');
$ACK = $this->seal(json_encode($messageArray));
return $ACK;
}
function connectionDisconnectACK($client_ip_address) {
$message = 'Client ' . $client_ip_address.' disconnected';
$messageArray = array('message'=>$message,'message_type'=>'chat-connection-ack');
$ACK = $this->seal(json_encode($messageArray));
return $ACK;
}
function createChatBoxMessage($chat_user,$chat_box_message) {
$message = $chat_user . ": <div class='chat-box-message'>" . $chat_box_message . "</div>";
$messageArray = array('message'=>$message,'message_type'=>'chat-box-html');
$chatMessage = $this->seal(json_encode($messageArray));
return $chatMessage;
}
}
?>
The author did not reply.
I can't see where you actualy use $context . You should probably use stream_socket_server to create your master sockett and use $context.
Have a look at https://github.com/napengam/phpWebSocketServer/blob/master/server/webSocketServer.php
on how to use all this.

issue in web-socket php

I have used WebSocket in PHP. but somehow it will close after some time(so many requests).
Is it anyway to handle it?
We got following error when we try to run it after stop:
socket_bind(): unable to bind address [10013]: An attempt was made to
access a socket in a way forbidden by its access permissions.
in C:\wamp64\www\Websocket\server.php on line 52
Warning: socket_listen(): unable to listen on socket [10022]: An invalid argument was supplied.
in C:\wamp64\www\Websocket\server.php on line 55
Here is my code:
<?php
set_time_limit(0);
error_reporting(E_ALL);
//include 'Triangulate.php';
$filename = 'logs.txt';
class Values
{
public $distance;
public $rasp_id;
public $rssi;
}
$host = '10.37.54.167'; //host
$port = '9000'; //port
$null = null; //null var
$rasp = array(
47 => array(17, 0),
124 => array(1,6.4),
43 => array(1,0),
44 => array(4.6,2));
//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//bind socket to specified host
socket_bind($socket, 0, $port);
//listen to port
socket_listen($socket);
//create & add listning socket to the list
$clients = array($socket);
$distance = array();
$totalbicken = array(array());
//start endless loop, so that our script doesn't stop
while (true) {
//manage multipal connections
$changed = $clients;
//returns the socket resources in $changed array
socket_select($changed, $null, $null, 0, 10);
$fp = fopen($filename, 'a+');
//check for new socket
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); //accpet new socket
$clients[] = $socket_new; //add socket to client array
$header = socket_read($socket_new, 1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
socket_getpeername($socket_new, $ip); //get ip address of connected socket
$response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' connected'))); //prepare json data
fwrite ($fp,$response . "\n");
// send_message($response); //notify all users about new connection
// send_message_socket($response, $socket_new);
//make room for new socket
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
}
//loop through all connected sockets
foreach ($changed as $changed_socket) {
//check for any incomming data
try {
while (socket_recv($changed_socket, $buf, 1024, 0) >= 1) {
$received_text = unmask($buf); //Unmask Recive data.
fwrite ($fp,"Text receive:" . $received_text . "\n");
$tst_msg = json_decode($received_text); //json decode.
fwrite ($fp,"Json Decord!". "\n");
if (!isset($tst_msg->action)) {
} else {
$user_action = $tst_msg->action; //sender name.
if ($user_action == "distance") { //If action is distance.
$rasp_id = $tst_msg->rasp_id; //get raspberry uniq id.
$beacon_id = $tst_msg->beacon_id; //get beacon id
$distance_temp = $tst_msg->distance; // get distance
$rssi = $tst_msg->rssi; //get RSSI.
fwrite ($fp,isset($distance[$beacon_id]). "\n");
fwrite ($fp,"Get all values!". "\n");
// echo mask(json_encode(array('type'=>'message', 'action'=>'distance', 'beacon_id'=>$beacon_id, 'rasp_id'=>$rasp_id, 'distance'=>$distance)));
if (isset($distance[$beacon_id])) {
$totalbicken[$beacon_id] = count($distance[$beacon_id]); //get total distance of sender beacon
} else {
$totalbicken[$beacon_id] = 0;
}
if (isset($rasp[$rasp_id])) {
echo "\nRequest from: " . $rasp_id;
$myVal = new Values();
$myVal->distance = $distance_temp;
$myVal->rasp_id = $rasp_id;
$myVal->rssi = $rssi;
$flag = false;
if (isset($distance[$beacon_id])) {
if (count($distance[$beacon_id]) > 0) {
for ($i = 0; $i < count($distance[$beacon_id]); $i++) {
$myTempVal = $distance[$beacon_id][$i];
if (($myTempVal->rasp_id) == $rasp_id) {
$flag = true;
$distance[$beacon_id][$i] = $myVal;
break;
}
}
if (!$flag) {
$distance[$beacon_id][$totalbicken[$beacon_id]] = $myVal;
}
} else {
$distance[$beacon_id][$totalbicken[$beacon_id]] = $myVal;
}
} else {
$distance[$beacon_id][$totalbicken[$beacon_id]] = $myVal;
}
if (count($distance[$beacon_id]) > 2) {
/*$data = triangulate($rasp[$distance[$beacon_id][0]->rasp_id], $distance[$beacon_id][0]->distance,
$rasp[$distance[$beacon_id][1]->rasp_id], $distance[$beacon_id][1]->distance,
$rasp[$distance[$beacon_id][2]->rasp_id], $distance[$beacon_id][2]->distance);*/
fwrite ($fp,"Before Triangulation!". "\n");
$data = getTrilateration($rasp[$distance[$beacon_id][0]->rasp_id], $distance[$beacon_id][0]->distance,
$rasp[$distance[$beacon_id][1]->rasp_id], $distance[$beacon_id][1]->distance,
$rasp[$distance[$beacon_id][2]->rasp_id], $distance[$beacon_id][2]->distance);
fwrite ($fp,"End Triangulation!". "\n");
$response_text = mask(json_encode(array('type' => 'message', 'action' => 'distance',
'beacon_id' => $beacon_id, 'distance' => $distance[$beacon_id], 'coordinates' => $data)));
fwrite ($fp,"Response: ". $response_text . "\n");
send_message($response_text);
}
}
}
fwrite ($fp,"Break!: ". "\n");
break 2; //exist this loop*/
}
}
} catch (Exception $e) {
fwrite ($fp,"Exception: done! \n");
fwrite ($fp,"Exception: ". $e->getMessage(). "\n");
echo "Exception:" . $e->getMessage();
}
$buf = #socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
try {
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);
//notify all users about disconnected connection
$response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' disconnected')));
send_message($response);
} catch (Exception $e) {
echo "Exception:" . $e;
}
}
}
}
// close the listening socket
socket_close($socket);
$fclose ($fp);
function send_message($msg)
{
global $clients;
foreach ($clients as $changed_socket) {
#socket_write($changed_socket, $msg, strlen($msg));
}
return true;
}
function send_message_socket($msg, $changed_socket)
{
#socket_write($changed_socket, $msg, strlen($msg));
return true;
}
//Unmask incoming framed message
function unmask($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;
}
//handshake new client.
function perform_handshaking($receved_header, $client_conn, $host, $port)
{
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach ($lines as $line) {
$line = chop($line);
if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/Websocket/shout.php\r\n" .
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn, $upgrade, strlen($upgrade));
}
Thanks in advance!
I have setup Linux environment and test. It is working fine. It might a firewall issue in windows.
As per my knowledge, the newer version of windows (after service pack-3) has some of the RPC rules for connection (Limit of HTTP requests and connection in second) so, that might be an issue.
Please read this.
As of now, change the operating system is the one of a solution.
Thanks & Regards
Jignesh M. Mehta

My PHP Socket Server keeps shutting down on Windows Server

I started a PHP Socket server on Windows Server 2012 R2 by running the command: php -q C:\path\to\server.php. The problem that I have is that after several hours the server I am not able to connect in JavaScript. I have done hours of researching to figure this about, but since there is no errors I don't know what to search. My only thought is that it may shutdown from inactivity.
<?php
set_time_limit(0);
$host = '10.18.8.7'; //host
$port = '9000'; //port
$null = NULL; //null var
//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//bind socket to specified host
socket_bind($socket, 0, $port);
//listen to port
socket_listen($socket);
//create & add listning socket to the list
$clients = array($socket);
//start endless loop, so that our script doesn't stop
while (#file_get_contents('shutdown.txt') == 1) {
$messages = #file_get_contents('C:\\Public\\messages.json');
if($messages !== FALSE && $messages != "" && $messages != "[]") {
$json = json_decode($messages);
send_message(mask(json_encode(array('type'=>$json->type, 'message'=>$json->message, 'for'=>$json->for, 'permissions'=>$json->permissions))));
file_put_contents('C:\\Public\\messages.json', "");
}
//manage multipal connections
$changed = $clients;
//returns the socket resources in $changed array
socket_select($changed, $null, $null, 0, 10);
//check for new socket
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); //accpet new socket
$clients[] = $socket_new; //add socket to client array
$header = socket_read($socket_new, 1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
socket_getpeername($socket_new, $ip); //get ip address of connected socket
$response = mask(json_encode(array('type'=>'1', 'message'=>$ip.' connected'))); //prepare json data
send_message($response); //notify all users about new connection
//make room for new socket
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
}
//loop through all connected sockets
foreach ($changed as $changed_socket) {
//check for any incomming data
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1) {
$received_text = unmask($buf); //unmask data
$tst_msg = json_decode($received_text); //json decode
//DO STUFF WITH DATA
break 2; //exits this loop
}
$buf = #socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);
//notify all users about disconnected connection
$response = mask(json_encode(array('type'=>'1', 'message'=>$ip.' disconnected')));
send_message($response);
}
}
}
// close the listening socket
socket_close($socket);
function send_message($msg) {
global $clients;
foreach($clients as $changed_socket) {
#socket_write($changed_socket,$msg,strlen($msg));
}
return true;
}
//Unmask incoming framed message
function unmask($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;
}
//handshake new client.
function perform_handshaking($receved_header,$client_conn, $host, $port) {
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach($lines as $line)
{
$line = chop($line);
if(preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
}
?>
Any thoughts or suggestions would be appreciated.
Edit
I have run the commands in Windows Powershell, but I also have a PHP page that executes the command.

Warning: socket_recv(): unable to read from socket [0]: Operation complete

I have five clients connected to my php socket, with html5 javascript.
Sometimes the php socket gives this error, and doubles the messages to the clients, for some strange reason:
Warning: socket_recv(): unable to read from socket [0]: Operation complete
How can I fix this trouble?
This is the full code:
<?php
$host = '192.168.0.201'; //host
$port = '9000'; //port
$null = NULL; //null var
//Create TCP/IP sream socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//reuseable port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//bind socket to specified host
socket_bind($socket, $host, $port);
//listen to port
socket_listen($socket);
//create & add listning socket to the list
$clients = array($socket);
//start endless loop, so that our script doesn't stop
while (true) {
//manage multipal connections
$changed = $clients;
//returns the socket resources in $changed array
socket_select($changed, $null, $null, 0, 10);
//check for new socket
if (in_array($socket, $changed)) {
$socket_new = socket_accept($socket); //accpet new socket
$clients[] = $socket_new; //add socket to client array
$header = socket_read($socket_new, 1024); //read data sent by the socket
perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake
socket_getpeername($socket_new, $ip); //get ip address of connected socket
//$response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' connected'))); //prepare json data
//send_message($response); //notify all users about new connection
//make room for new socket
$found_socket = array_search($socket, $changed);
unset($changed[$found_socket]);
}
//loop through all connected sockets
foreach ($changed as $changed_socket) {
//check for any incomming data
while (socket_recv($changed_socket, $buf, 1024, 0) >= 1) {
echo $buf;
$received_text = unmask($buf); //unmask data
$tst_msg = json_decode($received_text); //json decode
$user_message = $tst_msg; //message text
//prepare data to be sent to client
$response_text = mask(json_encode($user_message));
send_message($response_text); //send data
break 2; //exist this loop
}
$buf = #socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for $clients array
$found_socket = array_search($changed_socket, $clients);
socket_getpeername($changed_socket, $ip);
unset($clients[$found_socket]);
//notify all users about disconnected connection
//$response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' disconnected')));
//send_message($response);
}
}
}
// close the listening socket
socket_close($sock);
function send_message($msg) {
global $clients;
foreach ($clients as $changed_socket) {
#socket_write($changed_socket, $msg, strlen($msg));
}
return true;
}
//Unmask incoming framed message
function unmask($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;
}
//handshake new client.
function perform_handshaking($receved_header, $client_conn, $host, $port) {
$headers = array();
$lines = preg_split("/\r\n/", $receved_header);
foreach ($lines as $line) {
$line = chop($line);
if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
$headers[$matches[1]] = $matches[2];
}
}
$secKey = $headers['Sec-WebSocket-Key'];
$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
//hand shaking header
$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
"Upgrade: websocket\r\n" .
"Connection: Upgrade\r\n" .
"WebSocket-Origin: $host\r\n" .
"WebSocket-Location: ws://$host:$port/demo/shout.php\r\n" .
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn, $upgrade, strlen($upgrade));
}
Thank you in advance.
change like this
foreach ($changed as $changed_socket) {
//check for any incomming data
while (socket_recv($changed_socket, $buf, 1024, 0) >= 1) {...
with
foreach ($changed as $changed_socket) {
//check for any incomming data
$bytesocket=#socket_recv($changed_socket, $buf, 1024, 0);
while ($bytesocket >= 1) {....
this occurs when the client crash. In this situation the return of socket_recv() is false, use === operator to check.
On client normal exit the return is 0.
You can simulate both situations using Putty. Once connected to your server try:
kill with task manager (return false)
Exit normally (return 0)
Always use socket_close after client close or crash

Categories