Enable servers to send sampling messages to clients (#101)
This commit is contained in:
parent
67cc641247
commit
fb3c1e65a6
1 changed files with 460 additions and 137 deletions
|
|
@ -13,7 +13,9 @@ namespace Mcp\Capability\Registry;
|
|||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Exception\RegistryException;
|
||||
use Mcp\Server\ClientAwareInterface;
|
||||
use Mcp\Server\ClientGateway;
|
||||
use Mcp\Server\Session\SessionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -31,12 +33,18 @@ final class ReferenceHandler implements ReferenceHandlerInterface
|
|||
*/
|
||||
public function handle(ElementReference $reference, array $arguments): mixed
|
||||
{
|
||||
$session = $arguments['_session'];
|
||||
|
||||
if (\is_string($reference->handler)) {
|
||||
if (class_exists($reference->handler) && method_exists($reference->handler, '__invoke')) {
|
||||
$reflection = new \ReflectionMethod($reference->handler, '__invoke');
|
||||
$instance = $this->getClassInstance($reference->handler);
|
||||
$arguments = $this->prepareArguments($reflection, $arguments);
|
||||
|
||||
if ($instance instanceof ClientAwareInterface) {
|
||||
$instance->setClient(new ClientGateway($session));
|
||||
}
|
||||
|
||||
return \call_user_func($instance, ...$arguments);
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +57,7 @@ final class ReferenceHandler implements ReferenceHandlerInterface
|
|||
}
|
||||
|
||||
if (\is_callable($reference->handler)) {
|
||||
$reflection = $this->getReflectionForCallable($reference->handler);
|
||||
$reflection = $this->getReflectionForCallable($reference->handler, $session);
|
||||
$arguments = $this->prepareArguments($reflection, $arguments);
|
||||
|
||||
return \call_user_func($reference->handler, ...$arguments);
|
||||
|
|
@ -59,6 +67,11 @@ final class ReferenceHandler implements ReferenceHandlerInterface
|
|||
[$className, $methodName] = $reference->handler;
|
||||
$reflection = new \ReflectionMethod($className, $methodName);
|
||||
$instance = $this->getClassInstance($className);
|
||||
|
||||
if ($instance instanceof ClientAwareInterface) {
|
||||
$instance->setClient(new ClientGateway($session));
|
||||
}
|
||||
|
||||
$arguments = $this->prepareArguments($reflection, $arguments);
|
||||
|
||||
return \call_user_func([$instance, $methodName], ...$arguments);
|
||||
|
|
@ -130,7 +143,7 @@ final class ReferenceHandler implements ReferenceHandlerInterface
|
|||
/**
|
||||
* Gets a ReflectionMethod or ReflectionFunction for a callable.
|
||||
*/
|
||||
private function getReflectionForCallable(callable $handler): \ReflectionMethod|\ReflectionFunction
|
||||
private function getReflectionForCallable(callable $handler, SessionInterface $session): \ReflectionMethod|\ReflectionFunction
|
||||
{
|
||||
if (\is_string($handler)) {
|
||||
return new \ReflectionFunction($handler);
|
||||
|
|
@ -143,6 +156,10 @@ final class ReferenceHandler implements ReferenceHandlerInterface
|
|||
if (\is_array($handler) && 2 === \count($handler)) {
|
||||
[$class, $method] = $handler;
|
||||
|
||||
if ($class instanceof ClientAwareInterface) {
|
||||
$class->setClient(new ClientGateway($session));
|
||||
}
|
||||
|
||||
return new \ReflectionMethod($class, $method);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue