Websockets and https wont connect when using wss:// - javascript

i am creating a php web chat app for my site, it is built in php and js html, it works fine (with some minor annoyances and needing updates) when it is used over http (in secure connections) but when i use https it asked about loading unsafe scripts (the main js for the system) which i dont want, i have tried to change it to wss:// but now i dont get any connection now, there is two main parts to the site the page and the server, the page is as follows
<style type="text/css">
<!--
.chat_wrapper {
width: 100%;
height: 100%;
margin-right: auto;
margin-left: auto;
background: #CCCCCC;
border: 1px solid #999999;
padding: 10px;
font: 12px 'lucida grande',tahoma,verdana,arial,sans-serif;
}
.chat_wrapper .message_box {
background: #FFFFFF;
height: 380px;
overflow: scroll;
padding: 10px;
border: 1px solid #999999;
}
.chat_wrapper .panel input{
padding: 2px 2px 2px 5px;
}
.system_msg{color: #BDBDBD;font-style: italic;}
.user_name{font-weight:bold;}
.user_message{color: #88B6E0;}
-->
</style>
<?php
$colours = array('007AFF','FF7000','FF7000','15E25F','CFC700','CFC700','CF1100','CF00BE','F00');
$user_colour = array_rand($colours);
?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$("#message").keyup(function(event){
if(event.keyCode == 13){
$("#send-btn").click();
}
});
//create a new WebSocket object.
var wsUri = "ws://radiobeacononline.com:9000/server.php";
websocket = new WebSocket(wsUri);
websocket.onopen = function(ev) { // connection is open
var myname = $('#name').val(); //get user name
var mypic = $('#pic').val();
var msg = {
message: 'has just joined the chat',
name: myname,
pic : mypic,
color : '<?php echo $colours[$user_colour]; ?>'
};
//convert and send data to server
websocket.send(JSON.stringify(msg));
$('#message_box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
}
$('#send-btn').click(function(){ //use clicks message send button
var mymessage = $('#message').val(); //get message text
var myname = $('#name').val(); //get user name
if(mymessage == ""){ //emtpy message?
alert("Enter Some message Please!");
return;
}
var mypic = $('#pic').val();
//prepare json data
var msg = {
//type : 'mesage',
message: mymessage,
name: myname,
pic : mypic,
color : '<?php echo $colours[$user_colour]; ?>'
};
//convert and send data to server
websocket.send(JSON.stringify(msg));
});
//#### Message received from server?
websocket.onmessage = function(ev) {
var msg = JSON.parse(ev.data); //PHP sends Json data
var type = msg.type; //message type
var umsg = msg.message; //message text
var uname = msg.name; //user name
var upic = msg.pic // user pic
var ucolor = msg.color; //color
if(type == 'usermsg')
{
$('#message_box').append("<div><span class=\"user_name\" style=\"color:#"+ucolor+"\"><img src=\"app/engine/storage/users/"+uname+"/profile/"+upic+"\" width=\"23\" height=\"23\">"+uname+"</span> : <span class=\"user_message\">"+umsg+"</span></div>");
}
if(type == 'system')
{
$('#message_box').append("<div class=\"system_msg\">"+umsg+"</div>");
}
$('#message').val(''); //reset text
};
window.setInterval(function() {
var elem = document.getElementById('message_box');
elem.scrollTop = elem.scrollHeight;
}, 500);
websocket.onerror = function(ev){$('#message_box').append("<div class=\"system_error\">Error Occurred - "+ev.data+"</div>");};
websocket.onclose = function(ev){$('#message_box').append("<div class=\"system_msg\">Connection Closed</div>");};
});
</script>
<div class="chat_wrapper">
<div class="message_box" id="message_box"></div>
<div class="panel">
<input type="text" name="name" hidden="" id="name" value="<?= fSession::get('user_name')?>" maxlength="10" style="width:20%" />
<input type="text" name="pic" hidden="" id="pic" value="<?= fSession::get('user_photo')?>" maxlength="10" style="width:20%" />
<div class="input-group">
<span class="input-group-addon" id="basic-addon3"><?= fSession::get('user_name')?></span>
<input type="text" class="form-control" id="message" aria-describedby="basic-addon3" placeholder="Message" maxlength="80">
</div>
<button class="btn btn-default form-inline" id="send-btn">Send</button>
</div>
</div>
and the server is as follows
<?php
$host = 'radiobeacononline.com'; //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 (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'=>'A user has joined connected'))); //prepare json data
//send_message($response); //notify all users about new connection
$time = time();
$file = fopen('app/engine/storage/writeable/logs/chat.log','a+');
fwrite($file,"system: $ip connected $time \r\n");
fclose($file);
//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
// if($tst_msg->type == message)
// {
// what it says below
// elseif($tst_msg->type == system)
// {
// do a system update this will be if the user is online or not.
// this will need a lot fo work on it to make sure that they are.
// }
// elseif($tst_msg->type == users)
// {
// update user list.
// }
// elseif($tst_msg->type == ping)
// {
// do ping stuff.
// }
// elseif($tst_msg->type == pong)
// {
// do pong stuff
// }
$user_name = $tst_msg->name; //sender name
$user_message = $tst_msg->message; //message text
$user_color = $tst_msg->color; //color
$user_pic = $tst_msg->pic; //color
$time = time();
//prepare data to be sent to client
$response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color, 'pic'=>$user_pic)));
send_message($response_text); //send data
$file = fopen('app/engine/storage/writeable/logs/chat.log','a+');
fwrite($file,"usermsg $user_name : $user_message $time \r\n");
fclose($file);
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]);
$time = time();
//notify all users about disconnected connection
$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));
send_message($response);
$file = fopen('app/engine/storage/writeable/logs/chat.log','a+');
fwrite($file,"system $ip disconected $time \r\n");
fclose($file);
}
}
}
// 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: wss://$host:$port/demo/shout.php\r\n".
"Sec-WebSocket-Accept:$secAccept\r\n\r\n";
socket_write($client_conn,$upgrade,strlen($upgrade));
}
this works fine in http but does not work in https is there anybody out there that can help with this and make it work on a https system with out having to click something that will allow it after saying unsafe on it?

