1 頁 (共 1 頁)

用 PHP Daemon 寫一個 HTTP Server

發表於 : 2013-10-16 16:02:02
yehlu
http://lab.asika.tw/programming/php/31- ... erver.html

代碼: 選擇全部

<?php
/**
 * A PHP socket server demo file.
 *
 * @author     Asika
 * @email      asika@asikart.com
 * @date       2013-10-12
 * 
 * @copyright  Copyright (C) 2013 - Asika.
 * @license    GNU General Public License version 2 or later; see LICENSE
 */

/**
 * Daemon Application.
 */
class DaemonHttpApplication
{
    /**
     * Socket address.
     *
     * @var string 
     */
    protected $domain;

    /**
     * Socket port.
     *
     * @var int 
     */
    protected $port;

    /**
     * Max backlog
     *
     * @var int 
     */
    protected $maxBacklog = 16;

    /**
     * Set domain.
     *
     * @param  string  $domain  Your http server domain.
     *
     * @return  DaemonHttpApplication  Return self to support chaining.
     */
    public function setDomain($domain)
    {
        $this->domain = $domain;

        return $this;
    }

    /**
     * set port
     *
     * @param  int  $post  The port which socket listened.
     *
     * @return  DaemonHttpApplication  Return self to support chaining.
     */
    public function setPort($port)
    {
        $this->port = $port;

        return $this;
    }

    /**
     * Create a daemon process.
     *
     * @return  DaemonHttpApplication  Return self to support chaining.
     */
    public function execute()
    {
        // Create first child.
        if(pcntl_fork())
        {
            // I'm the parent
            // Protect against Zombie children
            pcntl_wait($status);
            exit;
        }

        // Make first child as session leader.
        posix_setsid();

        // Create second child.
        if(pcntl_fork())
        {
            // If pid not 0, means this process is parent, close it.
            exit;
        }

        // Create Http server
        $this->createHttpServer();

        return $this;
    }

    /**
     * Create a http service.
     *
     * @return  DaemonHttpApplication  Return self to support chaining.
     */
    protected function createHttpServer()
    {
        // Set response body
        $response   = <<<RES
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
    </head>
    <body>
        Hello World~~~!!!
    </body>
</html>
RES;

        // Count text length
        $responseLength = strlen($response);

        // Create socket.
        if(!($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)))
        {
            echo "Create socket failed!\n";
            exit;
        }   

        // Bind socket
        if(!(socket_bind($socket, $this->domain, $this->port)))
        {
            echo "Bind socket failed!\n";
            exit;
        }

        // Listen socket
        if(!(socket_listen($socket, $this->maxBacklog)))
        {
            echo "Listen to socket failed!\n";
            exit;
        }

        // Infinity loop for listening
        while(true)
        {
            $acceptSocket = socket_accept($socket);

            if(!$acceptSocket)
            {
                continue;
            }
            else
            {
                socket_write($acceptSocket, $response, $responseLength);

                socket_close($acceptSocket);
            }
        } // End while
    }
}


// Execute
// ---------------------------------------------

if(empty($_SERVER['argv'][1]))
{
    fwrite(STDERR, "Missing argument 1, please provide a domain address.\n");
    die;
}

$http = new DaemonHttpApplication();

$http->setDomain($_SERVER['argv'][1])
    ->setPort(9999)
    ->execute();