EWEB2

From Klaus' wiki
Jump to: navigation, search

Installing MySQL

With your team prepare your virtual server for running MySQL by following the steps below.

Install the server

As root perform

$ yum install mysql mysql-server

Secure the server

Next configure mysql by issuing

$ /usr/bin/mysql_secure_installation

Give a password you can remember for the root user and accept the default for the rest - but DO READ and understand what you're accepting.

Make mysqld start with Linux

Next configure the mysqld to start with the server start:

$ chkconfig --list|grep mysql

expect a result like this:

mysqld          0:off   1:off   2:off   3:off   4:off   5:off   6:off

Now configure the mysql daemon to start with Linux boot:

$ chkconfig --level 345 mysqld on

this instructs Linux to start mysqld in run-level 3, 4 and 5. MySQL will now start every time you (re)boot your computer.

Check that you've enabled the mysqld

$ chkconfig --list|grep mysql

expect a result like this:

mysqld          0:off   1:off   2:off   3:on   4:on   5:on   6:off

Manually start the daemon

Finally start the daemon manually for the first time:

$ service mysqld start

Test that you can login by issuing:

$ mysql -p

give the previously set password. To quit from the mysql console type

quit;

Install PHP

In order to use PHP in the web server, you have to install PHP.

As root perform:

$ yum install php
$ service httpd restart

The last line is to restart the Apache server loading the newly installed module.

Test the PHP installation

In the web-server root (typical /var/www/html) create a file info.php with this content:

<?php
phpinfo();
?>

Next test that your web-server and PHP is running as expected by entering in your web-browser the IP-address of your virtual server and /info.php like:

10.1.18.nnn/info.php

where you replace nnn with your virtual computers IP address.

Install a PHP plugin in Eclipse

If you've havn't got Eclipse install for the C/C++ do so by going to eclipse.org and download the package. Install it in /opt/eclipses/CDT

There are several plugins for Eclipse handling PHP. I suggest two different plugins here:

PDT

In the Help menu select Install New software. In the Work with select box choose Kepler - ... Open the Web development collection and select PHP Development Toolkit (PDT)

Be patient - it may take very long time to install, for some reason, but eventually you may end up with PDT installed.

Be sure to restart your Eclipse after installation.

PHPEclipse

Next start the Eclipse and in the Help menu select Install new software - click on the Add button. Add this link: http://phpeclipse.sourceforge.net/update/stable/1.2.x/ type or select a site name it PHPEclipse.

Be patient - I've seen this taking very, very long time.

Be sure to restart your Eclipse after installation.

Alternative go to Eclipse Marketplace and download a the package from there. Install the package by clicking on the Add button and select the Archive button thereafter. Locate the downloaded package and install it. Beware this I've also seen being a very long running process.

Next create a new PHP project and work in there.

JSEclipse

JSEclipse is a plugin for working with JavaScript.

From http://jseclipse.softpile.com/90100/download/?o=softup download a JavaScript plugin.

From within Eclipse select in the menu Help->Install New Software. Click on the Add button and click on the Archive button and select the just downloaded archive.

Get in contact with MySQL

As root install support for the MySQL database by issuing:

$ yum install php-mysql

Restart the httpd server.

Reload the info.php page and observe that you now have a section about MySQL.

Administer MySQL through PHPMyAdmin

PHPHMyAdmin is a web based application enabling you to manipulate the MySQL database.

Installation

First ensure that you have mysql and the mysql server installed.

$ yum install mysql mysql-server
$ service mysqld start

Install phpmyadmin by, as root, issuing this command:

$ yum install phpmyadmin

Configuration

Next you have to configure the phpmyadmin a little:

In /etc/http/conf.d/phpmyadmin.conf comment out the <Directory "/usr/share/phpmyadmin"> stanza ending up with something like this:

# But allowing phpMyAdmin to anyone other than localhost should be considered
# dangerous unless properly secured by SSL
 
Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin
 
#<Directory /usr/share/phpMyAdmin/>
#   Order Deny,Allow
#   Deny from All
#   Allow from 127.0.0.1
#   Allow from ::1
#</Directory>

Next we check that the authentication in phpMyAdmin is set to http:

Open /usr/share/phpMyAdmin/config.inc.php and look for the line:

$cfg['Servers'][$i]['auth_type']     = 'http';      // Authentication method (config, http or cookie based)?

if the setting is not http change it.

Restart the httpd by issuing:

$ service httpd restart

