PHPackages                             makaronnik/amphp-rpc - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. makaronnik/amphp-rpc

ActiveLibrary[Queues &amp; Workers](/categories/queues)

makaronnik/amphp-rpc
====================

PHP (8.1) Async RPC based on Amp

v1.0.0(3y ago)331MITPHPPHP &gt;=8.1

Since Sep 3Pushed 3y ago1 watchersCompare

[ Source](https://github.com/makaronnik/amphp-rpc)[ Packagist](https://packagist.org/packages/makaronnik/amphp-rpc)[ Docs](https://github.com/makaronnik/amphp-rpc)[ RSS](/packages/makaronnik-amphp-rpc/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (20)Versions (2)Used By (0)

[![StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md)

[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://vshymanskyy.github.io/StandWithUkraine/)

Amphp RPC
=========

[](#amphp-rpc)

PHP (8.1) Async RPC based on [Amp](https://amphp.org/)

Installation
------------

[](#installation)

This package can be installed as a [Composer](https://getcomposer.org/) dependency.

```
composer require makaronnik/amphp-rpc
```

Requirements
------------

[](#requirements)

- PHP 8.1+

Description
-----------

[](#description)

This is an RPC (remote procedure calls) package that works in asynchronous, non-blocking mode, based on [Amp](https://amphp.org/).
Based on ideas implemented in [amphp/rpc](https://github.com/amphp/rpc), but enhanced with advanced functionality useful for communication and load balancing in microservice architecture.
Used in the [Amphp Microservice Framework](https://github.com/makaronnik/amphp-microservice-framework) as one of the main methods of inter-service communication. It also serves as the basis for the Amphp Request Proxy package.

Main features
-------------

[](#main-features)

- Calling procedures (methods) by the client on a remote server (service), with the possibility of obtaining a result.
- Exceptions that occur on the server during the execution of procedures are caught and transferred to the client, where they can be caught and processed.
- Different response options from the server for various situations (redirect to another host/ip, try again after n seconds, etc.) and the corresponding client reaction. You can implement your own response options and their processing using the interceptor mechanism.
- Cache for `['$host . $className . $methodName' => 'URI']` pairs to store and reuse redirect targets to reduce the number of possible intermediate requests

Creating Remote Objects
-----------------------

[](#creating-remote-objects)

Remote objects are, in fact, instances of classes that are generated on the side of the RPC server when an RPC request is received from an RPC client. These classes MUST be on the server side and implement their interfaces. The public methods of these interfaces MUST return an Amp\\Promise object or an exception will be thrown. These methods are called Remote Procedures. They will be executed on the server as a result of calling similar methods on the proxy object on the client. In order for this to happen, the map between the remote object's interface and its implementation must be registered. This is done using the `registerRemoteObject` method of the RpcRegistry object, which is passed to the RpcServer constructor. The identical interface of the remote object MUST be on BOTH the server and the client. An identical interface on the client is needed to create the appropriate proxy for a remote object, on the client side, by calling the `createProxy` method on the RpcProxyObjectFactory.

#### Remote Object Interface example:

[](#remote-object-interface-example)

```
use Amp\Promise;

interface SimpleCalcInterface
{
    public function add(int $a, int $b): Promise; // remote procedure add() API
}
```

#### Remote Object Implementation example:

[](#remote-object-implementation-example)

```
use Amp\Promise;
use function Amp\call;

class SimpleCalc implements SimpleCalcInterface
{
    public function add(int $a, int $b): Promise // remote procedure add() implementation
    {
        return call(fn (): int => $a + $b); // returns Promise
    }
}
```

#### (Server) Registering a mapping between a remote object's interface and its implementation:

[](#server-registering-a-mapping-between-a-remote-objects-interface-and-its-implementation)

```
$registry = new RpcRegistry();
$registry->registerRemoteObject(SimpleCalcInterface::class, SimpleCalc::class);
$requestHandler = new RpcRequestHandler(new NativeSerializer(), $registry);
$rpcServer = (new RpcServerFactory(8181, $registry, $requestHandler))->getRpcServer();
yield $rpcServer->start();
```

#### (Client) Creating a remote object proxy and calling its remote method:

[](#client-creating-a-remote-object-proxy-and-calling-its-remote-method)

```
$rpcClient = (new RpcClientBuilder('localhost', 8181))->build();
$proxyCalc = yield $proxyObjectsFactory->createProxy($rpcClient, SimpleCalcInterface::class);
$addResult = yield $proxyCalc->add(5, 7); // int: 12
```

Complete examples
-----------------

[](#complete-examples)

You can find complete examples in the [examples](/examples/simple-calc) and [test](/test) directories.

Main package classes
--------------------

[](#main-package-classes)

### Server side:

[](#server-side)

- #### [RpcServer](/src/RpcServer.php) - starts a server serving RPC requests. It is preferable to configure it via [RpcServerFactory](/src/RpcServerFactory.php).

    [](#rpcserver---starts-a-server-serving-rpc-requests-it-is-preferable-to-configure-it-via-rpcserverfactory)
- #### [RpcRequestHandler](/src/RpcRequestHandler.php) - handles RPC requests. Has a `registerInterceptor` method for registering request interceptors that are executed before the main request processing logic. After the request has been processed, it returns the appropriate RPC response.

    [](#rpcrequesthandler---handles-rpc-requests-has-a-registerinterceptor-method-for-registering-request-interceptors-that-are-executed-before-the-main-request-processing-logic-after-the-request-has-been-processed-it-returns-the-appropriate-rpc-response)
- #### [RpcRegistry](/src/RpcRegistry.php) - stores links between interfaces of remote objects and their implementations. If you do not register a remote interface mapping with its implementation, then the server will not know how to handle the RPС request. Passed to the server's and handler's constructors.

    [](#rpcregistry---stores-links-between-interfaces-of-remote-objects-and-their-implementations-if-you-do-not-register-a-remote-interface-mapping-with-its-implementation-then-the-server-will-not-know-how-to-handle-the-rpс-request-passed-to-the-servers-and-handlers-constructors)

### Client side:

[](#client-side)

- #### [RpcClient](/src/RpcClient.php) - makes RPC requests to the server. It is preferable to configure it via [RpcClientBuilder](/src/RpcClientBuilder.php). Not used directly, passed to the remote object's proxy creation method.

    [](#rpcclient---makes-rpc-requests-to-the-server-it-is-preferable-to-configure-it-via-rpcclientbuilder-not-used-directly-passed-to-the-remote-objects-proxy-creation-method)
- #### [RpcResponseHandler](/src/RpcResponseHandler.php) - handles responses from the RPC server and returns the result of the RPC request or throws an appropriate exception.

    [](#rpcresponsehandler---handles-responses-from-the-rpc-server-and-returns-the-result-of-the-rpc-request-or-throws-an-appropriate-exception)
- #### [RpcProxyObjectFactory](/src/ProxyObjects/RpcProxyObjectFactory.php) - creates a proxy for the remote object. It has a single public method `createProxy` that takes as parameters an RpcClient object and the fully qualified interface name of the target remote object. If the previously generated proxy cannot be found, then the generator is used.

    [](#rpcproxyobjectfactory---creates-a-proxy-for-the-remote-object-it-has-a-single-public-method-createproxy-that-takes-as-parameters-an-rpcclient-object-and-the-fully-qualified-interface-name-of-the-target-remote-object-if-the-previously-generated-proxy-cannot-be-found-then-the-generator-is-used)
- #### [RpcProxyObjectGenerator](/src/ProxyObjects/RpcProxyObjectGenerator.php) - generates a proxy class file for the remote object. It is passed to the factory constructor, where it is used.

    [](#rpcproxyobjectgenerator---generates-a-proxy-class-file-for-the-remote-object-it-is-passed-to-the-factory-constructor-where-it-is-used)
- #### [RpcProxyClassFileLocator](/src/ProxyObjects/Utils/RpcProxyClassFileLocator.php) - configures a directory path to store generated proxy classes for remote objects. It is passed to the factory constructor, where it is used.

    [](#rpcproxyclassfilelocator---configures-a-directory-path-to-store-generated-proxy-classes-for-remote-objects-it-is-passed-to-the-factory-constructor-where-it-is-used)

### Responces factories:

[](#responces-factories)

- #### [SuccessRpcResponseFactory](/src/Responses/SuccessRpcResponseFactory.php) - creates an RPC response containing the serialized result of the RPC request.

    [](#successrpcresponsefactory---creates-an-rpc-response-containing-the-serialized-result-of-the-rpc-request)
- #### [ThrowableRpcResponseFactory](/src/Responses/ThrowableRpcResponseFactory.php) - creates an RPC response containing data about an exception that occurred on the server during the processing of an RPC request.

    [](#throwablerpcresponsefactory---creates-an-rpc-response-containing-data-about-an-exception-that-occurred-on-the-server-during-the-processing-of-an-rpc-request)
- #### [RetryRpcResponseFactory](/src/Responses/RetryRpcResponseFactory.php) - creates an RPC response that tells the RPC client (handler) to retry the request after a certain period of time.

    [](#retryrpcresponsefactory---creates-an-rpc-response-that-tells-the-rpc-client-handler-to-retry-the-request-after-a-certain-period-of-time)
- #### [RedirectRpcResponseFactory](/src/Responses/RetryRpcResponseFactory.php) - creates an RPC response that tells the RPC client (handler) to resubmit the request, but to a different host, or with a different port or path.

    [](#redirectrpcresponsefactory---creates-an-rpc-response-that-tells-the-rpc-client-handler-to-resubmit-the-request-but-to-a-different-host-or-with-a-different-port-or-path)

### Exceptions:

[](#exceptions)

- #### [UnprocessedCallException](/src/Exceptions/UnprocessedCallException.php) - thrown if the RPC request was not completed on the RPC server and it can be safely retried.

    [](#unprocessedcallexception---thrown-if-the-rpc-request-was-not-completed-on-the-rpc-server-and-it-can-be-safely-retried)
- #### [PossiblyProcessedCallException](/src/Exceptions/PossiblyProcessedCallException.php) - thrown if the RPC request was partially completed on the RPC server and its retry may be unsafe.

    [](#possiblyprocessedcallexception---thrown-if-the-rpc-request-was-partially-completed-on-the-rpc-server-and-its-retry-may-be-unsafe)
- #### [ProcessedCallException](/src/Exceptions/ProcessedCallException.php) - thrown if the request was successful on the server, but there was a problem getting or returning the result, and repeating this request is likely to be unsafe.

    [](#processedcallexception---thrown-if-the-request-was-successful-on-the-server-but-there-was-a-problem-getting-or-returning-the-result-and-repeating-this-request-is-likely-to-be-unsafe)
- #### [RetriesCountExceededException ](/src/Exceptions/RetriesCountExceededException.php) - thrown if the allowed number of retries has been exceeded. This exception inherits from UnprocessedCallException so the request can be retried safely.

    [](#retriescountexceededexception----thrown-if-the-allowed-number-of-retries-has-been-exceeded-this-exception-inherits-from-unprocessedcallexception-so-the-request-can-be-retried-safely)
- #### [RedirectCountExceededException](/src/Exceptions/RedirectCountExceededException.php) - thrown if the allowed number of redirects has been exceeded. This exception inherits from UnprocessedCallException so the request can be retried safely.

    [](#redirectcountexceededexception---thrown-if-the-allowed-number-of-redirects-has-been-exceeded-this-exception-inherits-from-unprocessedcallexception-so-the-request-can-be-retried-safely)

Versioning
----------

[](#versioning)

`makaronnik/amphp-rpc` follows the [semver](http://semver.org/) semantic versioning specification.

License
-------

[](#license)

The MIT License (MIT). Please see [`LICENSE`](./LICENSE) for more information.

###  Health Score

25

—

LowBetter than 35% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1399d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/9981799?v=4)[Andriy Karpishyn](/maintainers/discovery-ukraine)[@discovery-ukraine](https://github.com/discovery-ukraine)

---

Top Contributors

[![discovery-ukraine](https://avatars.githubusercontent.com/u/9981799?v=4)](https://github.com/discovery-ukraine "discovery-ukraine (11 commits)")[![makaronnik](https://avatars.githubusercontent.com/u/9981799?v=4)](https://github.com/makaronnik "makaronnik (11 commits)")

---

Tags

amphpasyncphp81rpcphpasyncrpcamphp

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/makaronnik-amphp-rpc/health.svg)

```
[![Health](https://phpackages.com/badges/makaronnik-amphp-rpc/health.svg)](https://phpackages.com/packages/makaronnik-amphp-rpc)
```

###  Alternatives

[danog/madelineproto

Async PHP client API for the telegram MTProto protocol.

3.5k902.0k23](/packages/danog-madelineproto)[amphp/parallel

Parallel processing component for Amp.

85251.9M98](/packages/amphp-parallel)[amphp/http-server

A non-blocking HTTP application server for PHP based on Amp.

1.3k6.7M110](/packages/amphp-http-server)[amphp/byte-stream

A stream abstraction to make working with non-blocking I/O simple.

394125.7M136](/packages/amphp-byte-stream)[amphp/pipeline

Asynchronous iterators and operators.

7740.0M49](/packages/amphp-pipeline)[amphp/redis

Efficient asynchronous communication with Redis servers, enabling scalable and responsive data storage and retrieval.

167714.3k59](/packages/amphp-redis)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
