Create a socket server in php and run as a service

Problem scenario:

Suppose you have a ecommerce site where customer can put an order. Then site will be notify you via sms or any device when new order found

Efficient Solved scenario:

You have to build a socket sever which check the new order and response you, then you will collect the new order from your e-commerce site

Prerequisites

  • PHP Sockets library. The extension is enabled at compile time using the –enable-sockets configure option.
  • CLI (Command Line Interface) version of PHP: enables the running of the socket server from the command line.As of PHP 4.3.0 the CLI executable is compiled and installed by default (you can explicitly install the CLI version by specifying –enable-cli at compile time).
  • Linux OS

Although this example uses Linux, I will show everything using *nix environments

What is a socket server?

A socket server is a service assigned to a particular port that listens to incoming requests and responds to them.
Socket Servers normally run continuously as a service or a system daemon.

Types of Sockets

There are two different protocols for splitting the information into packets, depending on the information type being sent and delivery requirements.

  • TCP (Transmission Control Protocol) – the transmitted packets are numbered and are assembled on the other end, they are assembled in order to form the entire message. TCP usually runs over IP (Internet Protocol) hence the term TCP/IP.TCP ensures that no data is lost (if a packet is lost it will be re-transmitted), and is therefore well suited for sending images, files or other information that must be received whole and integral (like your email).
  • UDP (User Datagram Protocol) – this is a connectionless protocol. Like TCP it can run over the IP protocol. The difference is that UDP provides few error recovery services and so there is no guarantee that a particular packet will be received on the other side, or in what order the packets will be received.
  • UDP is particularly suitable for streaming data such as music streams (if we lose some information, there is no point in trying to get it again as we may have already played that part).

In this example , TCP sockets will be used to ensure that all the data is received intact.

Creating a Socket Server using PHP

/*********function to check new order******************/
function get_new_order()
{
$con=mysql_connect(HOST, USERNAME, PASSWORD);
mysql_select_db(DATABASE,  $con);
$sql="select  OrderId from customer_order where order_Status='0' "; //0 for new order
$query=mysql_query($sql,$con);
if(mysql_num_rows(  $query)>0)
{
return true;
}
else return  false;
}
/*************************************/
/********Socket Server*********************/
set_time_limit (0);
// Set the ip and port we will listen on
$address = '127.0.0.1';
$port = 6789;
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0); // 0 for  SQL_TCP
// Bind the socket to an address/port
socket_bind($sock, 0, $port) or die('Could not bind to address');  //0 for localhost
// Start listening for connections
socket_listen($sock);
//loop and listen
while (true) {
/* Accept incoming  requests and handle them as child processes */
$client =  socket_accept($sock);
// Read the input  from the client – 1024000 bytes
$input =  socket_read($client, 1024000);
// Strip all white  spaces from input
$output =  ereg_replace("[ \t\n\r]","",$input)."\0";
$message=explode('=',$output);
if(count($message)==2)
{
if(get_new_order()) $response='NEW:1';
else  $response='NEW:0';
}
else $response='NEW:0';
// Display output  back to client
socket_write($client, $response);
socket_close($client);
}
// Close the master sockets
socket_close($sock);

Run the socketserver into your server

You can run this sever in several ways
1.using cronjob/crontab
2.using php CLI
3. as a daemon service
I will show you in *nix Enviroments
In Centos you can use like this

Chomd  a+x SocketServer.php  //to make  executable
Php  –q  SocketServer.php //run using php_cli

You can also run as a system_daemon

nohup  php SocketServer.php  & //you must  use & to create a pid, after using this command you can see the pid number

/** to kill the process**/

Kill  pid_number

/*********************/
In Ubuntu you can use like this

pear install -f System_Daemon // to  install pear package for system_daemon

now create a file named SockctCli.php like this

#!/usr/bin/php -q
/**
* System_Daemon turns PHP-CLI scripts into  daemons.
*
* PHP version 5
*
* @category   System
* @package    System_Daemon
* @author     Abdullah <ab.duetcse@yahoo.com>
* @copyright 2010 Abdullah
* @license    GPL
* @link       funphp.com/daemon_example
*/
/**
* System_Daemon Example Code
*
* If you run this code successfully, a daemon  will be spawned
* but unless have already generated the init.d  script, you have
* no real way of killing it yet.
*
* In this case wait 3 runs, which is the  maximum for this example.
*
*
* In panic situations, you can always kill you  daemon by typing
*
* killall -9 SocketCli.php
* OR:
* killall -9 php
*
Allowed arguments & their  defaults */
$runmode = array(
'no-daemon' => true,
'help' => false,
'write-initd' => false,
);
/* Scan command line attributes for  allowed arguments */
foreach ($argv as $k=>$arg) {
if (substr($arg, 0, 2) == '--' && isset($runmode[substr($arg,  2)])) {
$runmode[substr($arg, 2)] = true;
}
}
/* Help mode. Shows allowed argumentents  and quit directly */
if ($runmode['help'] == true) {
echo 'Usage: '.$argv[0].' [runmode]' . "\n";
echo 'Available runmodes:' . "\n";
foreach ($runmode as $runmod=>$val) {
echo ' --'.$runmod . "\n";
}
die();
}
*/ Make it possible to test in  source directory
 This is for PEAR developers only */