Testing the PHPMyAdmin installation

Test PHPMyAdmin by using this link phpMyadmin (works only if you're loged in on the development host using a NX terminal).

You may have to edit the phpmyadmin configuration file. Add the location og the mysql.sock file.

$ vi /etc/phpMyAdmin/config.inc.php

Find and change the socket setting so it looks like this:

$cfg['Servers'][$i]['socket']        = '/var/lib/mysql/mysql.sock';  // Path to the socket - leave blank for default socket

The path and file name of the mysql.sock file was added.

Be sure to reload the httpd before testing again.

Test from PHP

First prepare your Apache server to work with files from a project directory.

In /etc/httpd/conf/http.conf at the end enter these lines:

<VirtualHost *:80>
  DirectoryIndex        index.html index.htm index.php
  ServerAdmin           klausk@hih.au.dk
  DocumentRoot          /var/www/html/PHP-DBif
  ServerName            PHP-DBif
  ServerAlias           PHP-DBif
  ErrorLog              /var/log/httpd/PHP-DBif.log
  TransferLog           /var/log/httpd/PHP-DBif.log
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
  Customlog               /var/log/httpd/PHP-DBif.log combined
</VirtualHost>

This will work as the default Server for Apache.

Next thing is to configure Eclipse.

Using Eclipse you can create a Remote System Explorer integration.

There are several ways this can be done. One option is to work on the local machine where you can use the Local connection. Another option is to use SSH on a remote (or local) machine. Below is described how to create a SSH connection, but most of it covers the local connection also. It is only the connection method that differs. The SSH connection described here connect locally, but could just as well be used on a remote machine.

First open the Remote System Explorer perspective (Window menu -> Open Perspective)

In the left pane right-click and choose New Connection.

Select SSH Only, in the next dialogue select LOCALHOST and give the connection a descriptive name, e.g. Apache.

Click on the Finish button.

Now navigate to the newly created files system to the SFTP Files->root/var/www/html/.

Create a new folder that can hold your project.

Navigate into the newly created folder.

Right-click and select Create Remote Project.

Switch perspective to the PHPEclipse perspective and select the newly created project.

Create an index.php with the content shown below:

<!DOCTYPE html>
<head>
	<title>MySQL Connection Test</title>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<style type="text/css">
		#wrapper {
		    width: 600px;
		    margin: 20px auto 0;
		    font: 1.2em Verdana, Arial, sans-serif;
		}
		input {
		    font-size: 1em;
		}
		#submit {
		    padding: 4px 8px;
		}
	</style>
</head>
 
<body>
 
<div id="wrapper">
 
<?php
    $action = htmlspecialchars($_GET['action'], ENT_QUOTES);
?>
 
<?php if (!$action) { ?>
 
<h1>MySQL connection test</h1>
 
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?action=test" id="mail" method="post">
 
    <table cellpadding="2">
        <tr>
            <td>Hostname</td>
            <td><input type="text" name="hostname" id="hostname" value="" size="30" tabindex="1" /></td>
            <td>(usually "localhost")</td>
        </tr>
        <tr>
            <td>Username</td>
            <td><input type="text" name="username" id="username" value="" size="30" tabindex="2" /></td>
            <td></td>
        </tr>
        <tr>
            <td>Password</td>
            <td><input type="text" name="password" id="password" value="" size="30" tabindex="3" /></td>
            <td></td>
        </tr>
        <tr>
            <td>Database</td>
            <td><input type="text" name="database" id="database" value="" size="30" tabindex="4" /></td>
            <td>(optional)</td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" id="submit" value="Test Connection" tabindex="5" /></td>
            <td></td>
        </tr>
    </table>
 
</form>
 
<?php } ?>
 
