### Compile and Install Swoole from Source Source: https://github.com/swoole/swoole-src/blob/master/README.md Compiles and installs the Swoole PHP extension from its source code. This method requires cloning the repository, configuring the build, and then compiling and installing. ```shell git clone --branch v6.0.0 --single-branch https://github.com/swoole/swoole-src.git && \ cd swoole-src phpize && \ ./configure && \ make && make install ``` -------------------------------- ### Implement Shared Memory Tables Source: https://context7.com/swoole/swoole-src/llms.txt Shows how to initialize a high-performance shared memory table for cross-process data access. It includes examples of atomic operations like set, get, increment, and delete. ```php column('id', Swoole\Table::TYPE_INT); $table->column('name', Swoole\Table::TYPE_STRING, 64); $table->column('score', Swoole\Table::TYPE_FLOAT); $table->column('active', Swoole\Table::TYPE_INT, 1); $table->create(); $server = new Swoole\Http\Server('127.0.0.1', 9501); $server->set(['worker_num' => 4]); $server->on('request', function ($request, $response) use ($table) { $action = $request->get['action'] ?? 'get'; $key = $request->get['key'] ?? 'user1'; switch ($action) { case 'set': $table->set($key, [ 'id' => rand(1, 1000), 'name' => $request->get['name'] ?? 'Guest', 'score' => (float)($request->get['score'] ?? 0), 'active' => 1 ]); $response->end("Set {$key} successfully"); break; case 'get': $data = $table->get($key); $response->end(json_encode($data ?: ['error' => 'Not found'])); break; case 'incr': $table->incr($key, 'score', 1.5); $response->end("Incremented score for {$key}"); break; case 'del': $table->del($key); $response->end("Deleted {$key}"); break; case 'count': $response->end("Table has {$table->count()} rows"); break; case 'list': $all = []; foreach ($table as $key => $row) { $all[$key] = $row; } $response->end(json_encode($all)); break; } }); $server->start(); ``` -------------------------------- ### Install swoole_async Extension Source: https://github.com/swoole/swoole-src/blob/master/README.md Installs the `swoole_async` extension, which contains async clients and APIs moved from the main Swoole extension since version 4.3.0. This involves cloning the extension's repository, configuring, compiling, and installing. ```shell git clone https://github.com/swoole/ext-async.git cd ext-async phpize ./configure make -j 4 sudo make install ``` -------------------------------- ### HTTP Server Basic Setup Source: https://context7.com/swoole/swoole-src/llms.txt This snippet demonstrates how to create a basic Swoole HTTP server, set worker processes, enable coroutine hooks, and configure upload limits. ```APIDOC ## Swoole HTTP Server Setup ### Description This example shows the fundamental setup for a Swoole HTTP server, including specifying the host and port, configuring server settings like `worker_num` and `hook_flags`, and handling the `start` event to indicate the server is running. ### Method N/A (Server Initialization) ### Endpoint N/A (Server Initialization) ### Parameters #### Server Settings - **worker_num** (int) - Optional - The number of worker processes to spawn. - **hook_flags** (int) - Optional - Flags to enable runtime hooks for coroutines (e.g., `SWOOLE_HOOK_ALL`). - **upload_max_filesize** (int) - Optional - Maximum size for uploaded files in bytes. ### Request Example N/A ### Response #### Success Response (Start Event) - **Output**: Echoes a message to the console indicating the server has started. #### Response Example ``` HTTP Server started at http://127.0.0.1:9501 ``` ``` -------------------------------- ### Install Swoole via PECL Source: https://github.com/swoole/swoole-src/wiki/Installing The PECL method provides a simplified installation process for the Swoole extension. It automatically handles the download and compilation steps. ```shell pecl install swoole ``` -------------------------------- ### Install Swoole Project Artifacts Source: https://github.com/swoole/swoole-src/blob/master/CMakeLists.txt This section defines the installation rules for the swoole-src project. It specifies where the extension library, static libraries, and header files should be placed on the target system during the installation process. ```cmake INSTALL(TARGETS ext-swoole LIBRARY DESTINATION ${PHP_EXTENSION_DIR}) INSTALL(TARGETS lib-swoole LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) INSTALL(FILES ${HEAD_FILES} DESTINATION include/swoole) INSTALL(FILES ${HEAD_WAPPER_FILES} DESTINATION include/swoole/wrapper) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/config.h DESTINATION include/swoole) ``` -------------------------------- ### Configure Swoole Compilation Options Source: https://github.com/swoole/swoole-src/blob/master/README.md Provides examples of extra compiler configurations that can be passed to the `./configure` script to enable specific features like OpenSSL, sockets, MySQLnd, or Swoole-cURL. ```shell ./configure --enable-openssl --enable-sockets ``` -------------------------------- ### Build and Install Googletest for Swoole Core Tests Source: https://github.com/swoole/swoole-src/blob/master/docs/TESTS.md This snippet outlines the steps to download, compile, and install the Googletest framework, which is a dependency for Swoole's core C++ unit tests. It requires GCC/G++ version 8.0+ and C++17 support. ```shell wget https://github.com/google/googletest/releases/download/v1.15.2/googletest-1.15.2.tar.gz tar zxf googletest-1.15.2.tar.gz cd googletest-1.15.2 mkdir ./build && cd ./build cmake .. make -j sudo make install ``` -------------------------------- ### Schedule Tasks with Timers Source: https://context7.com/swoole/swoole-src/llms.txt Provides examples of using periodic and one-time timers within the Swoole event loop. It also demonstrates how to manage timer lifecycles and use coroutine-based sleep for iterative tasks. ```php 0]; for ($i = 0; $i < 4; $i++) { $pid = pcntl_fork(); if ($pid === 0) { for ($j = 0; $j < 10; $j++) { $rwlock->lock_read(); echo "Process {$i} read: {$sharedData['count']}\n"; $rwlock->unlock(); usleep(rand(1000, 5000)); } exit(0); } } for ($i = 0; $i < 5; $i++) { $rwlock->lock(); $sharedData['count']++; echo "Writer updated count to: {$sharedData['count']}\n"; $rwlock->unlock(); usleep(10000); } while (pcntl_wait($status) > 0); $mutex = new Swoole\Lock(SWOOLE_MUTEX); if ($mutex->trylock()) { echo "Got lock immediately\n"; $mutex->unlock(); } else { echo "Lock is busy, doing something else\n"; } ``` -------------------------------- ### Enable swoole_async Extension in php.ini Source: https://github.com/swoole/swoole-src/blob/master/README.md Adds the necessary line to the php.ini configuration file to enable the `swoole_async` extension after it has been compiled and installed. ```ini extension=swoole_async.so ``` -------------------------------- ### Coroutine Sleep Example Source: https://github.com/swoole/swoole-src/blob/master/README.md A simple example demonstrating the use of `Co::sleep()` for non-blocking delays within a coroutine. ```APIDOC ## Coroutine Sleep Example ### Description This example illustrates how to use `Co::sleep()` within a coroutine to introduce a non-blocking delay. The coroutine performs a task, sleeps, and repeats until a condition is met. ### Method N/A (Illustrative Code) ### Endpoint N/A ### Parameters N/A ### Request Example ```php go(function () { $i = 0; while (true) { Co::sleep(0.1); echo "📝 Do something...\n"; if (++$i === 5) { echo "🛎 Done\n"; break; } } echo "🎉 All right!\n"; }); ``` ### Response N/A ``` -------------------------------- ### Enable Swoole Extension in php.ini Source: https://github.com/swoole/swoole-src/blob/master/README.md Adds the necessary line to the php.ini configuration file to enable the Swoole extension after it has been compiled and installed. ```ini extension=swoole.so ``` -------------------------------- ### Enable ASan Debugging in Swoole Tests via Git Commit Source: https://github.com/swoole/swoole-src/blob/master/docs/WORKFLOW-PARAMETERS.md This example demonstrates how to enable AddressSanitizer (ASan), a fast memory error detector, for the test program by including the `--asan` parameter in the Git commit message. ASan helps in detecting memory errors like buffer overflows and use-after-free bugs. ```shell git commit -m "commit message --asan" ``` -------------------------------- ### Combine Workflow Filtering and Debugging with Git Commit Source: https://github.com/swoole/swoole-src/blob/master/docs/WORKFLOW-PARAMETERS.md This example illustrates how to combine multiple workflow control parameters in a single Git commit message. It shows the use of `--filter` to select specific workflows and `--valgrind` to enable Valgrind debugging, providing a comprehensive way to manage test execution and analysis. ```shell git commit -m "commit message --filter=[core][unit] --valgrind" ``` -------------------------------- ### Initialize and Configure Swoole Server Source: https://github.com/swoole/swoole-src/wiki/Classes This snippet demonstrates how to create a new Swoole Server instance, configure it with worker processes and daemonization, and register event handlers for client connections, data reception, and disconnections. ```php use Swoole\Server; $serv = new Server('127.0.0.1', 9501); $serv->set(array( 'worker_num' => 8, 'daemonize' => true, )); $serv->on('connect', function ($serv, $fd){ echo "Client:Connect.\n"; }); $serv->on('receive', function ($serv, $fd, $from_id, $data) { $serv->send($fd, 'Swoole: '.$data); $serv->close($fd); }); $serv->on('close', function ($serv, $fd) { echo "Client: Close.\n"; }); $serv->start(); ``` -------------------------------- ### Create an HTTP Server with Coroutines Source: https://github.com/swoole/swoole-src/blob/master/README.md Demonstrates how to initialize an HTTP server and use coroutines to perform concurrent HTTP requests. ```php $http = new Swoole\Http\Server('127.0.0.1', 9501); $http->set(['hook_flags' => SWOOLE_HOOK_ALL]); $http->on('request', function ($request, $response) { $result = []; Co::join([ go(function () use (&$result) { $result['google'] = file_get_contents("https://www.google.com/"); }), go(function () use (&$result) { $result['taobao'] = file_get_contents("https://www.taobao.com/"); }) ]); $response->end(json_encode($result)); }); $http->start(); ``` -------------------------------- ### Create HTTP/2 Server with SSL Source: https://context7.com/swoole/swoole-src/llms.txt Demonstrates setting up a Swoole HTTP server with HTTP/2 protocol enabled, SSL/TLS support, and resource pushing capabilities. It includes configuration for static file handling and header management. ```php $http = new Swoole\Http\Server('0.0.0.0', 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); $http->set([ 'worker_num' => 4, 'open_http2_protocol' => true, 'ssl_cert_file' => '/path/to/ssl.crt', 'ssl_key_file' => '/path/to/ssl.key', 'enable_static_handler' => true, 'document_root' => '/var/www/public', ]); $http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { if ($request->server['request_uri'] === '/') { $response->push('/style.css', [ 'content-type' => 'text/css', ]); } $response->header('Content-Type', 'text/html; charset=utf-8'); $response->header('Cache-Control', 'max-age=3600'); $response->end('