Obviously that would never work over SSL, because your code doesn't support SSL. You're just opening a raw socket and sending/receiving over an unsecured socket. SSL takes place as a layer of security, on top of the socket layer, hence the name SSL. You can't downgrade from a page loaded over a secured connection to loading resources over an insecure connection. The browser simply won't allow that is it defeats the purposes of using a secure connection.
The simple fix is to place a reverse proxy infront of your websocket server that supports SSL and have the SSL termination happen at the proxy level. HAProxy is one such reverse proxy that can support websockets.
The more complicated fix, which is far too broad to explain in detail here, is to actually do the SSL termination at your application level (i.e. in PHP). This part would require a tremendous amount of research and effort on your part and I really wouldn't suggest it if you're just starting out learning about these things.

Related

PHP script, that's called from AJAX, return value doesn't show up all the time

Here is the premise of what I'm doing:
I have a program running in the background, a socket server, at all times.
I created a website that calls a php script (using AJAX) that opens a client side socket, connects to the server, sends the request and receives it, then echos it out.
This echo is the response is the 'return value' for my AJAX script.
This is this issue:
When I click a button, the information sends but, sometimes, the information never makes it back to the site.
I know the request is being processed through the server because I can see the request running to completion on the server side.
I know that the information from the server side is sending to the client (the website) because I have a code that checks if data was successfully sent from the server side.
Sometimes the request is sent through and the appropriate response client side (an alert pop-up with information from the server) comes through.
Website Code:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
<input type="submit" class="button" name="weather" value="weather" />
<input type="submit" class="button" name="time" value="time" />
<input type="submit" class="button" name="date" value="date" />
</form>
jQuery Code:
$(document).ready(function(){
$('.button').click(function(){
var clickBtnValue = $(this).val();
var ajaxurl = 'php/portserverclient.php',
dataSend = {'action': clickBtnValue};
$.post(ajaxurl, dataSend, function (response) {
// Response div goes here.
//$('#servermessage').val($('#servermessage').val()+response);
alert(response);
});
});
PHP Code:
<?php
// -------------------------------------
// ----- Get Information Sent from Site
// -------------------------------------
if (isset($_POST['action']))
{
switch ($_POST['action']) {
case 'weather':
$in = "3";
$request = "Weather";
break;
case 'time':
$in = "2";
$request = "Time";
break;
case 'date':
$in = "1";
$request = "Date";
}
}
else
{
$in = "3";
$request = "Weather";
}
// -------------------------------------
// ----- Open Client Side Socket
// -------------------------------------
error_reporting(E_ALL);
$A1 = "Starting TCP/IP Connection... \n";
/* Get the port for the WWW service. */
$service_port = 51713;
/* Get the IP address for the target host. */
$address = '192.168.8.129';
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if ($socket === false)
{
$A2 = "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
exit;
}
else {
$A2 = "Socket Created...OK.\n";
}
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 5, 'usec' => 0));
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 5, 'usec' => 0));
$A3 = "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false)
{
$A4 = "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
exit;
}
else
{
$A4 = "OK.\n";
}
// -------------------------------------
// ----- Send message through socket
// -------------------------------------
$A5 = "Sending $request request...";
$sent = socket_write($socket, $in, strlen($in));
$A6 = "OK.\n";
// -------------------------------------
// ----- Receive response through socket
// -------------------------------------
$out = ' ';
do{$out = socket_read($socket, 20, PHP_NORMAL_READ) ;}
while($out === false);
// -------------------------------------
// ----- Close Client Side Socket
// -------------------------------------
$A7 = "Closing socket...";
$A8 = "OK.\n";
echo "\n From PHP END: ", $A1,$A2,$A3,$A4,$A5,$A6,$A7,$A8,"Message: ", $out,"\n";
socket_shutdown($socket,2);
socket_close($socket);
exit;
?>
C++ Server Side Code:
//---- read buffer ---
sizeofread = read(newsockfd, msg, 20);
if (sizeofread <= 0 || msg[0] == 0x0A || msg[0] == 0x0D || msg[0] == 0x00)
{
// Stops any buggy send (size of read <= 0)
// Stops terminal from sending new line (0x0A & 0x0D) after each press enter
// Stops terminal from sending 0 constantly (0x00)
}
else
{
printf("Received from TCP: %s \n",msg);
//--- Send to Arduino ---
printf( "Sending to Arduino: %s \n", msg);
write( uartt, msg, 20 );
delay(50); // Here to account for how long it takes to send & receive 20 bytes at 9600 Baud
//--- Receive from Arduino ---
while (counter <= 2 && found == false)
{
if ( !( msgLength = serialDataAvail(uartt) ))
{
printf("Nothing to read \n");
delay(1071); // Here to account for how long it takes to receive 1024 bytes at 9600 Baud
counter++;
}
else
{
found = true;
read(uartt, msg, msgLength);
msg[msgLength] = 0;
if (write(newsockfd, msg, 20) < 0)
{
printf("Failed to send to socket \n");
}
else
{
printf("Succesfully sent to socket \n");
}
printf("From the Arduino: ");
printf("%s \n", msg);
}
delay(100);
serialFlush(uartt);
}
counter = 0;
found = false;
close(newsockfd);
goto repeat;
}
Turns out the answer to this riddle was that I needed to disable the Submit buttons default event. Normally, in HTML, the submit button refreshes the page, this must be stopped.
It was stopped like this:
$('.button').click(function(event){
var clickBtnValue = $(this).val();
var ajaxurl = 'php/portserverclient.php',
dataSend = {'action': clickBtnValue};
$.post(ajaxurl, dataSend, function (response) {
alert(response);
});
event.preventDefault();
});
Thanks guys

Time spent by user on webpage

How can I get the time spent on website and save that data to database using ajax call. I have tried something like below but it is not working as expected.
<?php
$ip=$_SERVER['REMOTE_ADDR'];
$url=file_get_contents("http://ip-api.com/json/$ip");
//Convert the json to php associative array
$data = json_decode($url, true);
?>
<html>
<head>
<title>My website</title>
</head>
<body>
Name: <input type="text" id="name">
<input type="submit" id="name-submit">
<div id="name-data"></div>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
var startTime = new Date();
alert(startTime);
window.onbeforeunload = function(ajaxFunc)
{
var ajaxFunc = function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var time = timeSpentMilliseconds / 1000 / 60;
$.ajax({
type: 'GET',
url: 'http://example.com/get_time/index.php',
data: 'time=' + timeSpentMilliseconds + '&t=' + time
});
};
});
</script>
</body>
</html>
The quick and dirty method
We will use the server polling every N seconds to manually calculate time user spent on the website. In order to prevent accumulating errors I'll add threshold of M seconds (M > N).
What I've did is set up a database table like this:
+--------------+------------+-------------+
| ip | total_time | last_update |
+--------------+------------+-------------+
| 12.214.43.41 | 581 | 1456534430 |
+--------------+------------+-------------+
| 41.61.13.74 | 105 | 1456538910 |
+--------------+------------+-------------+
| 112.31.14.11 | 4105 | 1456241333 |
+--------------+------------+-------------+
Then, you have a server-side script that does the next:
server.php
<?php
$servername = 'localhost';
$dbname = 'cooldb';
$username = 'dbuser';
$password = 'changeit';
$table = 'timers';
// Session timeout - threshold that user have left the site.
$session_timeout = 60;
$ip = $_GET['REMOTE_ADDR'];
$now = time();
$total_time = 0;
$last_update = time();
try {
$db = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// Set the PDO error mode to exception
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Check if we have ip on our table
$stmt = $db->prepare("SELECT * FROM {$table} WHERE ip=?");
$stmt->execute([$ip]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($rows)) {
$client = reset($rows);
$total_time = $client['total_time'];
$last_update = $client['last_update'];
// Updating $total_time only when user is logged in and sending requests in $session_timeout timespan.
if ($last_update + $session_timeout > $now) {
$total_time += $now - $last_update;
}
$last_update = $now;
// Client is already recorded - update the timers.
$stmt = $db->prepare("UPDATE {$table} SET total_time=?, last_update=? WHERE ip=?");
$stmt->execute([$ip, $total_time, $last_update]);
} else {
// Client have logged in first time - create a record in db.
$stmt = $db->prepare("INSERT INTO {$table} (`ip`, `total_time`, `last_update`) VALUES ('?', '?', '?')");
$stmt->execute([$ip, $total_time, $last_update]);
}
} catch (PDOException $e) {
echo $e->getMessage();
}
$db = null;
Then, on client-side you are just making requests like this to record user activity:
// Something reasonable, below $session_timeout threshold.
var repeat = 20000;
setInterval(function(){ $.get('/server.php', function(){}); }, repeat);
I didn't tested it yet myself, but I hope you'll get the idea.

