Coder Social home page Coder Social logo

php-io's Introduction

Asynchronous object-oriented I/O PHP library

php-io is an object oriented and event-driven Input-Output library, primarily designed to serve network traffic to PHP scripts.

This library is partly based upon the php-uv's libuv binding, but other adapters are planned (pollig, libev, libevent)

The HTTP/WebSocket server example

A simple HTTP server could be implemented this way :

<?php

use Gplanchat\Io\Adapter\Libuv\DefaultServiceManager as LibuvServiceManager;
use Gplanchat\Io\Application\Application;
use Gplanchat\Io\Net\Protocol\Http;
use Gplanchat\EventManager\Event;
use Gplanchat\Io\Net\Tcp\ClientInterface;
use Gplanchat\Io\Net\Tcp\Plugin\Server as TcpServerPlugin;
use Gplanchat\Io\Net\Protocol\Http\Plugin\Server as HttpServerPlugin;


$httpListener = function(Event $event, ClientInterface $client, Http\Request $request, Http\Response $response) {
    $htmlBody = <<<HTML_EOF
<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <h1>Hello world</h1>
  </body>
</html>
HTML_EOF;

    $response
        ->setHeader('Content-Type', 'text/html')
        ->setBody($htmlBody)
        ->setReturnCode(200, 'OK')
        ->emit(new Event('ready'))
    ;
};

(new Application(new LibuvServiceManager()))
    ->registerPlugin(new TcpServerPlugin(), 'TcpServer', 0)
    ->registerPlugin(new HttpServerPlugin($httpListener), 'HttpServer', 0)
    ->init(function(Event $event, Application $application) {
        $application->callPlugin('TcpServer', ['0.0.0.0', 8081]);
        $application->callPlugin('HttpServer', ['TcpServer', 200]);
    })
    ->bootstrap()
    ->run()
;

Adding WebSocket support can be made this way by calling the init() method :

    ->init(function(Event $event, Application $application) {
        /*
         * Adding WebSocket (RFC 6455) support
         */
        $webSocketServiceManager = new WebSocket\ServerServiceManager();

        $webSocketListener = function(Event $event, ClientInterface $client, WebSocket\Request $request, WebSocket\Response $response) {
            $response
                ->addMessage(['Date' => date('c'), 'Hello' => 'World'])
                ->emit(new Event('ready'))
            ;
        };

        $httpServer = $application->getStorage('HttpServer');
        $httpServer->registerPlugin('WebSocket', new Http\Plugin\WebSocket($webSocketServiceManager, $webSocketListener));
    })

Using a database connection

For now, only MySQL using mysqli and mysqlnd is supported as a basic feature.

This is how you can implement a MySQL connection handler :

use Gplanchat\Io\Application\Application;
use Gplanchat\EventManager\Event;
use Gplanchat\Io\Adapter\Libuv\DefaultServiceManager as LibuvServiceManager;
use Gplanchat\Io\Db\Mysql\DefaultServiceManager as MysqlServiceManager;

(new Application(new LibuvServiceManager()))
    ->init(function(Event $event, Application $application) {
        // Initiating the poller and assigning it to the main loop through a timer
        /** @var \Gplanchat\Io\Loop\TimerInterface $timer */
        $timer = $application->getServiceManager()->get('Timer', [$application->getCurrentLoop()]);

        $serviceManager = new MysqlServiceManager();
        $poller = $serviceManager->get('Poller');

        $link = $serviceManager->get('Connection', ['localhost', 'root', '', 'foo_database']);
        $poller->addConnection($link);

        $timer->interval(1, $poller);
        $application->setStorage('Db', $link);
    })
    ->init(function(Event $event, Application $application) {
        // Sending requests to the RDBMS
        $worker = $application->getServiceManager()->get('Timer', [$application->getCurrentLoop()]);
        $worker->interval(20, function() use($application) {
            $link = $application->getStorage('Db');

            $link->query('SELECT * FROM foo_table ORDER BY RAND() LIMIT 1', function($result) {
                var_dump($result);
            });
        });
    })
    ->bootstrap()
    ->run()
;

Documentation

The API documentation Was built using php-docgen. » Read the docs

php-io's People

Contributors

gplanchat avatar steverhoades avatar

Stargazers

Hugo S. Becerra Adán avatar Alex Demchenko avatar 南無假行僧 avatar Spiros Kabasakalis avatar Sean Kumar avatar Evan Frohlich avatar  avatar sasezaki avatar Marc Bennewitz avatar

Watchers

 avatar 南無假行僧 avatar James Cloos avatar

php-io's Issues

Socket stuck in CLOSE_WAIT

This may not be an issue with php-io but adding it here for documentation purposes. The close event never gets fired if the client kills the connection, the server keeps the socket open CLOSE_WAIT state. My guess this has to do with unsent data back to the client - don't have a fix for this yet.

php 11508 vagrant 10u IPv4 6707089 0t0 TCP *:1337 (LISTEN)
php 11508 vagrant 11u IPv4 6704822 0t0 TCP localhost:1337->localhost:52682 (CLOSE_WAIT)
php 11508 vagrant 12u IPv4 6702965 0t0 TCP localhost:1337->localhost:52683 (CLOSE_WAIT)

To reproduce, create a websocket connection to the server - wait a few seconds then close the websocket.

Fatal Error: php-io/src/Gplanchat/Io/Net/Tcp/Plugin/Server.php on line 86

Quick note that when trying to run the example code after a fresh install (composer install) the following error is thrown.

$ php server.php
PHP Fatal error: Call to a member function get() on a non-object in /var/www/sandbox/php-io/src/Gplanchat/Io/Net/Tcp/Plugin/Server.php on line 86

Fatal error: Call to a member function get() on a non-object in /var/www/sandbox/php-io/src/Gplanchat/Io/Net/Tcp/Plugin/Server.php on line 86

I really like what you have done here - looks very promising. Any thoughts on perhaps leveraging the ZF2 service manager instead of your own? They appear to be identical aside from your library using the service manager class as a trait.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.