/**
  * Main function that runs in a forever loop to keep listening on all required ports
  * @param $strHostAddress
  * @param $intPort
  */
 protected function listen($strHostAddress, $intPort)
 {
     System::upTime(time());
     error_reporting(E_ALL);
     set_time_limit(0);
     ob_implicit_flush(true);
     //Load in all the registered WebSocket Apps
     AppHandler::load();
     $this->resMasterSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed");
     socket_set_option($this->resMasterSocket, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed");
     socket_bind($this->resMasterSocket, $strHostAddress, $intPort) or die("socket_bind() failed");
     socket_listen($this->resMasterSocket, 20) or die("socket_listen() failed");
     System::serverHeader(sprintf("Server Started\t: %s", date('Y-m-d H:i:s')));
     System::serverHeader(sprintf("Listening on\t: %s port %s", $strHostAddress, $intPort));
     System::serverHeader(sprintf("Master socket\t: %s\n", $this->resMasterSocket));
     System::output();
     while (true) {
         //Run the Scheduled Tasks on every iteration of the while loop
         Scheduler::process();
         System::output();
         //Grab an array of all the sockets that are connected
         $arrSockets = Sockets::getAll($this->resMasterSocket);
         $resWrite = null;
         $resExcept = null;
         //Proceed to the next iteration if no sockets are currently active
         if (socket_select($arrSockets, $resWrite, $resExcept, 1) < 1) {
             continue;
         }
         //Go through each socket and process accordingly
         foreach ($arrSockets as $resClientSocket) {
             if ($resClientSocket == $this->resMasterSocket) {
                 $resNewClient = socket_accept($this->resMasterSocket);
                 if ($resNewClient < 0) {
                     System::debug("socket_accept() failed");
                     continue;
                 } else {
                     $this->connect($resNewClient);
                     System::output();
                 }
             } else {
                 //8192
                 $intBytes = socket_recv($resClientSocket, $strBuffer, 8192, 0);
                 //No bytes returned then disconnect the user from the system
                 if ($intBytes === 0 || $intBytes == 0) {
                     $this->disconnect($resClientSocket, "No bytes returned then disconnect the user from the system");
                 } else {
                     //If the socket has not completed the handshake process yet then handshake now
                     if (Sockets::getHandshake($resClientSocket) === false) {
                         $this->handshake($resClientSocket, $strBuffer);
                     } else {
                         $strDecodedData = DataHandler::unwrap($strBuffer, $resClientSocket);
                         //Process the request message as the user is already valid and confirmed
                         $this->process($resClientSocket, $strDecodedData);
                     }
                 }
                 System::output();
             }
         }
         //If the server is to be shutdown then kill the server now
         if ($this->blShutdownServer == true) {
             echo "\n\n############################\n# Server is shutting down! #\n############################\n\n";
             break;
         }
     }
     //Close the server socket as it is not needed
     socket_close($this->resMasterSocket);
 }