Swoole Server Events and Callbacks

The swoole is an an high-performance network framework uses an event-driven, asynchronous, non-blocking I/O model makes it scalable and efficient. All the business logic is written within the callback functions. When a certain event is emitted, the callback function registered on the event is executed.

Event and Callback Functions List

  • onStart
  • onShutdown
  • onWorkerStart
  • onWorkerStop
  • onTimer
  • onConnect
  • onReceive
  • onPacket
  • onClose
  • onTask
  • onFinish
  • onPipeMessage
  • onWorkerError
  • onManagerStart
  • onManagerStop

onStart

When the Swoole server starts, the event start emits and execute the callback function registered on start event in the master process.

Before the start event emiting, the swoole server has finished the steps:

  • Create the manager process
  • Create the worker processes
  • Listen on the TCP/UDP Port
  • Listen on the Swoole Timer

After the start event, the reactors are ready to receive event and connections.

In the callback function registered on start, only allows limited functions such as logging, record and modify the name of process, record the process ID etc.

The events start and WorkerStart are emitted concurrently in different worker processes.

It is recommended to save the value of $server->master_pid and $server->manager_pid into file at the onStart callback function. Then you are able to send signals to control these processes.

This stage can't be used in SWOOLE_BASE mode.

Example

<?php
function onStart(Swoole\Server $server){

}

onShutdown

The event shutdown is emitted when the Swoole server shutting down.

Before the event shutdown is emitted, these steps are finished:

  • All threads are finished.
  • All the worker processed are finished.
  • The TCP/UDP ports is closed.
  • The reactor is closed.

Force killing a process using kill -9, doesn't trigger the callback function on shutdown. Use signal SIGTREM and kill -15 instead.

Example

<?php
function onShutdown(Swoole\Server $server)

onWorkerStart

The event workerStart is emitted when a worker process or task worker process is starting.

Based to the value of $worker_id, if $worker_id >= $server->setting['worker_num'], the worker is a task worker process otherwise it is a normal worker process.

There is no relationship between worker_id and pid of process.

Example

<?php
function onWorkerStart(Swoole\Server $server, int $worker_id)

Usage

Modify the process name when a new worker process starts.

<?php
$serv->on('WorkerStart', function ($serv, $worker_id){
    global $argv;
    if($worker_id >= $serv->setting['worker_num']) {
        swoole_set_process_name("php {$argv[0]} task worker");
    } else {
        swoole_set_process_name("php {$argv[0]} event worker");
    }
});

onWorkerStop

This event workerStop is emitted when a the worker process is stopping.

In the callback function registered on event workerStop, you can retrieve or release the resource for the worker process which is stopping.

The abnormal stop of a worker process doesn't trigger the event workerStop, such as fatal error or core dump doesn't trigger workerStop event.

Example

<?php
function onWorkerStop(Swoole\Server $server, int $worker_id);

onTimer

The event timer is emitted when the timer ticks.

Example

<?php
function onTimer(Swoole\Server $server, int $interval);

$interval is the interval set by the timer.

A timer is added to the server with $server->addTimer.

onConnect

This event connect happens when the new connection comes. And the worker process will call the callback function registered for the event connect.

In the mode UDP, there is only receive event and there is no connect and close event.

Example

<?php
function onConnect(Swoole\Server $server, int $fd, int $from_id);
  • $fd the id number of client

  • $from_id the id number of reactor thread

onReceive

The event receive is emitted when a worker process is receiving data.

The callback function registered on the event receive is executed in the worker process which is receiving data.

Example

<?php
function onReceive(Swoole\Server $server, int $fd, int $reactor_id, string $data)
  • $server the Swoole Server object

  • $fd If the Swoole Server is in TCP mode, it's FD of the client. If the Swoole Server is in UDP mode, it's the value of client ip which has been calculated by some algorithm.

  • $reactor_id If the Swoole Server is in TCP mode, it's the id number of reactor thread. If the Swoole Server is in UDP mode, it's the value of client port which has been calculated by some algorithm.

  • $data the data received from the client. If the configurations about automatic protocal hasn't been setted, the max length of data that worker process could receive is 64KB.

On the TCP mode, there is no boundary in the data transmits between client and server. It is necessary to set the configuration (eof_check/length_check/http_protocol) about how to split the stream into package or convert the data into package manually.

onPacket

The event packet is emitting when a worker process receiving UDP package.

Example