PHP stream websockets

Im kinda new with the sockets stuff and Im trying to make a server on PHP to support websockets calls from my javascript currently my code looks like this
<?php
class Websocket
{
private $server;
private $sockets = [];
public function create($host)
{
$this->server = stream_socket_server('tcp://localhost:8080', $errno, $errmsg);
stream_set_blocking($this->server, 0);
}
public function run()
{
while(true)
{
$client = stream_socket_accept($this->server);
if($client)
{
$data = stream_socket_recvfrom($client, 2048);
if($data)
{
echo 'Client connected'.PHP_EOL;
echo $data;
$response = $this->handshake($data);
stream_socket_sendto($client, $response);
}
}
}
}
private function handshake($data)
{
$data = explode(PHP_EOL, $data);
foreach($data as $header)
{
$current_header = explode(':', $header);
if($current_header[0] == 'Sec-WebSocket-Key')
{
$accept = base64_encode(sha1(trim($current_header[1]).'258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
$response = 'HTTP/1.1 101 Switching Protocols'.PHP_EOL.'Upgrade: websocket'.PHP_EOL.'Connection: Upgrade'.PHP_EOL.'Sec-WebSocket-Accept:'.$accept.PHP_EOL.PHP_EOL;
return $response;
}
}
}
}
And my javascript is just a simple
var socket = new WebSocket('ws://localhost:8080');
socket.onopen = function(event)
{
console.log('connected');
socket.send('hello');
}
Currently the message connected appears on my chrome console but after that when the hello message is supposed to be sent I get this error
"connection to: xxx was interrupted while the page was loading"
So my question is after I have successfully send the handshake to the client how do I process messages? I know my code is always sending the handshake to new connections but on my server I will only see the first message beeing echoed (the http request) and not the "hello" one
You need to handle the message -
socket.onmessage = function(e){
var server_message = e.data;
console.log(server_message);
}

Providing php generated xml file to javascript parser

I am developing a smart tv app that plays live streams. App itself works fine, when i provide a valid xml playlist to it.
But when i use php to generate xml file (wich also generates fine), it doesnt work.
I get an error:
TypeError: 'null' is not an object (evaluating 'this.XHRObj.responseXML.documentElement')
Here is my php file that generates videoList.xml, it works 100%.
In short words, this script checks if MAC address in database, and if it is, then it writes videoList.xml with walid live streaming links.
SamsungAPI.php
<?php
$MAC = $_GET['MAC'];
require_once('../config.php');
//Remove brackets form array
$_INFO = preg_replace('/[{}]/', '', $_INFO);
$mysqli = new mysqli($_INFO['host'], $_INFO['db_user'], $_INFO['db_pass'], $_INFO['db_name']);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql="SELECT * FROM users WHERE admin_notes = '$MAC' ";
$rs=$mysqli->query($sql);
$rows=mysqli_num_rows($rs);
if ($rows == 1) {
//MAC FOUND
$row = mysqli_fetch_array($rs);
$username = $row['username'];
$password = $row['password'];
$file = "videoList.xml";
$txt_file = file_get_contents('http://' . $_SERVER['HTTP_HOST'] . '/get.php?type=starlivev3&username=' . $username . '&password=' . $password . '&output=hls');
$rows = explode("\n", $txt_file);
if(empty($rows[count($rows)-1])) {
unset($rows[count($rows)-1]);
$rows=array_map('trim',$rows);
}
$handle = fopen($file, "w+") or die('Could not open file');
fwrite($handle, "<?xml version=\"1.0\"?>"."\n");
fwrite($handle, "<rss version=\"2.0\">"."\n");
fwrite($handle, "<channel>"."\n");
foreach($rows as $row => $data)
{
//get row data
$row_data = explode(',', $data);
//replace _ with spaces
$row_data[0] = str_replace('_', ' ', $row_data[0]);
//generate playlist content
fwrite($handle, "<item>"."\n");
fwrite($handle, "<title>{$row_data[0]}</title>"."\n");
fwrite($handle, "<link>{$row_data[1]}</link>"."\n");
fwrite($handle, "<description> Reserved for EPG </description>"."\n");
fwrite($handle, "</item>"."\n");
}
fwrite($handle, "</channel>"."\n");
fwrite($handle, "</rss>");
fclose($handle);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
} else {
//MAC NOT FOUND
echo "MAC NOT FOUND";
}
mysqli_close($mysqli); // Closing Connection
?>
Then in samsung smart tv videoplayer app, i have xml parser like this:
Server.js
var Server =
{
/* Callback function to be set by client */
dataReceivedCallback : null,
XHRObj : null,
url : "http://myvalidhost.com/samsungAPI.php?MAC=02000027000b"
}
Server.init = function()
{
var success = true;
if (this.XHRObj)
{
this.XHRObj.destroy(); // Save memory
this.XHRObj = null;
}
return success;
}
Server.fetchVideoList = function()
{
if (this.XHRObj == null)
{
this.XHRObj = new XMLHttpRequest();
}
if (this.XHRObj)
{
this.XHRObj.onreadystatechange = function()
{
if (Server.XHRObj.readyState == 4)
{
Server.createVideoList();
}
}
this.XHRObj.open("GET", this.url, true);
this.XHRObj.send(null);
}
else
{
alert("Failed to create XHR");
}
}
Server.createVideoList = function()
{
if (this.XHRObj.status != 200)
{
Display.status("XML Server Error " + this.XHRObj.status);
}
else
{
var xmlElement = this.XHRObj.responseXML.documentElement;
if (!xmlElement)
{
alert("Failed to get valid XML");
}
else
{
// Parse RSS
// Get all "item" elements
var items = xmlElement.getElementsByTagName("item");
var videoNames = [ ];
var videoURLs = [ ];
var videoDescriptions = [ ];
for (var index = 0; index < items.length; index++)
{
var titleElement = items[index].getElementsByTagName("title")[0];
var descriptionElement = items[index].getElementsByTagName("description")[0];
var linkElement = items[index].getElementsByTagName("link")[0];
if (titleElement && descriptionElement && linkElement)
{
videoNames[index] = titleElement.firstChild.data;
if(linkElement.firstChild.data.substring(0,4) !="http"){
alert("asdasdasd "+linkElement.firstChild.data.substring(0,4));
var rootPath = window.location.href.substring(0, location.href.lastIndexOf("/")+1);
var Abs_path = unescape(rootPath).split("file://")[1]+linkElement.firstChild.data;
videoURLs[index] = Abs_path;
}
else{
videoURLs[index] = linkElement.firstChild.data;
}
videoDescriptions[index] = descriptionElement.firstChild.data;
}
}
Data.setVideoNames(videoNames);
Data.setVideoURLs(videoURLs);
Data.setVideoDescriptions(videoDescriptions);
if (this.dataReceivedCallback)
{
this.dataReceivedCallback(); /* Notify all data is received and stored */
}
}
}
}
Does anyone have any idea why doesnt it accept my generated xml file?
Regards
M
I figured it out, in php headers content type was wrong.
Changed
header('Content-Type: application/octet-stream');
to
header('Content-Type: application/xml');
Now it works perfect!

Creating a PHP websockets server

I am new in websockets technology. I was trying to create a websockets php server and connect to the server with a javascript client. I am using xampp 1.8.3.
I made this simple PHP server:
<?php
error_reporting(E_ALL);
set_time_limit(0);
$address = "127.0.0.1";
$port = 1777;
$maxConnections = 10;
if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0))){
$errorCode = socket_last_error();
$errorMsg = socket_strerror($errorCode);
die("socket_create() failed -> {$errorCode}:{$errorMsg}\n");
}
echo "Server created.\n";
if(!(socket_bind($sock, $address, $port))){
$errorCode = socket_last_error();
$errorMsg = socket_strerror($errorCode);
die("socket_bind() failed -> {$errorCode}:{$errorMsg}\n");
}
echo "Server opened on {$address}:{$port}\n";
if(!(socket_listen($sock, $maxConnections))){
$errorCode = socket_last_error();
$errorMsg = socket_strerror($errorCode);
die("socket_listen() failed -> {$errorCode}:{$errorMsg}\n");
}
echo "Waiting for connections...\n";
$client = socket_accept($sock);
if(socket_getpeername($client, $address, $port)){
echo "The client {$address}:{$port} is online.\n";
}
$msg = socket_read($client, 1024000);
if(!(socket_write($client, $msg, strlen($msg)))){
$errorCode = socket_last_error();
$errorMsg = socket_strerror($errorCode);
die("socket_write() failed -> {$errorCode}:{$errorMsg}\n");
}
echo "Message sent\n";
socket_close($client);
socket_close($sock);
?>
I ran this php file with xampp shell using the following expression:
php htdocs/server.php
and I got this message on shell:
php htdocs/server.php
Server created.
Server opened on 127.0.0.1:1777
Waiting for connections...
Then I opened my client.html on chrome (my supports websockets).
My client.html code is:
<html>
<head>
<meta charset="UTF-8" />
<title>Websockets web-server connection</title>
</head>
<body>
<p>Websockets connection. Status: <span id="status"></span></p>
<script type="text/javascript">
var webSockets = new WebSocket("ws://127.0.0.1:1777/");
webSockets.onopen = function(){
document.getElementById("status").innerHTML="connected";
webSockets.send("ping");
}
</script>
</body>
</html>
And I received this message on javascript console log:
WebSocket connection to 'ws://127.0.0.1:1777/' failed: client.html:9
And my shell had this messages:
php htdocs/server.php
Server created.
Server opened on 127.0.0.1:1777
Waiting for connections...
The client 127.0.0.1:64446 is online
Message sent
However I didn't receive any message on client, I do not even get a connected status.
What is happening? Where is my error?
Thank you.
WebSockets are not raw TCP sockets. They require a rather complex HTTP-like handshake to establish a connection, and require data transferred over them to be encoded and framed in a very particular way. The protocol is defined in RFC 6455.
Unless you are feeling incredibly masochistic, you don't want to try to implement this yourself. Use a library like Ratchet to implement WebSockets in PHP.
I had the same problem bro but no need of using Ratchet or other libraries you can write your own simple code . The handshake process,and the masking-unmasking of messages is rather difficult so i copied the code for those
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;
}
Instead of socket_accept user socket_read to get the http header containing request from webpage that it wants to upgrade its http conn to websocket then use the handshake function above to write an accept header message .then your connection will be established .but still on the client side you have to add events like these
if("WebSocket" in window){
var a = "ws://"+serverip+":9000";
var ws = new WebSocket(a);
var error = null;
ws.onopen = function(){
open();
}
ws.onerror = function(err){
errorhandler(err);
}
ws.onmessage = function(e){
messagehandler(e);
}
ws.onclose = function(){
close();
}
}
function open(){
document.getElementById('logs').innerHTML+='<p>WebSocket Connection OPened</p>';
}
function errorhandler(err){
document.getElementById('logs').innerHTML+='<p>WebSocket Connection Error occured &nbsp'+err.data+'</p>';
}
function messagehandler(a){
document.getElementById('logs').innerHTML+="<p>"+a.data+"</p>";
}
function close(){
document.getElementById('logs').innerHTML+='<p>WebSocket Connection Closed</p>';
ws = null;
}

Categories

Resources