Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5
With OpenSwoole you can setup a TCP server or a HTTP server and use the following configuration options to maintain a long-running TCP connection:
open_tcp_keepalive
: Once set to true, you can use tcp_keepidle
, tcp_keepcount
, tcp_keepinterval
heartbeat_check_interval
: You can enable this, defined in seconds allowing you to keep connections open longer, you also set heartbeat_idle_time
as wellIn normal PHP programming and when using PHP-FPM everything is stateless, but when using OpenSwoole everything can be loaded into memory and reused. However, this poses a problem, for example, how can you use new code changes without having to restart an entire OpenSwoole HTTP server?
OpenSwoole has support for asynchronous or hot code reloading when using workers. You can reload code on the fly without having to restart the entire server and wait for workers to complete requests before restarting. This can only be accomplished when you include files within onWorkerStart
event, anything before it, for example, the current OpenSwoole runtime, cannot be hot reloaded.
Please refer to the hot code reloading documentation.
All coroutines in OpenSwoole need to be wrapped inside a coroutine context, this context is automatically created for you when you use the HTTP Server for example.
However, if you receive errors saying Uncaught Error: Call to undefined function co::run()
or Uncaught Error: Call to undefined function go()
, you must make sure you are on version v4.4.0
or above or include the namespace OpenSwoole\Coroutine
.
You can also use OpenSwoole\Coroutine::create(callable $function, ...$args): int|false
which is an alternative to go()
.
No, it is not possible to share one connection (Redis or MySQL) between multiple coroutines. It would not be possible to read or write at the same time using one connection.
You cannot share connections, but you can keep them open via connection pools. A connection pool allows you to store multiple connections that can be used by many coroutines and put back when they have been used and no longer needed, you can read more about connection pools here.
When using OpenSwoole, especially the HTTP Server, you may come across the following messages in the console:
NOTICE swFactoryProcess_finish (ERRNO 1004): send 165 byte failed, because connection[fd=123] is closed
NOTICE swFactoryProcess_finish (ERROR 1005): connection[fd=123] does not exists
When seeing these messages, they are only notices and nothing to be worried about. These messages are shown due to one of the following:
ab
Canceled at half of the pressure test when benchmarkingwrk
time-based pressure test (unfinished requests will be cancelled when the time is up)The situation above is normal, they are only notice messages.
If you are receiving any of the following errors:
WARNING swWorker_discard_data (ERRNO 1007): [2] received the wrong data[21 bytes] from socket#75
WARNING Worker_discard_data (ERRNO 1007): [2] ignore data[5 bytes] received from session#2
This is something you should take a look into, the errors above mean you have a large number of connections being disconnected and probably need to check your configuration with discard_timeout_request
option for the server.
If you are receiving connection refused errors on your browser or client, it likely means you are not accessing the right IP address or port where you have your OpenSwoole server running.
ps aux
netstat -lp
tcpdump traceroute
This error usually refers to the OpenSwoole\Client
module.
When getting the following error:
swoole_client::recv(): recv() failed. Error: Resource temporarily unavailable [11]
It indicates that the server did not return data within the specified time, and the connection timed out.
tcpdump
to check whether the server has sent data$serv->send()
needs to be true
If you come across the following:
WARNING swWorker_reactor_try_to_exit (ERRNO 9012): worker exit timeout, forced to terminate
Indicates that the worker process did not exit within the agreed time (max_wait_time
seconds), and OpenSwoole forcibly terminates the worker process.
You should increase the timeout or make sure your workload can keep within the max_wait_time
configuration option. However, this is only likely to be an issue when shutting down or restarting a server.
WARNING swSignalfd_onSignal (ERRNO 707): Unable to find callback function for signal Broken pipe: 13
Indicates that data is sent to a disconnected connection, usually because the return value of the send is not checked and the return fails and continues to send.
When using OpenSwoole\Runtime::HOOK_CURL
you can encounter these errors:
PHP Notice: Object of class OpenSwoole\Curl\Handler could not be converted to int
PHP Warning: curl_multi_add_handle() expects parameter 2 to be resource, object given
When CURL is hooked it is no longer a resource type but an object type so the conversion to an int
is not supported.
The best solution to get around this is to use OpenSwoole\Runtime::HOOK_NATIVE_CURL
instead as OpenSwoole now has full support for native CURL since v4.6.0
.
You could also use Guzzle's SDK to replace the handler as well.
When using hooked coroutines and Guzzle 7.0 + at the same time, after initiating the request, the result will be directly output to the terminal.
Please update to at least v4.5.8
as this has been fixed.
This error can be ignored. This error is that the socket_buffer_size
option is too large, which is not accepted by individual systems, and does not affect the operation of the program.
The GET request has only one Http header. OpenSwoole uses a fixed-size memory buffer of 8K, and it cannot be modified. If the request is not a correct Http request, an error will occur. The following error will be thrown:
WARN swReactorThread_onReceive_http_request: http header is too long.
The maximum size is limited by the package_max_length
, the default is 2M, you can call Server->set to pass in a new value to modify the size. OpenSwoole runs in memory, so if it is set too large, it may cause a large number of concurrent requests to exhaust server resources.
It is probably best to chunk uploads instead when handling large files being uploaded.
OpenSwoole is installed via a PHP PECL extension and requires you to configure and compile before using in your applications.
You may wish to check how OpenSwoole is configured at a later date, to do so, you can use php --ri openswoole
which will show something similar to:
openswoole
Open Swoole => enabled
Author => Open Swoole Group <[email protected]>
Version => 22.0.0
Built => Sep 13 2022 17:44:32
coroutine => enabled with boost asm context
kqueue => enabled
rwlock => enabled
sockets => enabled
openssl => OpenSSL 3.0.5 5 Jul 2022
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
pcre => enabled
c-ares => 1.18.1
zlib => 1.2.11
brotli => E16777225/D16777225
mysqlnd => enabled
postgresql => enabled
Directive => Local Value => Master Value
openswoole.enable_coroutine => On => On
openswoole.enable_preemptive_scheduler => Off => Off
openswoole.display_errors => On => On
openswoole.unixsock_buffer_size => 262144 => 262144
If you need to reconfigure OpenSwoole with different settings, you can use for example:
#!/bin/bash
pecl install --configureoptions 'enable-sockets="no" enable-openssl="yes" enable-http2="yes" enable-mysqlnd="yes" enable-hook-curl="yes"' openswoole
More information is on the installation page.
If you are receiving errors related with too many PDO connections open, you either need to increase your max_connections
in your MySQL config files to allow more DB connections to be created or make use of a connection pool. A connection pool allows you to reuse PDO connections after opening one, reducing the latency of creating and destroying a TCP database connection. When using a database connection pool you need to make sure to put the connection back into the pool, otherwise that connection won't be able to be reused on another requests, thus, being left open and resulting in too many PDO connections errors.
You may encounter this error if you are opening a connection pool for each OpenSwoole worker process, this means you have a pool for each worker. For example, if you have 4 workers, and they have 10 PDO connections each, you end up with 40 PDO connections open, in this case, you have to make sure your MySQL server supports this number of open connections.
export PHP_VERSION=8.2
export CI_BRANCH=master
./ci/route.sh