ini_set('include_path',  ini_get('include_path').':..');
/* Include Class */
error_reporting(E_ALL);
require_once 'System/Daemon.php';
/* Setup */
$options = array(
'appName' => 'SocketCli',
'appDir' => dirname(__FILE__),
'appDescription' => 'Run a socket server to listen printer request',
'authorName' => 'Md. Abdullah Bin salam',
'authorEmail' => 'ab.duetcse@gmail.com',
'sysMaxExecutionTime' => '0',
'sysMaxInputTime' => '0',
'sysMemoryLimit' => '1024M',
'appRunAsGID' => 1000,
'appRunAsUID' => 1000,
);
System_Daemon::setOptions($options);
/* This program can also be run in  the forground with runmode --no-daemon */
if (!$runmode['no-daemon']) {
/* Spawn Daemon */
System_Daemon::start();
}
/* With the runmode --write-initd,  this program can automatically write a
 system startup file called:  'init.d'
 This will make sure your daemon  will be started on reboot */
if (!$runmode['write-initd']) {
System_Daemon::info('not writing an init.d script this time');
} else {
if (($initd_location = System_Daemon::writeAutoRun()) === false) {
System_Daemon::notice('unable to write  init.d script');
} else {
System_Daemon::info(
'sucessfully written startup script: %s',
$initd_location
);
}
}
require_once '/var/www/SocketServer/SocketServer.php';
/* Run your code
 Here comes your own actual code
 This variable gives your own code  the ability to breakdown the daemon: */
$runningOkay = true;
/* This variable keeps track of how  many 'runs' or 'loops' your daemon has
 done so far. For example  purposes, we're quitting on 3. */
$cnt = 1;
/* While checks on 3 things in this  case:
 - That the Daemon Class hasn't  reported it's dying
 - That your own code has been  running Okay
 - That we're not executing more  than 3 runs */
while (!System_Daemon::isDying()  && $runningOkay ) {
/* What mode are we in? */
$mode = '"'.(System_Daemon::isInBackground() ? '' : 'non-' ).
'daemon" mode';
/* Log something using the Daemon class's logging facility
Depending on runmode it will either end up:
  - In the  /var/log/logparser.log
  - On screen (in case we're not  a daemon yet) */
System_Daemon::info('{appName} running in %s %s/3',
$mode,
$cnt
);
/* In the actuall logparser program, You could replace 'true'
 With e.g. a  parseLog('vsftpd')  function, and have it return
 either true on success, or false on failure. */
$runningOkay = true;
/*$runningOkay = parseLog('vsftpd');
Should your parseLog('vsftpd') return false, then
the daemon is automatically shut down.
An extra log entry would be nice, we're using level 3,
which is critical.
Level 4 would be fatal and shuts down the daemon immediately,
which in this case is handled by the while condition. */
if (!$runningOkay) {
System_Daemon::err('parseLog() produced  an error, '.
'so this will be my last run');
}
/* Relax the system by sleeping for a little bit
iterate also clears statcache */
System_Daemon::iterate(2);
$cnt++;
}
/* Shut down the daemon nicely
 This is ignored if the class is  actually running in the foreground*/
System_Daemon::stop();

Execute

Just make your daemon script executable, and then execute it:

chmod a+x ./SocketCli.php<
./ SocketCli.php

Check

Your daemon has no way of communicating through your console, so check for messages in:

tail /var/log/ SocketCli.log

And see if it's still running:

ps uf -C SocketCli.php

Kill

Without the start/stop files (see below for howto), you need to:

killall -9 SocketCli.php

Autch.. Let's work on those start / stop files, right?

Start / Stop files (Debian & Ubuntu only)

Real daemons have an init.d file. Remember you can restart Apache with the following statement?

/etc/init.d/apache2 restart

That's a lot better than killing. So you should be able to control your own daemon like this as well:

/etc/init.d/ SocketCli stop
/etc/init.d/ SocketCli start

Now your server is build and run into the server as a service like apache service.

Test your server

Open a terminal and telnet

telnet example.com 6789
  //example.com –your server domain where running your socketserver
  //6789—port number of the socket server
  Check=1  //send a  message to check new order
  After that you will get response from server like
  New:1 or New:0
  You can do anything according to server response 
  

Practical Uses

There are several uses of the socket server such as

  • Chat server (using a text based or graphical interface). This can be for fun or real application (e.g. customer support representatives).
  • Real time information streaming (news, stocks etc.)
  • Streaming multimedia (images, videos and sounds)
  • Authentication server
  • Simple web, POP3, SMTP and FTP servers.

10 Responses to “Create a socket server in php and run as a service”

  1. Carry on Abd, nice article…

  2. Terrific website! I thoroughly enjoyed your content material …very nicely written.

  3. In think this article is gonna be very useful to me because, currently, I need to develop uninterrupted multithreaded background processes as part of our project. I need info on how to make it multithreaded. Anybody having a link that should kindly help me. kudos!

  4. All I can say is maintain it up. This blog is so essential in a time when everybody just wants to talk about how several individuals someones cheated on their wife with. I mean, thanks for bringing intelligence back to the web, its been sorely missed. Great stuff. Please maintain it coming!

  5. Very helpful article about socket programmimg

  6. rajesh wasave says:

    dear sir… what kind of server i need and type of IP (static/dynamic) ??

  7. Hi Abdullah – do you have any experience running it as a windows service?

  8. Thank you very much.

Leave a Reply

Your email address will not be published.