feat: add PSR-17 factory auto-discovery to HTTP transport (#119)
This commit is contained in:
parent
e5a4cb5906
commit
0963d243bc
7 changed files with 73 additions and 68 deletions
|
|
@ -21,6 +21,7 @@
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
"ext-fileinfo": "*",
|
"ext-fileinfo": "*",
|
||||||
"opis/json-schema": "^2.4",
|
"opis/json-schema": "^2.4",
|
||||||
|
"php-http/discovery": "^1.20",
|
||||||
"phpdocumentor/reflection-docblock": "^5.6",
|
"phpdocumentor/reflection-docblock": "^5.6",
|
||||||
"psr/clock": "^1.0",
|
"psr/clock": "^1.0",
|
||||||
"psr/container": "^2.0",
|
"psr/container": "^2.0",
|
||||||
|
|
@ -64,6 +65,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"sort-packages": true
|
"sort-packages": true,
|
||||||
|
"allow-plugins": {
|
||||||
|
"php-http/discovery": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,24 +95,47 @@ and process requests and send responses. It provides a flexible architecture tha
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Message\ResponseFactoryInterface;
|
|
||||||
use Psr\Http\Message\StreamFactoryInterface;
|
|
||||||
|
|
||||||
|
// PSR-17 factories are automatically discovered
|
||||||
$transport = new StreamableHttpTransport(
|
$transport = new StreamableHttpTransport(
|
||||||
request: $serverRequest, // PSR-7 server request
|
request: $serverRequest, // PSR-7 server request
|
||||||
responseFactory: $responseFactory, // PSR-17 response factory
|
responseFactory: null, // Optional: PSR-17 response factory (auto-discovered if null)
|
||||||
streamFactory: $streamFactory, // PSR-17 stream factory
|
streamFactory: null, // Optional: PSR-17 stream factory (auto-discovered if null)
|
||||||
logger: $logger // Optional PSR-3 logger
|
logger: $logger // Optional PSR-3 logger
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
- **`request`** (required): `ServerRequestInterface` - The incoming PSR-7 HTTP request
|
- **`request`** (required): `ServerRequestInterface` - The incoming PSR-7 HTTP request
|
||||||
- **`responseFactory`** (required): `ResponseFactoryInterface` - PSR-17 factory for creating HTTP responses
|
- **`responseFactory`** (optional): `ResponseFactoryInterface` - PSR-17 factory for creating HTTP responses. Auto-discovered if not provided.
|
||||||
- **`streamFactory`** (required): `StreamFactoryInterface` - PSR-17 factory for creating response body streams
|
- **`streamFactory`** (optional): `StreamFactoryInterface` - PSR-17 factory for creating response body streams. Auto-discovered if not provided.
|
||||||
- **`logger`** (optional): `LoggerInterface` - PSR-3 logger for debugging. Defaults to `NullLogger`.
|
- **`logger`** (optional): `LoggerInterface` - PSR-3 logger for debugging. Defaults to `NullLogger`.
|
||||||
|
|
||||||
|
### PSR-17 Auto-Discovery
|
||||||
|
|
||||||
|
The transport automatically discovers PSR-17 factory implementations from these popular packages:
|
||||||
|
|
||||||
|
- `nyholm/psr7`
|
||||||
|
- `guzzlehttp/psr7`
|
||||||
|
- `slim/psr7`
|
||||||
|
- `laminas/laminas-diactoros`
|
||||||
|
- And other PSR-17 compatible implementations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install any PSR-17 package - discovery works automatically
|
||||||
|
composer require nyholm/psr7
|
||||||
|
```
|
||||||
|
|
||||||
|
If auto-discovery fails or you want to use a specific implementation, you can pass factories explicitly:
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Nyholm\Psr7\Factory\Psr17Factory;
|
||||||
|
|
||||||
|
$psr17Factory = new Psr17Factory();
|
||||||
|
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
||||||
|
```
|
||||||
|
|
||||||
### Architecture
|
### Architecture
|
||||||
|
|
||||||
The HTTP transport doesn't run its own web server. Instead, it processes PSR-7 requests and returns PSR-7 responses that
|
The HTTP transport doesn't run its own web server. Instead, it processes PSR-7 requests and returns PSR-7 responses that
|
||||||
|
|
@ -126,19 +149,17 @@ This design allows integration with any PHP framework or application that suppor
|
||||||
|
|
||||||
### Basic Usage (Standalone)
|
### Basic Usage (Standalone)
|
||||||
|
|
||||||
Here's an opinionated example using Nyholm PSR-7 and Laminas emitter:
|
Here's a simplified example using PSR-17 discovery and Laminas emitter:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
use Http\Discovery\Psr17Factory;
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
use Mcp\Server\Session\FileSessionStore;
|
use Mcp\Server\Session\FileSessionStore;
|
||||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
||||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
|
||||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||||
|
|
||||||
$psr17Factory = new Psr17Factory();
|
$psr17Factory = new Psr17Factory();
|
||||||
$creator = new ServerRequestCreator($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
$request = $psr17Factory->createServerRequestFromGlobals();
|
||||||
$request = $creator->fromGlobals();
|
|
||||||
|
|
||||||
$server = Server::builder()
|
$server = Server::builder()
|
||||||
->setServerInfo('HTTP Server', '1.0.0')
|
->setServerInfo('HTTP Server', '1.0.0')
|
||||||
|
|
@ -146,7 +167,7 @@ $server = Server::builder()
|
||||||
->setSession(new FileSessionStore(__DIR__ . '/sessions')) // HTTP needs persistent sessions
|
->setSession(new FileSessionStore(__DIR__ . '/sessions')) // HTTP needs persistent sessions
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
$transport = new StreamableHttpTransport($request);
|
||||||
|
|
||||||
$response = $server->run($transport);
|
$response = $server->run($transport);
|
||||||
|
|
||||||
|
|
@ -174,27 +195,23 @@ use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
|
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
|
||||||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
||||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
|
|
||||||
class McpController
|
class McpController
|
||||||
{
|
{
|
||||||
#[Route('/mcp', name: 'mcp_endpoint']
|
#[Route('/mcp', name: 'mcp_endpoint')]
|
||||||
public function handle(Request $request, Server $server): Response
|
public function handle(Request $request, Server $server): Response
|
||||||
{
|
{
|
||||||
// Create PSR-7 factories
|
// Convert Symfony request to PSR-7 (PSR-17 factories auto-discovered)
|
||||||
$psr17Factory = new Psr17Factory();
|
$psrHttpFactory = new PsrHttpFactory();
|
||||||
$psrHttpFactory = new PsrHttpFactory($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
|
||||||
$httpFoundationFactory = new HttpFoundationFactory();
|
$httpFoundationFactory = new HttpFoundationFactory();
|
||||||
|
|
||||||
// Convert Symfony request to PSR-7
|
|
||||||
$psrRequest = $psrHttpFactory->createRequest($request);
|
$psrRequest = $psrHttpFactory->createRequest($request);
|
||||||
|
|
||||||
// Process with MCP
|
// Process with MCP (factories auto-discovered)
|
||||||
$transport = new StreamableHttpTransport($psrRequest, $psr17Factory, $psr17Factory);
|
$transport = new StreamableHttpTransport($psrRequest);
|
||||||
$psrResponse = $server->run($transport);
|
$psrResponse = $server->run($transport);
|
||||||
|
|
||||||
// Convert PSR-7 response back to Symfony
|
// Convert PSR-7 response back to Symfony
|
||||||
return $httpFoundationFactory->createResponse($psrResponse);
|
return $httpFoundationFactory->createResponse($psrResponse);
|
||||||
}
|
}
|
||||||
|
|
@ -219,17 +236,14 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
||||||
|
|
||||||
class McpController
|
class McpController
|
||||||
{
|
{
|
||||||
public function handle(ServerRequestInterface $request, Server $server): ResponseInterface
|
public function handle(ServerRequestInterface $request, Server $server): ResponseInterface
|
||||||
{
|
{
|
||||||
$psr17Factory = new Psr17Factory();
|
|
||||||
|
|
||||||
// Create the MCP HTTP transport
|
// Create the MCP HTTP transport
|
||||||
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
$transport = new StreamableHttpTransport($request);
|
||||||
|
|
||||||
// Process MCP request and return PSR-7 response
|
// Process MCP request and return PSR-7 response
|
||||||
// Laravel automatically handles PSR-7 responses
|
// Laravel automatically handles PSR-7 responses
|
||||||
return $server->run($transport);
|
return $server->run($transport);
|
||||||
|
|
@ -248,8 +262,6 @@ Create a route handler using Slim's built-in factories and container:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use Slim\Factory\AppFactory;
|
use Slim\Factory\AppFactory;
|
||||||
use Slim\Psr7\Factory\ResponseFactory;
|
|
||||||
use Slim\Psr7\Factory\StreamFactory;
|
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
|
|
||||||
|
|
@ -260,12 +272,9 @@ $app->any('/mcp', function ($request, $response) {
|
||||||
->setServerInfo('My MCP Server', '1.0.0')
|
->setServerInfo('My MCP Server', '1.0.0')
|
||||||
->setDiscovery(__DIR__, ['.'])
|
->setDiscovery(__DIR__, ['.'])
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
$responseFactory = new ResponseFactory();
|
$transport = new StreamableHttpTransport($request);
|
||||||
$streamFactory = new StreamFactory();
|
|
||||||
|
|
||||||
$transport = new StreamableHttpTransport($request, $responseFactory, $streamFactory);
|
|
||||||
|
|
||||||
return $server->run($transport);
|
return $server->run($transport);
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
@ -330,6 +339,3 @@ npx @modelcontextprotocol/inspector http://localhost:8000
|
||||||
The choice between STDIO and HTTP transport depends on the client you want to integrate with.
|
The choice between STDIO and HTTP transport depends on the client you want to integrate with.
|
||||||
If you are integrating with a client that is running **locally** (like Claude Desktop), use STDIO.
|
If you are integrating with a client that is running **locally** (like Claude Desktop), use STDIO.
|
||||||
If you are building a server in a distributed environment and need to integrate with a **remote** client, use Streamable HTTP.
|
If you are building a server in a distributed environment and need to integrate with a **remote** client, use Streamable HTTP.
|
||||||
|
|
||||||
One additiona difference to consider is that STDIO is process-based (one session per process) while HTTP is
|
|
||||||
request-based (multiple sessions via headers).
|
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,15 @@
|
||||||
require_once dirname(__DIR__).'/bootstrap.php';
|
require_once dirname(__DIR__).'/bootstrap.php';
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
|
|
||||||
|
use Http\Discovery\Psr17Factory;
|
||||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||||
use Mcp\Example\HttpCombinedRegistration\ManualHandlers;
|
use Mcp\Example\HttpCombinedRegistration\ManualHandlers;
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Session\FileSessionStore;
|
use Mcp\Server\Session\FileSessionStore;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
||||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
|
||||||
|
|
||||||
$psr17Factory = new Psr17Factory();
|
$psr17Factory = new Psr17Factory();
|
||||||
$creator = new ServerRequestCreator($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
$request = $psr17Factory->createServerRequestFromGlobals();
|
||||||
|
|
||||||
$request = $creator->fromGlobals();
|
|
||||||
|
|
||||||
$server = Server::builder()
|
$server = Server::builder()
|
||||||
->setServerInfo('Combined HTTP Server', '1.0.0')
|
->setServerInfo('Combined HTTP Server', '1.0.0')
|
||||||
|
|
@ -40,7 +37,7 @@ $server = Server::builder()
|
||||||
)
|
)
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
$transport = new StreamableHttpTransport($request);
|
||||||
|
|
||||||
$response = $server->run($transport);
|
$response = $server->run($transport);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,14 @@
|
||||||
require_once dirname(__DIR__).'/bootstrap.php';
|
require_once dirname(__DIR__).'/bootstrap.php';
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
|
|
||||||
|
use Http\Discovery\Psr17Factory;
|
||||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Session\FileSessionStore;
|
use Mcp\Server\Session\FileSessionStore;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
||||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
|
||||||
|
|
||||||
$psr17Factory = new Psr17Factory();
|
$psr17Factory = new Psr17Factory();
|
||||||
$creator = new ServerRequestCreator($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
$request = $psr17Factory->createServerRequestFromGlobals();
|
||||||
|
|
||||||
$request = $creator->fromGlobals();
|
|
||||||
|
|
||||||
$server = Server::builder()
|
$server = Server::builder()
|
||||||
->setServerInfo('Event Scheduler Server', '1.0.0')
|
->setServerInfo('Event Scheduler Server', '1.0.0')
|
||||||
|
|
@ -33,7 +30,7 @@ $server = Server::builder()
|
||||||
->setDiscovery(__DIR__)
|
->setDiscovery(__DIR__)
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
$transport = new StreamableHttpTransport($request);
|
||||||
|
|
||||||
$response = $server->run($transport);
|
$response = $server->run($transport);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,14 @@
|
||||||
require_once dirname(__DIR__).'/bootstrap.php';
|
require_once dirname(__DIR__).'/bootstrap.php';
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
|
|
||||||
|
use Http\Discovery\Psr17Factory;
|
||||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Session\FileSessionStore;
|
use Mcp\Server\Session\FileSessionStore;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
||||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
|
||||||
|
|
||||||
$psr17Factory = new Psr17Factory();
|
$psr17Factory = new Psr17Factory();
|
||||||
$creator = new ServerRequestCreator($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
$request = $psr17Factory->createServerRequestFromGlobals();
|
||||||
|
|
||||||
$request = $creator->fromGlobals();
|
|
||||||
|
|
||||||
$server = Server::builder()
|
$server = Server::builder()
|
||||||
->setServerInfo('HTTP User Profiles', '1.0.0')
|
->setServerInfo('HTTP User Profiles', '1.0.0')
|
||||||
|
|
@ -75,7 +72,7 @@ $server = Server::builder()
|
||||||
)
|
)
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
$transport = new StreamableHttpTransport($request);
|
||||||
|
|
||||||
$response = $server->run($transport);
|
$response = $server->run($transport);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,14 @@
|
||||||
require_once dirname(__DIR__).'/bootstrap.php';
|
require_once dirname(__DIR__).'/bootstrap.php';
|
||||||
chdir(__DIR__);
|
chdir(__DIR__);
|
||||||
|
|
||||||
|
use Http\Discovery\Psr17Factory;
|
||||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||||
use Mcp\Server;
|
use Mcp\Server;
|
||||||
use Mcp\Server\Session\FileSessionStore;
|
use Mcp\Server\Session\FileSessionStore;
|
||||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
|
||||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
|
||||||
|
|
||||||
$psr17Factory = new Psr17Factory();
|
$psr17Factory = new Psr17Factory();
|
||||||
$creator = new ServerRequestCreator($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
$request = $psr17Factory->createServerRequestFromGlobals();
|
||||||
|
|
||||||
$request = $creator->fromGlobals();
|
|
||||||
|
|
||||||
$server = Server::builder()
|
$server = Server::builder()
|
||||||
->setServerInfo('Schema Showcase', '1.0.0')
|
->setServerInfo('Schema Showcase', '1.0.0')
|
||||||
|
|
@ -33,7 +30,7 @@ $server = Server::builder()
|
||||||
->setDiscovery(__DIR__)
|
->setDiscovery(__DIR__)
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
$transport = new StreamableHttpTransport($request);
|
||||||
|
|
||||||
$response = $server->run($transport);
|
$response = $server->run($transport);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Mcp\Server\Transport;
|
namespace Mcp\Server\Transport;
|
||||||
|
|
||||||
|
use Http\Discovery\Psr17FactoryDiscovery;
|
||||||
use Mcp\Schema\JsonRpc\Error;
|
use Mcp\Schema\JsonRpc\Error;
|
||||||
use Psr\Http\Message\ResponseFactoryInterface;
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
@ -27,6 +28,9 @@ use Symfony\Component\Uid\Uuid;
|
||||||
*/
|
*/
|
||||||
class StreamableHttpTransport implements TransportInterface
|
class StreamableHttpTransport implements TransportInterface
|
||||||
{
|
{
|
||||||
|
private ResponseFactoryInterface $responseFactory;
|
||||||
|
private StreamFactoryInterface $streamFactory;
|
||||||
|
|
||||||
/** @var callable(string, ?Uuid): void */
|
/** @var callable(string, ?Uuid): void */
|
||||||
private $messageListener;
|
private $messageListener;
|
||||||
|
|
||||||
|
|
@ -49,12 +53,15 @@ class StreamableHttpTransport implements TransportInterface
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly ServerRequestInterface $request,
|
private readonly ServerRequestInterface $request,
|
||||||
private readonly ResponseFactoryInterface $responseFactory,
|
?ResponseFactoryInterface $responseFactory = null,
|
||||||
private readonly StreamFactoryInterface $streamFactory,
|
?StreamFactoryInterface $streamFactory = null,
|
||||||
private readonly LoggerInterface $logger = new NullLogger(),
|
private readonly LoggerInterface $logger = new NullLogger(),
|
||||||
) {
|
) {
|
||||||
$sessionIdString = $this->request->getHeaderLine('Mcp-Session-Id');
|
$sessionIdString = $this->request->getHeaderLine('Mcp-Session-Id');
|
||||||
$this->sessionId = $sessionIdString ? Uuid::fromString($sessionIdString) : null;
|
$this->sessionId = $sessionIdString ? Uuid::fromString($sessionIdString) : null;
|
||||||
|
|
||||||
|
$this->responseFactory = $responseFactory ?? Psr17FactoryDiscovery::findResponseFactory();
|
||||||
|
$this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initialize(): void
|
public function initialize(): void
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue