6

I am able to make a simple php websocket server with libevent , but I am stuck when I'm trying to make it multiprocessing.

for example this is single processing

<?php
$socket = stream_socket_server ('tcp://0.0.0.0:2000', $errno, $errstr);
stream_set_blocking($socket, 0);
$base = event_base_new();
$event = event_new();
event_set($event, $socket, EV_READ | EV_PERSIST, 'ev_accept', $base);
event_base_set($event, $base);
event_add($event);
event_base_loop($base);

$GLOBALS['connections'] = array();
$GLOBALS['buffers'] = array();

function ev_accept($socket, $flag, $base) {
    static $id = 0;

    $connection = stream_socket_accept($socket);
    stream_set_blocking($connection, 0);

    $id += 1;

    $buffer = event_buffer_new($connection, 'ev_read', NULL, 'ev_error', $id);
    event_buffer_base_set($buffer, $base);
    event_buffer_timeout_set($buffer, 30, 30);
    event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);
    event_buffer_priority_set($buffer, 10);
    event_buffer_enable($buffer, EV_READ | EV_PERSIST);

    // we need to save both buffer and connection outside
    $GLOBALS['connections'][$id] = $connection;
    $GLOBALS['buffers'][$id] = $buffer;
}

function ev_error($buffer, $error, $id) {
    event_buffer_disable($GLOBALS['buffers'][$id], EV_READ | EV_WRITE);
    event_buffer_free($GLOBALS['buffers'][$id]);
    fclose($GLOBALS['connections'][$id]);
    unset($GLOBALS['buffers'][$id], $GLOBALS['connections'][$id]);
}

function ev_read($buffer, $id) {
    while ($read = event_buffer_read($buffer, 256)) {
        var_dump($read);
    }
}
?> 

But when I do this in function ev_read

     function ev_read($buffer, $id) {
            while ($read = event_buffer_read($buffer, 256)) {
    $pid = pcntl_fork();
        switch ($pid) {
        case -1: // Error
            die('Fork failed, your system is b0rked!');
            break;
        case 0: // Child
                event_buffer_write($buffer,"asdawdasd");

        exit(0);
            break;


            }
   } }

it doesnt send the data...

So how can I make a multiprocessing php socket server?

Deadworldisee
  • 61
  • 1
  • 2
  • Why do you want to fork new processes? If you're using libevent then why not try an asynchronous "multi-processing" approach? – Robin Apr 19 '11 at 18:40
  • Give me some hints, how to make that in php... – Deadworldisee Apr 19 '11 at 18:43
  • Have a poke around this as an example: http://code.google.com/p/web-socks/source/browse/trunk/WebSocks.php – Robin Apr 19 '11 at 18:49
  • That example doesnt use libevents and its not multiprocessing either.... – Deadworldisee Apr 19 '11 at 18:54
  • You don't have to use libevent to write an asynchronous program, and you don't have to use `fork` to serve multiple clients at the same time ;-) – Robin Apr 19 '11 at 18:56
  • And whats the solution to make a fast asynchronous socket server and to serve multiple clients in parallel without making it to have a bottleneck , just because a client task didnt finished earlier? – Deadworldisee Apr 19 '11 at 19:01
  • Basically, it's this: http://www.php.net/manual/en/function.socket-select.php – Robin Apr 19 '11 at 19:50
  • I've added some client code to the WebSocks trunk (Google Code link above) - if you've got Google Chrome you can check it for yourself. You can connect up to 4 connections at the same time and chat to yourself :-). HTH. – Robin Apr 19 '11 at 20:04
  • Trying to port node.js to PHP? :) – Alix Axel May 21 '11 at 11:53
  • @Robin: Read http://blog.si.kz/index.php/2010/02/03/libevent-for-php – Alix Axel May 22 '11 at 12:19
  • @alix - no - not trying to port Node to PHP, although I reckon this could be done as a PHP SAPI. I wasn't trying to deter the questioner away from the libevent stuff, just help him understand what Async programming is. The fact that he's trying to fork new processes to serve clients suggested to me that he didn't fully understand the underlying concepts. – Robin May 22 '11 at 12:36
  • function.socket-select.php uses select() while libevent uses more powerful event notification systems like epoll() or kqueue()... Furthermore select() is restricted to around 1024 filedescriptors... Are there any improvements on your libevent+php-Code Deadworldisee? – Filipe Santos Nov 10 '11 at 00:52
  • http://code.google.com/p/web-socks/source/browse/trunk/WebSocks.php is dead. –  Nov 11 '15 at 00:07
  • http://blog.si.kz/index.php/2010/02/03/libevent-for-php stalled in 2011. –  Nov 11 '15 at 00:08

1 Answers1

5

While nanoserv is an excellent library, it does not use libevent. Infact the author himself has written, in his blog, that he would like to convert nanoserv to use libevent at some point of time. See his blog post here: http://blog.si.kz/index.php/2010/02/03/libevent-for-php

There is also a comment by Alix Axel on May 22 '11 at 12:19 regarding the same.

Update: A little more research led me to http://phpdaemon.net/ . It seems they are using libevent to build a whole host of network servers

Updated 30th May 2021: Recently there has been https://www.swoole.co.uk/ & https://reactphp.org/ which provide good async libraries for sockets.

phpdaemon has a new url at https://daemon.io/

Updated 31st August 2022: Swoole has now been forked into two separate projects: Open Swoole & Swoole

Amitabh Kant
  • 145
  • 2
  • 6