An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols. PHP>=5.3.

Overview

Workerman

Gitter Latest Stable Version Total Downloads Monthly Downloads Daily Downloads License

What is it

Workerman is an asynchronous event-driven PHP framework with high performance to build fast and scalable network applications. Workerman supports HTTP, Websocket, SSL and other custom protocols. Workerman supports event extension.

Requires

PHP 5.3 or Higher
A POSIX compatible operating system (Linux, OSX, BSD)
POSIX and PCNTL extensions required
Event extension recommended for better performance

Installation

composer require workerman/workerman

Basic Usage

A websocket server

<?php

use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

// Create a Websocket server
$ws_worker = new Worker('websocket://0.0.0.0:2346');

// 4 processes
$ws_worker->count = 4;

// Emitted when new connection come
$ws_worker->onConnect = function ($connection) {
    echo "New connection\n";
};

// Emitted when data received
$ws_worker->onMessage = function ($connection, $data) {
    // Send hello $data
    $connection->send('Hello ' . $data);
};

// Emitted when connection closed
$ws_worker->onClose = function ($connection) {
    echo "Connection closed\n";
};

// Run worker
Worker::runAll();

An http server

use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

// #### http worker ####
$http_worker = new Worker('http://0.0.0.0:2345');

// 4 processes
$http_worker->count = 4;

// Emitted when data received
$http_worker->onMessage = function ($connection, $request) {
    //$request->get();
    //$request->post();
    //$request->header();
    //$request->cookie();
    //$request->session();
    //$request->uri();
    //$request->path();
    //$request->method();

    // Send data to client
    $connection->send("Hello World");
};

// Run all workers
Worker::runAll();

A tcp server

use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

// #### create socket and listen 1234 port ####
$tcp_worker = new Worker('tcp://0.0.0.0:1234');

// 4 processes
$tcp_worker->count = 4;

// Emitted when new connection come
$tcp_worker->onConnect = function ($connection) {
    echo "New Connection\n";
};

// Emitted when data received
$tcp_worker->onMessage = function ($connection, $data) {
    // Send data to client
    $connection->send("Hello $data \n");
};

// Emitted when connection is closed
$tcp_worker->onClose = function ($connection) {
    echo "Connection closed\n";
};

Worker::runAll();

Enable SSL

<?php

use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

// SSL context.
$context = array(
    'ssl' => array(
        'local_cert'  => '/your/path/of/server.pem',
        'local_pk'    => '/your/path/of/server.key',
        'verify_peer' => false,
    )
);

// Create a Websocket server with ssl context.
$ws_worker = new Worker('websocket://0.0.0.0:2346', $context);

// Enable SSL. WebSocket+SSL means that Secure WebSocket (wss://). 
// The similar approaches for Https etc.
$ws_worker->transport = 'ssl';

$ws_worker->onMessage = function ($connection, $data) {
    // Send hello $data
    $connection->send('Hello ' . $data);
};

Worker::runAll();

Custom protocol

Protocols/MyTextProtocol.php

namespace Protocols;

/**
 * User defined protocol
 * Format Text+"\n"
 */
class MyTextProtocol
{
    public static function input($recv_buffer)
    {
        // Find the position of the first occurrence of "\n"
        $pos = strpos($recv_buffer, "\n");

        // Not a complete package. Return 0 because the length of package can not be calculated
        if ($pos === false) {
            return 0;
        }

        // Return length of the package
        return $pos+1;
    }

    public static function decode($recv_buffer)
    {
        return trim($recv_buffer);
    }

    public static function encode($data)
    {
        return $data . "\n";
    }
}
use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

// #### MyTextProtocol worker ####
$text_worker = new Worker('MyTextProtocol://0.0.0.0:5678');

$text_worker->onConnect = function ($connection) {
    echo "New connection\n";
};

$text_worker->onMessage = function ($connection, $data) {
    // Send data to client
    $connection->send("Hello world\n");
};

$text_worker->onClose = function ($connection) {
    echo "Connection closed\n";
};

// Run all workers
Worker::runAll();

Timer

use Workerman\Worker;
use Workerman\Timer;

require_once __DIR__ . '/vendor/autoload.php';

$task = new Worker();
$task->onWorkerStart = function ($task) {
    // 2.5 seconds
    $time_interval = 2.5; 
    $timer_id = Timer::add($time_interval, function () {
        echo "Timer run\n";
    });
};