<?php
function onPacket(Swoole\Server $server, string $data, array $client_info)
  • $data the UDP package received

  • $client_info, this data is an array. php Array ( [server_socket] => 4 [server_port] => 9501 [address] => 127.0.0.1 [port] => 47306 )

If Swoole Server is listening on both TCP and UDP ports, the callback function onReceive is called when TCP data is received and the callback function onPacket is called when UDP data is received.

Data transformation

Transform the data into the $fd and reactor_id of callback function onReceive

<?php
$fd = unpack('L', pack('N', ip2long($addr['address'])))[1];
$reactor_id = ($addr['server_socket'] << 16) + $addr['port'];

onClose

The event close is emitted when a TCP connection between the client and the server is closed.

Example

<?php
function onClose(Swoole\Server $server, int $fd, int $reactorId);
  • $server the swoole server object

  • $fd the id number of client

  • $reactorId the id number of reactor thread, when the $reactorId < 0, the connection is closed by server.

onBufferFull

The event bufferfull happens when the buffer watermark is highest.

Example

<?php
function onBufferFull(Swoole\Server $serv, int $fd)
  • Set the configuration server->buffer_high_watermark to control the buffer high watermark
  • When the event bufferfull is triggered, it should not send data to client any more.

onBufferEmpty

The event bufferempty happens when the buffer watermark is lowest.

Example

<?php
function onBufferEmpty(Swoole\Server $serv, int $fd)
  • Set the configuration server->buffer_low_watermark to control the buffer low watermark
  • When the event bufferempty is triggered, it could send data to client.

onTask

The event task is emitted when a worker process sending task data to a task worker process pool.

The task worker process which is receiveing task data calls the callback function registered on the event task.

When a task worker process is processing the task, it's status is changed to be busy and the status is changed to be idle when finishing the task.

Example

<?php
function onTask(Swoole\Server $server, int $task_id, int $src_worker_id, mixed $data);
  • $server the Swoole Server object
  • $task_id the id number of task, the combination of $task_id and $src_worker_id is an unique identification for task
  • $data the task data

Return task result to worker process

In the callback function registered on event task, the return value of this function which is the result of task will be sent to the worker process which was senting the task. You can also return the result of a task by calling Swoole\Server->finish().

When the worker process is receiveing the task result, the event finish is triggered and execute the callback function on event finish.

onFinish

This callback function is executed when a task is finished, the result senting back to the worker process.

Example

<?php
function onFinish(Swoole\Server $server, int $task_id, mixed $data)
  • $serv the swoole server object

  • $task_id the id number of task

  • $data the result of task

onPipeMessage

When a worker process or task worker process is receiving the message sent by sendMessage.

Example

<?php
function onPipeMessage(Swoole\Server $server, int $from_worker_id, mixed $message);
  • $from_worker_id the id number of worker when the message from

  • $message the message

onWorkerError

When there is error or exception in the worker process or task worker process, the event workererror happens in the manager process.

The callback function registered for event workererror is called in manager process.

Example

<?php
function onWorkerError(Swoole\Server $server, int $worker_id, int $worker_pid, int $exit_code, int $signal);
  • $worker_id the id number of worker

  • $worker_pid the pid of worker process

  • $exit_code the exit code of worker process

  • $signal the exit signal of worker process

onManagerStart

The event managerStart is emitted when the manager process starts.

The callback function registered for event managerstart is called in the manager process.

Example

<?php
function onManagerStart(Swoole\Server $server);

onManagerStop

The event managerstop is emitted when the manager process stops.

The callback function registered for event managerstop is called in the manager process.

Example

<?php
function onManagerStop(Swoole\Server $server);

Order of events

  • All the callback functions of events are triggered after the start of swoole server.

  • The last event of swoole server is onShutdown when the swoole server shutdowns.

  • After starting the swoole server, the callback functions of onStart/onManagerStart/onWorkerStart are triggered in different process.

Catch Exception

The swoole doesn't support the set_exception_handler function.

If there is the logic of throwing exception in your code, it must add the try/catch in the very beginning of callback function.

<?php
$server->on('Timer', function() {
    try
    {
        //some code
    }
    catch(Exception $e)
    {
        //exception code
    }
}

Example

Example of registering event callback functions:

<?php
$server = new Swoole\Server("127.0.0.1", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP);
$server->on('WorkerStart', function($serv, $workerId) {
    var_dump(get_included_files());
});