HTTP/2 Server

'); }); $http->start(); ``` -------------------------------- ### Compile Swoole from Source Source: https://github.com/swoole/swoole-src/wiki/Installing This process involves cloning the repository, preparing the build environment with phpize, configuring the build, and compiling the extension. After compilation, you must manually add the extension to your php.ini file. ```shell git clone https://github.com/swoole/swoole-src.git cd swoole-src phpize ./configure make && make install ``` -------------------------------- ### Pipelining Commands Source: https://github.com/swoole/swoole-src/blob/master/thirdparty/hiredis/README.md Demonstrates how to use `redisAppendCommand` and `redisAppendCommandArgv` to queue commands for pipelined execution, followed by `redisGetReply` to retrieve the results. ```APIDOC ## Pipelining Commands ### Description This section explains how to implement command pipelining in Hiredis using `redisAppendCommand` and `redisAppendCommandArgv`. Pipelining allows sending multiple commands to the Redis server without waiting for each reply, improving performance by reducing network round trips. ### Functions - `void redisAppendCommand(redisContext *c, const char *format, ...)`: Appends a formatted command to the output buffer. - `void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen)`: Appends a command with arguments to the output buffer. - `redisReply *redisGetReply(redisContext *c, void **reply)`: Retrieves the next reply from the input buffer or by writing the output buffer to the socket and reading the reply. ### Request Example ```c redisReply *reply; redisAppendCommand(context,"SET foo bar"); redisAppendCommand(context,"GET foo"); redisGetReply(context,&reply); // reply for SET freeReplyObject(reply); redisGetReply(context,&reply); // reply for GET freeReplyObject(reply); ``` ### Use Case: Blocking Subscriber ```c redisReply *reply; reply = redisCommand(context,"SUBSCRIBE foo"); freeReplyObject(reply); while(redisGetReply(context,&reply) == REDIS_OK) { // consume message freeReplyObject(reply); } ``` ``` -------------------------------- ### Manage Child Processes with Swoole Source: https://context7.com/swoole/swoole-src/llms.txt Demonstrates how to spawn multiple worker processes, facilitate inter-process communication via pipes, and handle process lifecycle events like termination signals. ```php read(); if ($data === '') break; echo "Worker {$worker->pid} received: {$data}\n"; $result = strtoupper($data); $worker->write("Processed: {$result}"); } }, false, SOCK_DGRAM); $pid = $process->start(); $workers[$pid] = $process; } Swoole\Process::signal(SIGCHLD, function ($signo) use (&$workers) { while ($ret = Swoole\Process::wait(false)) { $pid = $ret['pid']; echo "Worker {$pid} exited with status {$ret['code']}\n"; unset($workers[$pid]); } }); foreach ($workers as $pid => $process) { $process->write("hello from master"); $response = $process->read(); echo "Master received: {$response}\n"; } Swoole\Timer::tick(1000, function () use (&$workers) { echo "Active workers: " . count($workers) . "\n"; }); ``` -------------------------------- ### Implement Multi-Protocol Server Source: https://github.com/swoole/swoole-src/blob/master/README.md Creates a unified server instance handling HTTP, WebSocket, and TCP protocols simultaneously on a single event loop. Includes helper functions for TCP packet framing. ```php function tcp_pack(string $data): string { return pack('N', strlen($data)) . $data; } function tcp_unpack(string $data): string { return substr($data, 4, unpack('N', substr($data, 0, 4))[1]); } $tcp_options = [ 'open_length_check' => true, 'package_length_type' => 'N', 'package_length_offset' => 0, 'package_body_offset' => 4 ]; $server = new Swoole\WebSocket\Server('127.0.0.1', 9501, SWOOLE_BASE); $server->set(['open_http2_protocol' => true]); $server->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { $response->end('Hello ' . $request->rawcontent()); }); $server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) { $server->push($frame->fd, 'Hello ' . $frame->data); }); $tcp_server = $server->listen('127.0.0.1', 9502, SWOOLE_TCP); $tcp_server->set($tcp_options); $tcp_server->on('receive', function (Swoole\Server $server, int $fd, int $reactor_id, string $data) { $server->send($fd, tcp_pack('Hello ' . tcp_unpack($data))); }); $server->start(); ``` -------------------------------- ### HTTP/2 Server with SSL/TLS Source: https://context7.com/swoole/swoole-src/llms.txt This snippet shows how to create a high-performance HTTP/2 server using Swoole, complete with SSL/TLS support for secure connections. It includes configurations for worker processes, HTTP/2 protocol, SSL certificates, static file handling, and demonstrates server push functionality. ```APIDOC ## HTTP/2 Server Create an HTTP/2 server with SSL/TLS support for modern, efficient web services with multiplexed streams and header compression. ### Description This endpoint demonstrates the creation of an HTTP/2 server with SSL/TLS support. It is configured to handle requests efficiently, supports server push, and can serve static files. ### Method N/A (Server setup) ### Endpoint N/A (Server setup) ### Parameters #### Server Settings - `worker_num` (int) - Optional - Number of worker processes. - `open_http2_protocol` (bool) - Required - Enables HTTP/2 protocol. - `ssl_cert_file` (string) - Required - Path to the SSL certificate file. - `ssl_key_file` (string) - Required - Path to the SSL private key file. - `enable_static_handler` (bool) - Optional - Enables static file serving. - `document_root` (string) - Optional - The root directory for static files. ### Request Example N/A (Server setup) ### Response #### Success Response (200) Handles HTTP requests, potentially with server push. #### Response Example ```html

HTTP/2 Server

``` ``` -------------------------------- ### Locking Mechanisms for Synchronization Source: https://context7.com/swoole/swoole-src/llms.txt Provides examples of using Swoole's `Lock` class to implement mutual exclusion and synchronization between processes. It covers various lock types including mutex, read-write locks, and demonstrates their usage for protecting shared data. ```APIDOC ## Lock Implement mutual exclusion and synchronization between processes using various lock types including mutex, file locks, read-write locks, and spinlocks. ### Description This section details the usage of `Swoole\Lock` for process synchronization. It shows how to create and use mutex locks for exclusive access and read-write locks for managing concurrent read and exclusive write access to shared resources. An example of `trylock` is also included. ### Method N/A (Locking primitives) ### Endpoint N/A (Locking primitives) ### Parameters #### Lock Types - `SWOOLE_MUTEX` - Creates a mutex lock for exclusive access. - `SWOOLE_RWLOCK` - Creates a read-write lock for managing concurrent reads and exclusive writes. ### Request Example N/A (Locking primitives) ### Response #### Success Response Demonstrates protected access to shared data using locks. #### Response Example ``` Writer updated count to: 1 Process 0 read: 1 Process 1 read: 1 Writer updated count to: 2 Process 2 read: 2 Process 3 read: 2 Writer updated count to: 3 Process 0 read: 3 Process 1 read: 3 Writer updated count to: 4 Process 2 read: 4 Process 3 read: 4 Writer updated count to: 5 Process 0 read: 5 Process 1 read: 5 Got lock immediately ``` ``` -------------------------------- ### Establish Asynchronous Redis Connection Source: https://github.com/swoole/swoole-src/blob/master/thirdparty/hiredis/README.md Demonstrates how to initiate a non-blocking connection to a Redis server using redisAsyncConnect and check for connection errors. ```c redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); if (c->err) { printf("Error: %s\n", c->errstr); // handle error } ``` -------------------------------- ### Execute Pipelined Commands in Hiredis Source: https://github.com/swoole/swoole-src/blob/master/thirdparty/hiredis/README.md Demonstrates how to queue multiple commands using redisAppendCommand and retrieve their respective replies sequentially using redisGetReply. ```c redisReply *reply; redisAppendCommand(context,"SET foo bar"); redisAppendCommand(context,"GET foo"); redisGetReply(context,&reply); // reply for SET freeReplyObject(reply); redisGetReply(context,&reply); // reply for GET freeReplyObject(reply); ``` -------------------------------- ### Establish WebSocket Connection in JavaScript Source: https://github.com/swoole/swoole-src/blob/master/examples/ssl/websocket_client.html This snippet demonstrates how to initialize a WebSocket connection to a Swoole server. It includes event listeners for the open, close, message, and error events to manage the connection state and handle incoming data. ```javascript var wsServer = 'wss://localhost:9502'; var websocket = new WebSocket(wsServer); websocket.onopen = function (evt) { console.log("Connected to WebSocket server."); }; websocket.onclose = function (evt) { console.log("Disconnected"); }; websocket.onmessage = function (evt) { console.log('Retrieved data from server: ' + evt.data); }; websocket.onerror = function (evt, e) { console.log('Error occured: ' + evt.data); }; ``` -------------------------------- ### Control Swoole Workflows with Git Commit Filters Source: https://github.com/swoole/swoole-src/blob/master/docs/WORKFLOW-PARAMETERS.md This example demonstrates how to use the `--filter` parameter in a Git commit message to specify which workflows should be executed. This is useful for running only relevant tests, improving efficiency. The parameter accepts a list of workflow names matching their respective YAML file names. ```shell git commit -m "commit message --filter=[core][unit]" ``` -------------------------------- ### Configure CMake for Swoole C++ Samples Source: https://github.com/swoole/swoole-src/blob/master/core-tests/samples/CMakeLists.txt This CMake script sets up the build environment for Swoole C++ samples. It specifies C++11 standards, includes necessary header directories, and links the resulting executable against the Swoole library. ```cmake cmake_minimum_required(VERSION 2.8) project(samples) set(CMAKE_CXX_STANDARD 11) file(GLOB_RECURSE SOURCE_FILES FOLLOW_SYMLINKS src/*.cc) add_definitions(-DHAVE_CONFIG_H) link_directories($ENV{SWOOLE_DIR}/lib) include_directories(. ./include $ENV{SWOOLE_DIR} $ENV{SWOOLE_DIR}/include BEFORE) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) add_executable(core_samples ${SOURCE_FILES}) target_link_libraries(core_samples swoole) ``` -------------------------------- ### Find and Link libpq for PostgreSQL Extension Source: https://github.com/swoole/swoole-src/blob/master/CMakeLists.txt This snippet handles the configuration for the PostgreSQL client library (libpq), which is a dependency for the 'ext-swoole' extension. It supports both a pre-defined libpq directory and uses pkg-config to find the library if not explicitly set. It then links the necessary libraries for the extension. ```cmake if (DEFINED libpq_dir) include_directories(BEFORE ${libpq_dir}/include) link_directories(${libpq_dir}/lib) else() pkg_check_modules(LIBPQ REQUIRED libpq) target_include_directories(ext-swoole PRIVATE ${LIBPQ_INCLUDE_DIRS}) endif() target_link_libraries(ext-swoole swoole pq curl) ``` -------------------------------- ### Coroutine HTTP Client Operations in PHP Source: https://context7.com/swoole/swoole-src/llms.txt Demonstrates making various HTTP requests (GET, POST, file upload, WebSocket upgrade) using Swoole's coroutine HTTP client. It supports keep-alive connections and concurrent requests. Dependencies include the Swoole extension. Inputs are URLs and data, outputs are HTTP responses and status codes. ```php setHeaders([ 'Host' => 'httpbin.org', 'User-Agent' => 'Swoole HTTP Client', 'Accept' => 'application/json', ]); $client->set(['timeout' => 10]); $client->get('/get?foo=bar'); echo "Status: {$client->statusCode}\n"; echo "Body: {$client->body}\n"; // POST with JSON body $client->setHeaders(['Content-Type' => 'application/json']); $client->post('/post', json_encode(['name' => 'Swoole', 'version' => '6.0'])); echo "POST Response: {$client->body}\n"; // File upload $client->addFile('/path/to/file.txt', 'upload_file'); $client->addData('inline content', 'inline_file', 'text/plain'); $client->post('/upload'); // WebSocket upgrade $wsClient = new Client('echo.websocket.org', 443, true); $wsClient->upgrade('/'); if ($wsClient->statusCode === 101) { $wsClient->push('Hello WebSocket!'); $frame = $wsClient->recv(5.0); echo "WebSocket response: {$frame->data}\n"; } // Concurrent requests $results = []; $wg = new Swoole\Coroutine\WaitGroup(); foreach (['google.com', 'github.com', 'php.net'] as $host) { $wg->add(); go(function () use ($host, &$results, $wg) { $cli = new Client($host, 443, true); $cli->set(['timeout' => 5]); $cli->get('/'); $results[$host] = strlen($cli->body); $wg->done(); }); } $wg->wait(); print_r($results); }); ``` -------------------------------- ### Execute Redis Commands with Hiredis (C) Source: https://github.com/swoole/swoole-src/blob/master/thirdparty/hiredis/README.md Demonstrates how to send Redis commands to a server using the Hiredis synchronous API's redisCommand function. It supports printf-style formatting for simple string interpolation and the %b specifier for binary-safe arguments, requiring a size_t length. ```c void *redisCommand(redisContext *c, const char *format, ...); // Simple command reply = redisCommand(context, "SET foo bar"); // String interpolation reply = redisCommand(context, "SET foo %s", value); // Binary-safe arguments reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen); // Arguments with specifiers anywhere reply = redisCommand(context, "SET key:%s %s", myid, value); ``` -------------------------------- ### Connect to Swoole WebSocket Server using JavaScript Source: https://github.com/swoole/swoole-src/blob/master/examples/websocket/client.html This snippet demonstrates how to initialize a WebSocket connection to a Swoole server. It includes event listeners for the open, close, message, and error states to manage communication flow. ```javascript var wsServer = 'ws://127.0.0.1:9501'; var websocket = new WebSocket(wsServer); websocket.onopen = function (evt) { console.log("Connected to WebSocket server."); }; websocket.onclose = function (evt) { console.log("Disconnected"); }; websocket.onmessage = function (evt) { console.log('Retrieved data from server: ' + evt.data); }; websocket.onerror = function (evt, e) { console.log('Error occured: ' + evt.data); }; ``` -------------------------------- ### Build Swoole PHP Extension Source: https://github.com/swoole/swoole-src/blob/master/docs/TESTS.md Steps to compile the Swoole PHP extension using `phpize` and `make`. This process requires a PHP development environment and involves configuring `php.ini` to enable the extension. ```shell cd swoole-src phpize ./configure ${options} make -j$(nproc) make install ``` -------------------------------- ### Runtime Coroutine Enabling Source: https://github.com/swoole/swoole-src/blob/master/README.md Demonstrates how to enable coroutine support at runtime for synchronous PHP network libraries using `Swoole\Runtime::enableCoroutine()`. ```APIDOC ## Runtime Coroutine Enabling ### Description This example shows how to enable coroutine support for synchronous PHP network libraries with a single line of code: `Swoole\Runtime::enableCoroutine()`. It then demonstrates concurrent Redis operations. ### Method N/A (Illustrative Code) ### Endpoint N/A ### Parameters N/A ### Request Example ```php Swoole\Runtime::enableCoroutine(); $s = microtime(true); Co\run(function() { for ($c = 100; $c--;) { go(function () { ($redis = new Redis)->connect('127.0.0.1', 6379); for ($n = 100; $n--;) { assert($redis->get('awesome') === 'swoole'); } }); } }); echo 'use ' . (microtime(true) - $s) . ' s'; ``` ### Response N/A ``` -------------------------------- ### Manage Timers and Coroutine Loops Source: https://github.com/swoole/swoole-src/blob/master/README.md Explains how to use Swoole's Timer class for scheduled tasks and how to implement a loop within a coroutine using Co::sleep for non-blocking delays. ```php $id = Swoole\Timer::tick(100, function () { echo "⚙️ Do something...\n"; }); Swoole\Timer::after(500, function () use ($id) { Swoole\Timer::clear($id); echo "⏰ Done\n"; }); Swoole\Timer::after(1000, function () use ($id) { if (!Swoole\Timer::exists($id)) { echo "✅ All right!\n"; } }); go(function () { $i = 0; while (true) { Co::sleep(0.1); echo "📝 Do something...\n"; if (++$i === 5) { echo "🛎 Done\n"; break; } } echo "🎉 All right!\n"; }); ``` -------------------------------- ### Connect to Redis using Hiredis Synchronous API (C) Source: https://github.com/swoole/swoole-src/blob/master/thirdparty/hiredis/README.md Establishes a connection to a Redis server using the synchronous API of the Hiredis library. It demonstrates creating a redisContext, checking for connection errors, and accessing error strings. Note that redisContext is not thread-safe. ```c redisContext *redisConnect(const char *ip, int port); redisContext *c = redisConnect("127.0.0.1", 6379); if (c == NULL || c->err) { if (c) { printf("Error: %s\n", c->errstr); // handle error } else { printf("Can't allocate redis context\n"); } } ``` -------------------------------- ### Build Coroutine TCP Server Source: https://context7.com/swoole/swoole-src/llms.txt Demonstrates creating a high-concurrency TCP server using Swoole's Coroutine API. Each connection is handled in a separate coroutine, enabling efficient I/O operations. ```php set([ 'open_length_check' => true, 'package_length_type' => 'N', 'package_length_offset' => 0, 'package_body_offset' => 4, ]); $server->handle(function (Connection $conn) { echo "New connection from {$conn->exportSocket()->getsockname()['address']}\n"; while (true) { $data = $conn->recv(1.0); if ($data === '' || $data === false) { echo "Connection closed or timeout\n"; break; } $message = substr($data, 4); echo "Received: {$message}\n"; $response = json_encode(['status' => 'ok', 'echo' => $message]); $packed = pack('N', strlen($response)) . $response; $conn->send($packed); } $conn->close(); }); $server->start(); }); Swoole\Event::wait(); ``` -------------------------------- ### Create and Feed Redis Reader - C Source: https://github.com/swoole/swoole-src/blob/master/thirdparty/hiredis/README.md Demonstrates the creation of a redisReader structure and feeding it with incoming data. The function redisReaderCreate initializes the reader, and redisReaderFeed appends data to its internal buffer for later parsing. ```c redisReader *reader = redisReaderCreate(); redisReaderFeed(reader, buf, len); ``` -------------------------------- ### Enable Coroutine Runtime Hooks Source: https://github.com/swoole/swoole-src/blob/master/README.md Demonstrates how to enable Swoole's runtime hooks to automatically convert synchronous network operations (like standard php-redis) into asynchronous coroutine-scheduled tasks. ```php Swoole\Runtime::enableCoroutine(); $s = microtime(true); Co\run(function() { for ($c = 100; $c--;) { go(function () { ($redis = new Redis)->connect('127.0.0.1', 6379); for ($n = 100; $n--;) { assert($redis->get('awesome') === 'swoole'); } }); } }); echo 'use ' . (microtime(true) - $s) . ' s'; ``` -------------------------------- ### Implement Coroutine Communication with Channels Source: https://context7.com/swoole/swoole-src/llms.txt Demonstrates the producer-consumer pattern using Swoole Coroutine Channels. It shows how to push data into a channel from multiple producer coroutines and consume them in a separate coroutine with timeout handling. ```php push($data); echo "Pushed: {$data}\n"; Swoole\Coroutine::sleep(0.1); } }); } // Consumer coroutine go(function () use ($channel) { $count = 0; while ($count < 15) { $data = $channel->pop(1.0); // 1 second timeout if ($data !== false) { echo "Consumed: {$data}\n"; $count++; } } $channel->close(); }); }); ``` -------------------------------- ### Build a Real-time WebSocket Server with Swoole Source: https://context7.com/swoole/swoole-src/llms.txt Implements a WebSocket server for bidirectional communication. It handles connection upgrades, message framing, and allows pushing data to specific clients or broadcasting to all. Dependencies include Swoole extension. ```php set([ 'worker_num' => 2, 'websocket_compression' => true, ]); // Handle new WebSocket connections $server->on('open', function (Server $server, Request $request) { echo "Client #{$request->fd} connected\n"; $server->push($request->fd, json_encode([ 'type' => 'welcome', 'message' => 'Connected to WebSocket server' ])); }); // Handle incoming messages $server->on('message', function (Server $server, Frame $frame) { $data = json_decode($frame->data, true); switch ($data['action'] ?? '') { case 'broadcast': // Broadcast to all connected clients foreach ($server->connections as $fd) { if ($server->isEstablished($fd)) { $server->push($fd, json_encode([ 'type' => 'broadcast', 'from' => $frame->fd, 'message' => $data['message'] ])); } } break; case 'ping': $server->push($frame->fd, json_encode(['type' => 'pong', 'time' => time()])); break; default: $server->push($frame->fd, "Echo: {$frame->data}"); } }); // Handle connection close $server->on('close', function (Server $server, int $fd) { echo "Client #{$fd} disconnected\n"; }); // Also handle HTTP requests $server->on('request', function (Request $request, Response $response) { $response->end(' '); }); $server->start(); ``` -------------------------------- ### Create a TCP Server with Swoole for Custom Protocols Source: https://context7.com/swoole/swoole-src/llms.txt Establishes a TCP server capable of handling raw socket connections with custom protocols. It features length-based packet splitting, EOF detection, and supports concurrent client management. Requires Swoole extension. ```php set([ 'worker_num' => 4, 'open_length_check' => true, 'package_length_type' => 'N', 'package_length_offset' => 0, 'package_body_offset' => 4, 'package_max_length' => 1024 * 1024, ]); // Pack data with length prefix function pack_data(string $data): string { return pack('N', strlen($data)) . $data; } // Unpack data function unpack_data(string $data): string { return substr($data, 4); } $server->on('connect', function (Swoole\Server $server, int $fd) { echo "Client #{$fd} connected\n"; }); $server->on('receive', function (Swoole\Server $server, int $fd, int $reactorId, string $data) { $message = unpack_data($data); echo "Received from #{$fd}: {$message}\n"; // Process and respond $response = json_encode([ 'status' => 'ok', 'received' => $message, 'timestamp' => time() ]); $server->send($fd, pack_data($response)); }); $server->on('close', function (Swoole\Server $server, int $fd) { echo "Client #{$fd} closed\n"; }); $server->start(); ``` -------------------------------- ### Build Swoole Core Libraries and Tests Source: https://github.com/swoole/swoole-src/blob/master/docs/TESTS.md Commands to compile the core Swoole C++ libraries and the core test executables. This process involves using CMake and make within the swoole-src directory. ```shell cd swoole-src cmake . make -j$(nproc) lib-swoole make -j$(nproc) core-tests ``` -------------------------------- ### Redis Command Execution Source: https://github.com/swoole/swoole-src/blob/master/thirdparty/hiredis/README.md Details on how to execute Redis commands using `redisCommand` and `redisCommandArgv`. ```APIDOC ## Sending Redis Commands ### `redisCommand` * **Description**: Executes a Redis command. * **Return Value**: A `redisReply` object on success, or `NULL` on error. If an error occurs, the `err` field in the context will be set, and the context becomes unusable. ### `redisCommandArgv` * **Description**: Executes a Redis command with arguments provided as an array. * **Prototype**: `void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);` * **Parameters**: * `argc` (int): The number of arguments. * `argv` (const char **): An array of strings representing the command and its arguments. * `argvlen` (const size_t *): An array of the lengths of each argument in `argv`. If `NULL`, `strlen` is used. Provide this array for binary-safe arguments. * **Return Value**: Same semantics as `redisCommand`. ``` -------------------------------- ### Producer-Consumer Pattern using Coroutines and Channels Source: https://github.com/swoole/swoole-src/blob/master/README.md Shows how to coordinate multiple concurrent tasks using a Channel to collect results from different coroutines, ensuring non-blocking execution. ```php go(function () { $channel = new Swoole\Coroutine\Channel; go(function () use ($channel) { $addr_info = Co::getaddrinfo('github.com'); $channel->push(['A', json_encode($addr_info, JSON_PRETTY_PRINT)]); }); go(function () use ($channel) { $mirror = Co::readFile(__FILE__); $channel->push(['B', $mirror]); }); go(function () use ($channel) { $channel->push(['C', date(DATE_W3C)]); }); for ($i = 3; $i--;) { list($id, $data) = $channel->pop(); echo "From {$id}:\n {$data}\n"; } }); ``` -------------------------------- ### Build Libraries and Executables Source: https://github.com/swoole/swoole-src/blob/master/CMakeLists.txt Defines the main Swoole shared library and test executables, ensuring proper linking and dependency management. ```cmake add_library(lib-swoole SHARED ${SRC_LIST}) target_link_libraries(lib-swoole ${SWOOLE_LINK_LIBRARIES}) add_executable(test_server examples/cpp/test_server.cc) add_dependencies(test_server lib-swoole) target_link_libraries(test_server swoole pthread) ```