// Run all workers
Worker::runAll();

AsyncTcpConnection (tcp/ws/text/frame etc...)

use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;

require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker();
$worker->onWorkerStart = function () {
    // Websocket protocol for client.
    $ws_connection = new AsyncTcpConnection('ws://echo.websocket.org:80');
    $ws_connection->onConnect = function ($connection) {
        $connection->send('Hello');
    };
    $ws_connection->onMessage = function ($connection, $data) {
        echo "Recv: $data\n";
    };
    $ws_connection->onError = function ($connection, $code, $msg) {
        echo "Error: $msg\n";
    };
    $ws_connection->onClose = function ($connection) {
        echo "Connection closed\n";
    };
    $ws_connection->connect();
};

Worker::runAll();

Available commands

php start.php start
php start.php start -d
workerman start
php start.php status
workerman satus
php start.php connections
php start.php stop
php start.php restart
php start.php reload

Documentation

中文主页:http://www.workerman.net

中文文档: http://doc.workerman.net

Documentation:https://github.com/walkor/workerman-manual

Benchmarks

https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext&l=zik073-1r

Other links with workerman

PHPSocket.IO
php-socks5
php-http-proxy

Donate

LICENSE

Workerman is released under the MIT license.

Comments
  • Save ::_statisticsFile at tmp folder is bad idea

    Save ::_statisticsFile at tmp folder is bad idea

    It is not good idea to save data at tmp folder via php. because only proccess what create or edit file at tmp folder can read it. when you try to get status Workerman can't unlink at firstly (see Worker.php line 932) , but add new information at the end

    And file will be very large (when i found this problem it was 40Gb)

    of course , you can edit your server setting with PrivateTmp=false but this problem is very actualy https://stackoverflow.com/questions/30444914/php-has-its-own-tmp-in-tmp-systemd-private-nabcde-tmp-when-accessed-through-ng

    opened by webrobot1 27
  • status not work

    status not work

    Workerman[tz.php] start in DAEMON mode
    ----------------------- WORKERMAN -----------------------------
    Workerman version:3.3.9          PHP version:7.1.2
    ------------------------ WORKERS -------------------------------
    user          worker        listen               processes status
    root          Proberv       http://0.0.0.0:2345   3         [OK] 
    ----------------------------------------------------------------
    Input "php tz.php stop" to quit. Start success.
    
    [XZB /opt/tz]# ls
    _opt_tz_tz.php.pid  online.json         tz.php              vendor              workerman.log
    [XZB /opt/tz]# php tz.php status
    Workerman[tz.php] status 
    [XZB /opt/tz]# php tz.php status
    Workerman[tz.php] status 
    Workerman[tz.php] not run
    [XZB /opt/tz]# php tz.php status
    Workerman[tz.php] status 
    Workerman[tz.php] not run
    

    实际上运行正常

    question 
    opened by wwng2333 19
  • LibEvent issue

    LibEvent issue

    When I switch to libevent I have this issue

    PHP Warning:  stream_set_blocking(): supplied resource is not a valid stream resource in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 263
    
    Warning: stream_set_blocking(): supplied resource is not a valid stream resource in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 263
    PHP Warning:  stream_set_read_buffer(): supplied resource is not a valid stream resource in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 266
    
    Warning: stream_set_read_buffer(): supplied resource is not a valid stream resource in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 266
    PHP Warning:  socket_import_stream(): supplied resource is not a valid stream resource in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 270
    
    Warning: socket_import_stream(): supplied resource is not a valid stream resource in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 270
    PHP Warning:  socket_set_option() expects parameter 1 to be resource, boolean given in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 271
    
    Warning: socket_set_option() expects parameter 1 to be resource, boolean given in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 271
    PHP Warning:  socket_set_option() expects parameter 1 to be resource, boolean given in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 272
    
    Warning: socket_set_option() expects parameter 1 to be resource, boolean given in /home/app/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 272
    PHP Warning:  event_set(): fd argument must be either valid PHP stream or valid PHP socket resource in /home/app/vendor/workerman/workerman/Events/Libevent.php on line 105
    
    Warning: event_set(): fd argument must be either valid PHP stream or valid PHP socket resource in /home/app/vendor/workerman/workerman/Events/Libevent.php on line 105
    PHP Warning:  event_set(): fd argument must be either valid PHP stream or valid PHP socket resource in /home/app/vendor/workerman/workerman/Events/Libevent.php on line 105
    
    Warning: event_set(): fd argument must be either valid PHP stream or valid PHP socket resource in /home/app/vendor/workerman/workerman/Events/Libevent.php on line 105
    
    
    question 
    opened by sm2017 18
  • Send data to all workers

    Send data to all workers

    Hello, I'm trying to create websocket server with 4 workers. Is any way to send data onMessage to all connections in existed workers?

    Also method Worker::getAllWorkers() returns only current worker.

    Thank You.

    question 
    opened by ImadBazzal 15
  • English docs

    English docs

    I really, really like workerman. After a few tests I did with it, I want to put it into my project under production. In order to really do so, I need to know more of the API. Like how to associate worker names, which on{...} methods exist and which variables can be set.

    Further, I would like to be able to give my server some arguments of its own. It will be started by a parent process and receive its arguments via command line. Can I still get the arguments for my script even after workerman took them?

    Kind regards, Ingwie.

    enhancement 
    opened by IngwiePhoenix 15
  • AsyncTcpConnection wss onMessage doesn't work

    AsyncTcpConnection wss onMessage doesn't work

    Hi! Thanks so much for a great library. Question about AsyncTcpConnection. Have wss server $context = [ 'ssl' => [ 'local_cert' =>x , 'local_pk' =>x , 'verify_peer' => false, ], ]; $wsWorker = new Worker( 'websocket://0.0.0.0:' . $port, $context ); $wsWorker->transport = 'ssl'; Js client works great with address 'wss:domain:port', but AsyncTcpConnection `$worker->onWorkerStart = function ( $worker ) {

    $connection            = new AsyncTcpConnection( 'websocket://domain:port' );
    $connection->transport = 'ssl';
    
    $connection->onConnect = function ( $connection ) {
    	echo "onConnect\n";
                $connection->send('test');
    };
    
    $connection->onMessage = function ( $connection, $data ) {
    	echo "onMessage\n";
    };
    
    $connection->onClose = function ( $connection ) {
    	echo "onClose\n";
    };
    
    $connection->onError = function ( $connection, $code, $msg ) {
    	echo "onError\n";
    };
    
    $connection->connect();
    

    };` doesn't working properly, means call only onConnect & onClose, also $connection->send return null & doesn't send any data. The connection exists, because it closes after a timeout specified on the server. What are the possible reasons? Thanks.

    opened by ghost 14
  • Debuging in production mode

    Debuging in production mode

    How can I detect in production mode and heavy loads , Which line of code is taking long times? I have stop fails in php start.php stop some times in heavy load and some strange behavior , hanging for minutes after hours of good working

    opened by sm2017 14
  • stop fail

    stop fail

    Can you tell me why sometimes workerman cannot stop itself?

    php index.php stop
    

    Workerman[index.php] stop Workerman[index.php] is stoping ... Workerman[index.php] stop fail

    Now I have an issue with workerman , I have ChatBusinessWorker , ChatGateway , Register And HttpServerWorker in my server when I start service all of them started , if I check status immediatly using

    php index.php status
    

    There is no problem sometimes but sometimes there is not HttpServerWorker , Why? I am sure there is no fatal error in this worker , but I know workerman reopen worker if it happens

    In this case , when there is no HttpServerWorker in status table php index.php stop always failed , after this when I check php index.php status , the result is

    3 workers 4 processes

    but no pid is listed

    question 
    opened by sm2017 14
  • Too many open files in vendor/composer/ClassLoader.php on line 571

    Too many open files in vendor/composer/ClassLoader.php on line 571

    @walkor

    Using "5.x-dev", I do wrk -c5000 -t1 -d5 "http://127.0.0.1:2345/" while open file descriptors is raised on both workerman and wrk end to 40,000.

    After running wrk for two or three times I get the following in the workerman's console.

    ----------------------------------------- WORKERMAN -----------------------------------------
    Workerman version:5.0.0    PHP version:8.1.3     Event-loop:\Workerman\Events\Select
    ------------------------------------------ WORKERS ------------------------------------------
    proto   user            worker          listen                 processes    status
    tcp     testing    none            http://0.0.0.0:2345    1             [OK]
    ---------------------------------------------------------------------------------------------
    Press Ctrl+C to stop. Start success.
    PHP Warning:  include(~/testing/vendor/workerman/workerman/src/Protocols/Http/Request.php): Failed to open stream: Too many open files in ~/testing/vendor/composer/ClassLoader.php on line 571
    PHP Warning:  include(): Failed opening '~/testing/vendor/composer/../workerman/workerman/src/Protocols/Http/Request.php' for inclusion (include_path='.:/opt/remi/php81/root/usr/share/pear:/opt/remi/php81/root/usr/share/php:/usr/share/pear:/usr/share/php') in ~/testing/vendor/composer/ClassLoader.php on line 571
    Error: Class "Workerman\Protocols\Http\Request" not found in ~/testing/vendor/workerman/workerman/src/Protocols/Http.php:176
    Stack trace:
    #0 ~/testing/vendor/workerman/workerman/src/Connection/TcpConnection.php(653): Workerman\Protocols\Http::decode()
    #1 ~/testing/vendor/workerman/workerman/src/Events/Select.php(334): Workerman\Connection\TcpConnection->baseRead()
    #2 ~/testing/vendor/workerman/workerman/src/Worker.php(2349): Workerman\Events\Select->run()
    #3 ~/testing/vendor/workerman/workerman/src/Worker.php(1495): Workerman\Worker->run()
    #4 ~/testing/vendor/workerman/workerman/src/Worker.php(1339): Workerman\Worker::forkOneWorkerForLinux()
    #5 ~/testing/vendor/workerman/workerman/src/Worker.php(1313): Workerman\Worker::forkWorkersForLinux()
    #6 ~/testing/vendor/workerman/workerman/src/Worker.php(541): Workerman\Worker::forkWorkers()
    #7 ~/testing/workerman.php(17): Workerman\Worker::runAll()
    #8 {main}
    PHP Warning:  file_put_contents(~/testing/vendor/workerman/workerman/src/../../workerman.log): Failed to open stream: Too many open files in ~/testing/vendor/workerman/workerman/src/Worker.php on line 2061
    worker[none:76797] exit with status 64000
    

    That's the code I'm using.

    <?php
    use Workerman\Worker;
    require_once __DIR__ . '/vendor/autoload.php';
    $http_worker = new Worker('http://0.0.0.0:2345');
    $http_worker->count = 1;
    $http_worker->onMessage = function ($connection, $request) {
        $connection->send("Hello, World!\n");
    };
    Worker::runAll();
    

    Any idea what's wrong?!

    opened by cayolblake 13
  • Problems with frames

    Problems with frames

    Hello. I have problems with transport data from client to server by websocket workerman connection (BUT server messages to client by local tcp worker without errors).

    Params: Client OS = windows 10; Server OS = centos 7 (it's local server in virtual machine); Browser = chromium based latest version (ws connection on other production service work good);

    Server side code:

    <?
    
    require_once __DIR__ . '/vendor/autoload.php';
    use Workerman\Worker;
    
    // Create a Websocket server
    $ws_worker = new Worker("websocket://0.0.0.0:8891");
    
    // 4 processes
    $ws_worker->count = 4;
    
    // Emitted when new connection come
    $ws_worker->onConnect = function($connection)
    {
    	echo "New connection\n";
    };
    
    // Emitted when data received
    $ws_worker->onMessage = function($connection, $data)
    {
    	// Send hello $data
    	$connection->send('hello ' . $data);
    };
    
    // Emitted when connection closed
    $ws_worker->onClose = function($connection)
    {
    	echo "Connection closed\n";
    };
    
    // Run worker
    Worker::runAll();
    

    Client side code:

    var ws = new WebSocket ('ws://nskuslugi.loc:8891');
    
    ws.onopen = function () {
    	console.log('Open');
    }
    
    ws.onmessage = function (e) {
    	console.log('Message:' + e.data);
    }
    
    ws.onclose = function () {
    	console.log('Close');
    }
    
    ws.onerror = function(){
    	console.log(e);
    }
    
    ws.send('Some data to send');
    ws.send('And more data');
    

    Browser error: "WebSocket connection to 'ws://nskuslugi.loc:8891/' failed: Could not decode a text frame as UTF-8." Server error: "frame not masked so close the connection".

    What am I doing wrong? Coded in JSON request and response, but the error is the same.

    P.S sorry for my English

    image image image

    opened by abramovantonru 13
  • All clients have the same identifier (1)

    All clients have the same identifier (1)

    Hi! I have many devices (WebSocket Client) and WebSocket Server. I want to send commands to clients, knowing their identifier. 1. I connected to the WebSocket server from different clients (Browser / Phone / ESP8266-Wifi), but id everywhere = 1. I decided that the problem is related to the same IP address of the devices, but no. I downloaded the original sample WebSocket server:

    `<?php require_once DIR . '/autoload.php'; use Workerman\Worker;

    // Create a Websocket server $ws_worker = new Worker("websocket://0.0.0.0:2342");

    // 4 processes $ws_worker->count = 4;

    // Emitted when new connection come $ws_worker->onConnect = function($connection) { echo "New Client: $connection->id\n"; };

    // Emitted when data received $ws_worker->onMessage = function($connection, $data) { // Send hello $data $connection->send('hello ' . $data); };

    // Emitted when connection closed $ws_worker->onClose = function($connection) { echo "Connection closed\n"; };

    // Run worker Worker::runAll();` That's what's in the console: https://imgur.com/a/kukJzKU

    How to fix it?

    opened by DeltaVetal26 11
  • How to send a message to the client from the backend server ?

    How to send a message to the client from the backend server ?

    Hey! First of all, I want to thank you for your library. I have a problem that I don't know how to solve yet.

    I have a chat in which I implemented sending simple messages, everything works fine. Now I want to send files and ran into a problem with large file sizes. I decided not to load the connection socket and send files directly to the backend server via form/data.

    BUT. How, after a successful send, initialize the user and send him a socket notification that his file was successfully sent? At the moment my code looks like this:

    ` $ws_worker = new Worker('websocket://'.config('websockets.server'));

    // Emitted when new connection come
    $ws_worker->onConnect = function (TcpConnection $connection) {
    
        $connection->onWebSocketConnect = function($connection) {
    
            if (isset($_GET['token']) && $token = PersonalAccessToken::findToken($_GET['token'])) {
                $user = $token->tokenable;
    
                $this->clients[$connection->id] = [
                    'user' => $user,
                    'connection' => $connection,
                ];
            }
            return;
        };
    };
    
    
    $ws_worker->onMessage = function (TcpConnection $connection, $message) {
    
        if (!array_key_exists($connection->id, $this->clients)) {
            echo "Error. User not authorized\n";
            return;
        }
    
        $sender = $this->clients[$connection->id];
    
        $data = json_decode($message, true);
    
        // send message to DB
    
        $connectionClientsUniques = ArrayHelper::arrayColumnsWithSaveKeys($this->clients, 'client_unique');
        $findedConnectionsClients = array_keys($connectionClientsUniques, $roomMember['client_unique'], true);
    
        foreach ($findedConnectionsClients as $findedConnectionClient) {
            // SEND MESSAGE FOR CONNECTION
        }
    };
    
    
    $ws_worker->onClose = function($connection)
    {
        echo "Close connection ID ".$connection->id."\n";
    
        if (array_key_exists($connection->id, $this->clients)) {
            unset($this->clients[$connection->id]);
            echo "FINDED CONNECTION ID  ".$connection->id." AND LOST CONNECTIONS - ".count($this->clients)." \n";
        }
    };
    
    // Run worker
    Worker::runAll();
    

    `

    My problem is that I don't know where to store active user sessions. So that I can access them from other parts of the project. Now they are stored in my clients variable in the same place where the websocket server starts. Should they be stored elsewhere? Where do you recommend? And also, please tell me how to send notifications to the desired connection from any part of the project. For example, I imagined it like this:

    ` send_alert.php

    <?php
    use Workerman\Worker;
    
    $ws_worker = new Worker('websocket://11.11.111.111');
    $ws_worker->findByConnection(...)->send($data);
    

    `

    opened by Muradg 1
  • Bug with multi server - they start listen port and get connection by another

    Bug with multi server - they start listen port and get connection by another

    Example:

    1. Start workerman Websocket server on port 8081 - all ok image

    2. Connect to server via another application (not workerman, client on local machine at c# language) - all ok image

    3. Start another workerman Websocket server on 8082 - all ok image

    4. Server point 1 (8081) create workerman AsyncTcpConnection to server from pint 3 (with port 8082) - all ok (doesnt matter wich server connect AsyncTcpConnection first) image

    5. Check after this 8081 port - not ok:

    • Master and Worker of server from point 3 (with 8082 port) start to listen 8081 port too (as Unix console say at the picture) image

    • additional this server from point 3 (port 8082) start to listen my client (what connect only to 8081 server from point 1) (as Lunix console say - you can see t the picture) image

    1. if i stop server from poit 1 (port 8081) server from point 3 still Listen the port 8081 and client from pint 2 now have Estabilished connection with server 3 (port 8082) image
    opened by webrobot1 17
  • Cloudflare universal ssl

    Cloudflare universal ssl

    How to work with cloudflare edge certificates? I can't run socket about of several days, because workerman requires certificate file but i can't catch it, because can't obtain certificate code and private key. How can i work with cloudflare universall ssl?

    opened by Raserad 0
  • reduced speed when running a server with openresty

    reduced speed when running a server with openresty

    Hi, doing direct benchmarks on the machine with Mark the speed is remarkable, but if I pass my connection through an api gateway with openresty doing the benchmark the speed drops a lot and I would like to understand how to improve it.

    opened by MrSipping 4
  • Use static anonymous functions

    Use static anonymous functions

    Will be good to change in all the code and examples.

    And explain that's better to use static.

    For performance and memory benefit.

    Anonymous functions when declared in the context of a class, the current class is automatically bound to it, making $this available inside of the function's scope. If this automatic binding of the current class is not wanted, then static anonymous functions may be used instead.

    opened by joanhey 1
  • SO_REUSEPORT option. How a child process gets its own listening socket?

    SO_REUSEPORT option. How a child process gets its own listening socket?

    Hi!) I have a similar question, discussed here: https://github.com/walkor/Workerman/issues/156

    I would like to understand how child process get it own listening socket. Master creates several listening sockets and then fork, after this each of workers inherits several sockets, and should close (decrease ref counter) all except one socket, and accept new connection from it? As a result all workers have independent queue for receiving request to connection?

    opened by creamsodainyourmouth 1
Releases(v3.5.34)
  • v3.5.34(Dec 16, 2022)

    What's Changed

    • fread(): Length parameter must be greater than 0 by @wandoubaba in https://github.com/walkor/workerman/pull/855

    New Contributors

    • @wandoubaba made their first contribution in https://github.com/walkor/workerman/pull/855

    Full Changelog: https://github.com/walkor/workerman/compare/v3.5.33...v3.5.34

    Source code(tar.gz)
    Source code(zip)
  • v4.1.5(Dec 14, 2022)

    • Websocket support deflate
    • Fix upload type error in extreme cases
    • Other optimizations

    Full Changelog: https://github.com/walkor/workerman/compare/v4.1.4...v4.1.5

    Source code(tar.gz)
    Source code(zip)
  • 4.0.43(Dec 14, 2022)

  • v3.5.33(Nov 17, 2022)

    What's Changed

    • AllowDynamicProperties https://github.com/walkor/workerman/issues/824#issuecomment-1317929999
    • Show event loop in displayUI by @joanhey in https://github.com/walkor/workerman/pull/836

    Full Changelog: https://github.com/walkor/workerman/compare/v3.5.32...v3.5.33

    Source code(tar.gz)
    Source code(zip)
  • v3.5.32(Oct 22, 2022)

    What's Changed

    • Fix Chinese filename bug by @MakeHui in https://github.com/walkor/workerman/pull/622
    • Add sendFile range support by @MakeHui in https://github.com/walkor/workerman/pull/628
    • Add session_regenerate_id() by @joanhey in https://github.com/walkor/workerman/pull/835

    New Contributors

    • @MakeHui made their first contribution in https://github.com/walkor/workerman/pull/622

    Full Changelog: https://github.com/walkor/workerman/compare/v3.5.31...v3.5.32

    Source code(tar.gz)
    Source code(zip)
  • v4.1.4(Oct 9, 2022)

  • v4.1.3(Sep 23, 2022)

  • v4.1.2(Sep 22, 2022)

    What's Changed

    • Fix bad interpreter: Text file busy by @Yurunsoft in https://github.com/walkor/workerman/pull/813
    • Fix no content-length by @Yurunsoft in https://github.com/walkor/workerman/pull/814

    Full Changelog: https://github.com/walkor/workerman/compare/v4.1.1...v4.1.2

    Source code(tar.gz)
    Source code(zip)
  • v4.1.1(Sep 19, 2022)

  • v4.1.0(Aug 20, 2022)

  • v4.0.42(Jul 29, 2022)

    • Fix multi upload files see #788
    • Add $worker-> onWorkerExit callback

    Full Changelog: https://github.com/walkor/workerman/compare/v4.0.41...v4.0.42

    Source code(tar.gz)
    Source code(zip)
  • v4.0.41(Jul 19, 2022)

  • v4.0.40(Jul 18, 2022)

    What's Changed

    • add FastCGI protocol to support FastCGI-Client application by @blogdaren in https://github.com/walkor/workerman/pull/784
    • Upload file optimiztions
    • Fix Session->gc()

    Full Changelog: https://github.com/walkor/workerman/compare/v4.0.39...v4.0.40

    Source code(tar.gz)
    Source code(zip)
  • v4.0.39(Jun 16, 2022)

  • v4.0.38(Jun 11, 2022)

    What's Changed

    • display Event-Loop UI item when start as debug mode by @blogdaren in https://github.com/walkor/workerman/pull/764
    • $response->cookie($key, $value, $max_age); when $max_age is 0 then remove the cookie

    Full Changelog: https://github.com/walkor/workerman/compare/v4.0.37...v4.0.38

    Source code(tar.gz)
    Source code(zip)
  • v4.0.37(May 17, 2022)

  • v4.0.36(Apr 29, 2022)

  • v4.0.35(Apr 28, 2022)

    What's Changed

    • php >= 5.4 required
    • Add libuv support by @blogdaren in https://github.com/walkor/workerman/pull/755
    • fix the libuv EventTimer which works unexpectedly in millisecond by @blogdaren in https://github.com/walkor/workerman/pull/756
    • Support Session::$cookieLifetime Session::$cookiePath etc
    • Other optimizations

    Full Changelog: https://github.com/walkor/workerman/compare/4.0.34...v4.0.35

    Source code(tar.gz)
    Source code(zip)
  • 4.0.34(Apr 21, 2022)

    • Workerman\Protocols\Http\Request::sessionId($sid) support sid param
    • Optimize multi file upload
    • Support RedisClusterSessionHandler
    • RedisSessionHandler support ping and reconnect
    • Support Workerman\Worker::$stopTimeout

    Full Changelog: https://github.com/walkor/workerman/compare/v4.0.33...4.0.34

    Source code(tar.gz)
    Source code(zip)
  • v4.0.33(Mar 29, 2022)

  • v4.0.31(Mar 23, 2022)

    What's Changed

    • Fix cookie Max-Age
    • Fix TypeError: strlen() expects parameter 1 to be string, int given by @Yurunsoft in https://github.com/walkor/workerman/pull/727

    Full Changelog: https://github.com/walkor/workerman/compare/v4.0.30...v4.0.31

    Source code(tar.gz)
    Source code(zip)
  • v4.0.30(Feb 28, 2022)

  • 4.0.29(Feb 25, 2022)

  • v4.0.28(Feb 19, 2022)

  • v4.0.27(Feb 11, 2022)

    What's Changed

    • Fix PHP 8.1 by @Yurunsoft in https://github.com/walkor/workerman/pull/701
    • update AsyncUdpConnection.php note by @LTaooo in https://github.com/walkor/workerman/pull/704
    • Do not modify the global variable $argv by @Yurunsoft in https://github.com/walkor/workerman/pull/708
    • Phar support. by @fuzqing in https://github.com/walkor/workerman/pull/712

    New Contributors

    • @LTaooo made their first contribution in https://github.com/walkor/workerman/pull/704
    • @fuzqing made their first contribution in https://github.com/walkor/workerman/pull/712

    Full Changelog: https://github.com/walkor/workerman/compare/v4.0.26...v4.0.27

    Source code(tar.gz)
    Source code(zip)
  • v4.0.26(Dec 21, 2021)

    Fix cookie() fail when first time set session. See https://github.com/walkor/webman-framework/issues/22 Full Changelog: https://github.com/walkor/workerman/compare/v4.0.25...v4.0.26

    Source code(tar.gz)
    Source code(zip)
  • v4.0.25(Dec 10, 2021)

  • v4.0.24(Dec 2, 2021)

  • v4.0.23(Dec 1, 2021)

    What's Changed

    • implement session updateTimestamp and refresh session expire time api by @lvshuang in https://github.com/walkor/Workerman/pull/686
    • compatible with php8.1

    Full Changelog: https://github.com/walkor/Workerman/compare/v4.0.22...v4.0.23

    Source code(tar.gz)
    Source code(zip)
  • v4.0.22(Oct 29, 2021)

Event-driven, non-blocking I/O with PHP.

Event-driven, non-blocking I/O with PHP. ReactPHP is a low-level library for event-driven programming in PHP. At its core is an event loop, on top of

ReactPHP 8.5k Jan 8, 2023
The Hoa\Websocket library.

Hoa is a modular, extensible and structured set of PHP libraries. Moreover, Hoa aims at being a bridge between industrial and research worlds. Hoa\Web

Hoa 419 Dec 30, 2022
Icicle is a PHP library for writing asynchronous code using synchronous coding techniques

Icicle is now deprecated in favor of Amp v2.0. This version is is currently under development, but close to release. The v2.0 branches are amp_v2 in a

icicle.io 1.1k Dec 21, 2022
Asynchronous coroutines for PHP 7.

Recoil An asynchronous coroutine kernel for PHP 7. composer require recoil/recoil The Recoil project comprises the following packages: recoil/api - T

Recoil 787 Dec 8, 2022
Infrastructure and testing helpers for creating CQRS and event sourced applications.

Broadway Broadway is a project providing infrastructure and testing helpers for creating CQRS and event sourced applications. Broadway tries hard to n

null 1.5k Dec 27, 2022
Événement is a very simple event dispatching library for PHP.

Événement Événement is a very simple event dispatching library for PHP. It has the same design goals as Silex and Pimple, to empower the user while st

Igor 1.2k Jan 4, 2023
A pragmatic event sourcing library for PHP with a focus on developer experience.

EventSaucePHP EventSauce is a somewhat opinionated, no-nonsense, and easy way to introduce event sourcing into PHP projects. It's designed so storage

EventSauce 685 Dec 31, 2022
PHP Application using DDD CQRS Event Sourcing with Hexagonal Architecture

PHP Application using DDD CQRS Event Sourcing with Hexagonal Architecture Application built with Ecotone Framework and powered by integrations with Pr

EcotoneFramework 65 Dec 27, 2022
Revolt is a rock-solid event loop for concurrent PHP applications.

Revolt is a rock-solid event loop for concurrent PHP applications.

Revolt PHP 586 Jan 2, 2023
[READ-ONLY] The event dispatcher library for CakePHP. This repo is a split of the main code that can be found in https://github.com/cakephp/cakephp

CakePHP Event Library This library emulates several aspects of how events are triggered and managed in popular JavaScript libraries such as jQuery: An

CakePHP 21 Oct 6, 2022
A non-blocking concurrency framework for PHP applications. 🐘

Amp is a non-blocking concurrency framework for PHP. It provides an event loop, promises and streams as a base for asynchronous programming. Promises

Amp 3.8k Jan 6, 2023
PHP 7.4 EventStore Implementation

Prooph Event Store Common classes and interface for Prooph Event Store implementations. Installation You can install prooph/event-store via composer b

null 532 Dec 9, 2022
Reactive extensions for PHP.

This package is abandoned. Use https://github.com/ReactiveX/RxPHP instead Rx.PHP Reactive extensions for PHP. The reactive extensions for PHP are a se

Alexander 208 Apr 6, 2021
Golang's defer statement for PHP

PHP Defer A defer statement originally comes from Golang. This library allows you to use defer functionality in PHP code. Usage <?php defer($context,

null 249 Dec 31, 2022
Reactive extensions for PHP

RxPHP Reactive extensions for PHP. The reactive extensions for PHP are a set of libraries to compose asynchronous and event-based programs using obser

ReactiveX 1.6k Dec 12, 2022
🚀 Coroutine-based concurrency library for PHP

English | 中文 Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++

Swoole Project 17.7k Jan 5, 2023
An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols. PHP>=5.3.

Workerman What is it Workerman is an asynchronous event-driven PHP framework with high performance to build fast and scalable network applications. Wo

walkor 10.2k Dec 31, 2022
Learning Websocket by creating Custom Websocket-server package provided by Laravel

Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling.

Chisty Md.Muzammel Hossain 3 Oct 25, 2022
Kit is a lightweight, high-performance and event-driven web services framework that provides core components such as config, container, http, log and route.

Kit What is it Kit is a lightweight, high-performance and event-driven web services framework that provides core components such as config, container,

null 2 Sep 23, 2022
Event-driven, streaming HTTP client and server implementation for ReactPHP

HTTP Event-driven, streaming HTTP client and server implementation for ReactPHP. This HTTP library provides re-usable implementations for an HTTP clie

ReactPHP 640 Dec 29, 2022