Skip to content

Commit 3029f5f

Browse files
committed
Add non-coroutine Swoole HTTP server adapter
Add HttpServer adapter class that wraps Swoole\Http\Server for users who need the traditional multi-process server with worker management and graceful reload, as an alternative to the existing coroutine-based Server adapter. Both adapters implement the same Adapter contract and are interchangeable.
1 parent 15d1195 commit 3029f5f

3 files changed

Lines changed: 112 additions & 0 deletions

File tree

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,34 @@ $http->start();
116116

117117
> When using Swoole, you can use the command `php src/server.php` to run the HTTP server locally, but you need Swoole installed. For setup with Docker, check out our [example application](/example)
118118
119+
#### Using Swoole HTTP server (non-coroutine)
120+
121+
For the traditional multi-process `Swoole\Http\Server` with worker management and graceful reload support:
122+
123+
```php
124+
use Utopia\DI\Container;
125+
use Utopia\Http\Http;
126+
use Utopia\Http\Request;
127+
use Utopia\Http\Response;
128+
use Utopia\Http\Adapter\Swoole\HttpServer;
129+
130+
$container = new Container();
131+
132+
Http::get('/')
133+
->inject('request')
134+
->inject('response')
135+
->action(
136+
function(Request $request, Response $response) {
137+
$response->send('Hello from Swoole HTTP Server');
138+
}
139+
);
140+
141+
$http = new Http(new HttpServer('0.0.0.0', 80), 'America/New_York', $container);
142+
$http->start();
143+
```
144+
145+
> The `HttpServer` adapter uses `Swoole\Http\Server` instead of `Swoole\Coroutine\Http\Server`. It supports the same API as the coroutine-based `Server` adapter and can be used interchangeably.
146+
119147
### Parameters
120148

121149
Parameters are used to receive input into endpoint action from the HTTP request. Parameters could be defined as URL parameters or in a body with a structure such as JSON.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace Utopia\Http\Adapter\Swoole;
4+
5+
use Swoole\Coroutine;
6+
use Utopia\Http\Adapter;
7+
use Utopia\DI\Container;
8+
use Swoole\Http\Server as SwooleServer;
9+
use Swoole\Http\Request as SwooleRequest;
10+
use Swoole\Http\Response as SwooleResponse;
11+
12+
class HttpServer extends Adapter
13+
{
14+
protected SwooleServer $server;
15+
protected const REQUEST_CONTAINER_CONTEXT_KEY = '__utopia_http_request_container';
16+
protected Container $container;
17+
18+
public function __construct(string $host, int $port, array $settings = [], ?Container $container = null)
19+
{
20+
$this->server = new SwooleServer($host, $port);
21+
$this->server->set(\array_merge($settings, [
22+
'enable_coroutine' => true,
23+
'http_parse_cookie' => false,
24+
]));
25+
$this->container = $container ?? new Container();
26+
}
27+
28+
public function onRequest(callable $callback)
29+
{
30+
$this->server->on('request', function (SwooleRequest $request, SwooleResponse $response) use ($callback) {
31+
$requestContainer = new Container($this->container);
32+
$requestContainer->set('swooleRequest', fn () => $request);
33+
$requestContainer->set('swooleResponse', fn () => $response);
34+
35+
Coroutine::getContext()[self::REQUEST_CONTAINER_CONTEXT_KEY] = $requestContainer;
36+
37+
$utopiaRequest = new Request($request);
38+
$utopiaResponse = new Response($response);
39+
40+
\call_user_func($callback, $utopiaRequest, $utopiaResponse);
41+
});
42+
}
43+
44+
public function getContainer(): Container
45+
{
46+
return Coroutine::getContext()[self::REQUEST_CONTAINER_CONTEXT_KEY] ?? $this->container;
47+
}
48+
49+
public function onStart(callable $callback)
50+
{
51+
$this->server->on('start', function () use ($callback) {
52+
\call_user_func($callback, $this);
53+
});
54+
}
55+
56+
public function start()
57+
{
58+
$this->server->start();
59+
}
60+
}

tests/e2e/server-swoole-http.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
require_once __DIR__.'/init.php';
4+
5+
use Swoole\Http\Request as SwooleRequest;
6+
use Swoole\Http\Response as SwooleResponse;
7+
use Utopia\Http\Adapter\Swoole\HttpServer;
8+
use Utopia\Http\Http;
9+
10+
Http::delete('/swoole-test')
11+
->inject('swooleRequest')
12+
->inject('swooleResponse')
13+
->action(function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) {
14+
$method = $swooleRequest->getMethod();
15+
$swooleResponse->header('Content-Type', 'text/plain');
16+
$swooleResponse->header('Cache-Control', 'no-cache');
17+
$swooleResponse->setStatusCode(200);
18+
$swooleResponse->write($method);
19+
$swooleResponse->end();
20+
});
21+
22+
$server = new HttpServer('0.0.0.0', 80);
23+
$http = new Http($server, 'UTC');
24+
$http->start();

0 commit comments

Comments
 (0)