Skip to content

Commit cdf7fba

Browse files
fix: Correct client state handling in LaravelHttpTransport
Removes in-memory active client tracking (`$activeClients` array and associated event listeners) from `LaravelHttpTransport`. This local tracking was unreliable due to Laravel's typical request-response lifecycle where the transport instance is re-initialized per interaction. The `ClientStateManager`, which uses a persistent cache, is already responsible for managing active client state and activity across requests. The `LaravelHttpTransport` now correctly relies solely on `ClientStateManager` for queuing messages (`sendToClientAsync`) and updates client activity via `ClientStateManager` when messages are received.
1 parent 48200b8 commit cdf7fba

File tree

1 file changed

+1
-27
lines changed

1 file changed

+1
-27
lines changed

src/Transports/LaravelHttpTransport.php

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77
use Evenement\EventEmitterTrait;
88
use PhpMcp\Server\Contracts\LoggerAwareInterface;
99
use PhpMcp\Server\Contracts\ServerTransportInterface;
10-
use PhpMcp\Server\Exception\TransportException;
1110
use PhpMcp\Server\State\ClientStateManager;
1211
use Psr\Log\LoggerInterface;
1312
use Psr\Log\NullLogger;
1413
use React\Promise\PromiseInterface;
1514

16-
use function React\Promise\reject;
1715
use function React\Promise\resolve;
1816

1917
class LaravelHttpTransport implements ServerTransportInterface, LoggerAwareInterface
@@ -24,23 +22,11 @@ class LaravelHttpTransport implements ServerTransportInterface, LoggerAwareInter
2422

2523
protected ClientStateManager $clientStateManager;
2624

27-
/** @var array<string, true> Tracks active client IDs managed by this transport */
28-
private array $activeClients = [];
29-
3025
public function __construct(ClientStateManager $clientStateManager)
3126
{
3227
$this->clientStateManager = $clientStateManager;
3328
$this->logger = new NullLogger;
3429

35-
$this->on('client_connected', function (string $clientId) {
36-
$this->activeClients[$clientId] = true;
37-
$this->clientStateManager->updateClientActivity($clientId);
38-
});
39-
40-
$this->on('client_disconnected', function (string $clientId, string $reason) {
41-
unset($this->activeClients[$clientId]);
42-
});
43-
4430
$this->on('message', function (string $message, string $clientId) {
4531
$this->clientStateManager->updateClientActivity($clientId);
4632
});
@@ -68,12 +54,6 @@ public function listen(): void
6854
*/
6955
public function sendToClientAsync(string $clientId, string $rawFramedMessage): PromiseInterface
7056
{
71-
if (! isset($this->activeClients[$clientId])) {
72-
$this->logger->warning('Attempted to send message to inactive or unknown client.', ['clientId' => $clientId]);
73-
74-
return reject(new TransportException("Client '{$clientId}' is not actively managed by this transport."));
75-
}
76-
7757
$messagePayload = rtrim($rawFramedMessage, "\n");
7858

7959
if (empty($messagePayload)) {
@@ -90,13 +70,7 @@ public function sendToClientAsync(string $clientId, string $rawFramedMessage): P
9070
*/
9171
public function close(): void
9272
{
93-
$activeClientIds = array_keys($this->activeClients);
94-
95-
foreach ($activeClientIds as $clientId) {
96-
$this->emit('client_disconnected', [$clientId, 'Transport globally closed']);
97-
$this->emit('close', ['Transport closed.']);
98-
}
99-
73+
$this->emit('close', ['Transport closed.']);
10074
$this->removeAllListeners();
10175
}
10276
}

0 commit comments

Comments
 (0)