<?php if ($action == "test") {
 
// The variables have not been adequately sanitized to protect against SQL Injection attacks: http://us3.php.net/mysql_real_escape_string
 
    $hostname = trim($_POST['hostname']);
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);
    $database = trim($_POST['database']);
 
    $link = mysql_connect("$hostname", "$username", "$password");
        if (!$link) {
            echo "<p>Could not connect to the server '" . $hostname . "'</p>\n";
            echo mysql_error();
        }else{
            echo "<p>Successfully connected to the server '" . $hostname . "'</p>\n";
//          printf("MySQL client info: %s\n", mysql_get_client_info());
//          printf("MySQL host info: %s\n", mysql_get_host_info());
//          printf("MySQL server version: %s\n", mysql_get_server_info());
//          printf("MySQL protocol version: %s\n", mysql_get_proto_info());
        }
    if ($link && !$database) {
        echo "<p>No database name was given. Available databases:</p>\n";
        $db_list = mysql_list_dbs($link);
        echo "<pre>\n";
        while ($row = mysql_fetch_array($db_list)) {
            echo $row['Database'] . "\n";
        }
        echo "</pre>\n";
    }
    if ($database) {
    $dbcheck = mysql_select_db("$database");
        if (!$dbcheck) {
            echo mysql_error();
        }else{
            echo "<p>Successfully connected to the database '" . $database . "'</p>\n";
            // Check tables
            $sql = "SHOW TABLES FROM `$database`";
            $result = mysql_query($sql);
            if (mysql_num_rows($result) > 0) {
                echo "<p>Available tables:</p>\n";
                echo "<pre>\n";
                while ($row = mysql_fetch_row($result)) {
                    echo "{$row[0]}\n";
                }
                echo "</pre>\n";
            } else {
                echo "<p>The database '" . $database . "' contains no tables.</p>\n";
                echo mysql_error();
            }
        }
    }
}
?>
 
</div><!-- end #wrapper -->
</body>
</html>

Finally edit the /etc/http/conf/httpd.conf file and add near the button, but above the <VirtualHost *:80> you already have a copy of the definition just below, changing the ServerName and DocumentRoot to appropriate values (the first <VirtualHost *:80> will be the default for localhost.

To make it work as root

$ service httpd restart

observer that there are no errors reported. Fix any before continuing.

Now in yor browser enter the address: http://localhost/ and see the result.

You can edit the php file from within Eclipse.

Websockets

Websockets are handy when you have a server that should push updates to a client at arbitrary times. Rather than polling from the client using HTTP, which are one shot connections that are closed after use, the websocket can be kept open and is bidirectional. Hence, the server can, when data needs to be sent to the client, immediately send it to the browser and the data can be handled in the client by JavaScript code.

Websockects can run as an upgrade to a HTTP request, i.e. over the port 80, and thereby circumventing the firewall, which typically at the client side blocks for incoming requests, i.e. disallowing the server to push updates to the client. Websockets can also be run on a separate port, which consequently of course requires that the chosen port is open in the firewall.

Server

To try out the websockets by creating this PHP code on a server.

<?php
$host = 'localhost'; //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'=>$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 
			$user_name = $tst_msg->name; //sender name
			$user_message = $tst_msg->message; //message text
			$user_color = $tst_msg->color; //color
 
			//prepare data to be sent to client
			$response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));
			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));
}

Execute the code on the commandline as root:

$ php -q server.php

save the file in e.g. server.php

Client

In a directory from where the webserver serves files create this file:

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<style type="text/css">
<!--
.chat_wrapper {
	width: 500px;
	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: 150px;
	overflow: auto;
	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>
</head>
<body>	
<?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(){
	//create a new WebSocket object.
	var wsUri = "ws://localhost:9000/demo/server.php"; 	
	websocket = new WebSocket(wsUri); 
 
	websocket.onopen = function(ev) { // connection is open 
		$('#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(myname == ""){ //empty name?
			alert("Enter your Name please!");
			return;
		}
		if(mymessage == ""){ //emtpy message?
			alert("Enter Some message Please!");
			return;
		}
 
		//prepare json data
		var msg = {
		message: mymessage,
		name: myname,
		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 ucolor = msg.color; //color
 
		if(type == 'usermsg') 
		{
			$('#message_box').append("<div><span class=\"user_name\" style=\"color:#"+ucolor+"\">"+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
	};
 
	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" id="name" placeholder="Your Name" maxlength="10" style="width:20%"  />
<input type="text" name="message" id="message" placeholder="Message" maxlength="80" style="width:60%" />
<button id="send-btn">Send</button>
</div>
</div>
 
</body>
</html>

save the file as e.g. index.php

Other preparations

Install php-pecl-json

$ yum install php-pecl-json

Try it!

Open in your browser the client code, e.g. http://localhost/index.php

Observe, using Wireshark, the traffic on the Ethernet.

NOTE: This example will not use the HTTP upgrade functionality. Apache is not designed to maintain long running connections. Apache is designed for quick server and forget purposes as normal HTTP traffic is.

A HW Display Example with websocket

In order to display hardware using a websocket connection I've prepared a small example, which can be found here