PHPackages                             clue/connection-manager-extra - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. clue/connection-manager-extra

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

clue/connection-manager-extra
=============================

Extra decorators for creating async TCP/IP connections, built on top of ReactPHP's Socket component

v1.4.0(2mo ago)2215.6k↑339.6%46MITPHPPHP &gt;=5.3CI passing

Since Jan 12Pushed 2mo ago5 watchersCompare

[ Source](https://github.com/clue/reactphp-connection-manager-extra)[ Packagist](https://packagist.org/packages/clue/connection-manager-extra)[ Docs](https://github.com/clue/reactphp-connection-manager-extra)[ Fund](https://clue.engineering/support)[ GitHub Sponsors](https://github.com/clue)[ RSS](/packages/clue-connection-manager-extra/feed)WikiDiscussions 1.x Synced 2d ago

READMEChangelog (10)Dependencies (10)Versions (18)Used By (6)

clue/reactphp-connection-manager-extra
======================================

[](#cluereactphp-connection-manager-extra)

[![CI status](https://github.com/clue/reactphp-connection-manager-extra/actions/workflows/ci.yml/badge.svg)](https://github.com/clue/reactphp-connection-manager-extra/actions)[![code coverage](https://camo.githubusercontent.com/2d45ae33b28ed0c5f14fdba645e579072cf437770a215524795c9eb258581b1c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6465253230636f7665726167652d3130302532352d73756363657373)](#tests)[![installs on Packagist](https://camo.githubusercontent.com/67b26f6354e8b73859bd18685177a734b491ec6747f45aa1a34292f45c60e707/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f636c75652f636f6e6e656374696f6e2d6d616e616765722d65787472613f636f6c6f723d626c7565266c6162656c3d696e7374616c6c732532306f6e2532305061636b6167697374)](https://packagist.org/packages/clue/connection-manager-extra)

This project provides *extra* (in terms of "additional", "extraordinary", "special" and "unusual") decorators, built on top of [ReactPHP's Socket](https://github.com/reactphp/socket).

**Table of contents**

- [Support us](#support-us)
- [Introduction](#introduction)
- [Usage](#usage)
    - [Repeat](#repeat)
    - [Timeout](#timeout)
    - [Delay](#delay)
    - [Reject](#reject)
    - [Swappable](#swappable)
    - [Consecutive](#consecutive)
    - [Random](#random)
    - [Concurrent](#concurrent)
    - [Selective](#selective)
- [Install](#install)
- [Tests](#tests)
- [License](#license)

Support us
----------

[](#support-us)

I maintain an ecosystem of open-source projects that have been downloaded hundreds of millions of times and are actively maintained and continuously improved. If you find any of these projects useful, please consider [becoming a sponsor on GitHub](https://github.com/sponsors/clue). Your support helps ensure long-term maintenance and continued development. Thank you! 🚀

Introduction
------------

[](#introduction)

If you're not already familar with [react/socket](https://github.com/reactphp/socket), think of it as an async (non-blocking) version of [`fsockopen()`](https://www.php.net/manual/en/function.fsockopen.php)or [`stream_socket_client()`](https://www.php.net/manual/en/function.stream-socket-client.php). I.e. before you can send and receive data to/from a remote server, you first have to establish a connection - which takes its time because it involves several steps. In order to be able to establish several connections at the same time, [react/socket](https://github.com/reactphp/socket) provides a simple API to establish simple connections in an async (non-blocking) way.

This project includes several classes that extend this base functionality by implementing the same simple `ConnectorInterface`. This interface provides a single promise-based method `connect($uri)` which can be used to easily notify when the connection is successfully established or the `Connector` gives up and the connection fails.

```
$connector->connect('www.google.com:80')->then(function ($stream) {
    echo 'connection successfully established';
    $stream->write("GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n");
    $stream->end();
}, function ($exception) {
    echo 'connection attempt failed: ' . $exception->getMessage();
});
```

Because everything uses the same simple API, the resulting `Connector` classes can be easily interchanged and be used in places that expect the normal `ConnectorInterface`. This can be used to stack them into each other, like using [timeouts](#timeout) for TCP connections, [delaying](#delay) SSL/TLS connections, [retrying](#repeat) failed connection attempts, [randomly](#random) picking a `Connector` or any combination thereof.

Usage
-----

[](#usage)

This section lists all features of this library along with some examples. The examples assume you've [installed](#install) this library and already [set up a `Socket/Connector` instance `$connector`](https://github.com/reactphp/socket#connector).

All classes are located in the `ConnectionManager\Extra` namespace.

### Repeat

[](#repeat)

The `ConnectionManagerRepeat($connector, $tries)` tries connecting to the given location up to a maximum of `$tries` times when the connection fails.

If you pass a value of `3` to it, it will first issue a normal connection attempt and then retry up to 2 times if the connection attempt fails:

```
$connectorRepeater = new ConnectionManagerRepeat($connector, 3);

$connectorRepeater->connect('www.google.com:80')->then(function ($stream) {
    echo 'connection successfully established';
    $stream->close();
});
```

### Timeout

[](#timeout)

The `ConnectionManagerTimeout($connector, $timeout, $loop = null)` sets a maximum `$timeout` in seconds on when to give up waiting for the connection to complete.

```
$connector = new ConnectionManagerTimeout($connector, 3.0);
```

### Delay

[](#delay)

The `ConnectionManagerDelay($connector, $delay, $loop = null)` sets a fixed initial `$delay` in seconds before actually trying to connect. (Not to be confused with [`ConnectionManagerTimeout`](#timeout) which sets a *maximum timeout*.)

```
$delayed = new ConnectionManagerDelayed($connector, 0.5);
```

### Reject

[](#reject)

The `ConnectionManagerReject(null|string|callable $reason)` simply rejects every single connection attempt. This is particularly useful for the below [`ConnectionManagerSelective`](#selective) to reject connection attempts to only certain destinations (for example blocking advertisements or harmful sites).

The constructor accepts an optional rejection reason which will be used for rejecting the resulting promise.

You can explicitly pass a `string` value which will be used as the message for the `Exception` instance:

```
$connector = new ConnectionManagerReject('Blocked');
$connector->connect('www.google.com:80')->then(null, function ($e) {
    assert($e instanceof \Exception);
    assert($e->getMessage() === 'Blocked');
});
```

You can explicitly pass a `callable` value which will be used to either `throw` or `return` a custom `Exception` instance:

```
$connector = new ConnectionManagerReject(function ($uri) {
    throw new RuntimeException($uri . ' blocked');
});
$connector->connect('www.google.com:80')->then(null, function ($e) {
    assert($e instanceof \RuntimeException);
    assert($e->getMessage() === 'www.google.com:80 blocked');
});
```

### Swappable

[](#swappable)

The `ConnectionManagerSwappable($connector)` is a simple decorator for other `ConnectionManager`s to simplify exchanging the actual `ConnectionManager` during runtime (`->setConnectionManager($connector)`).

### Consecutive

[](#consecutive)

The `ConnectionManagerConsecutive($connectors)` establishes connections by trying to connect through any of the given `ConnectionManager`s in consecutive order until the first one succeeds.

```
$consecutive = new ConnectionManagerConsecutive(array(
    $connector1,
    $connector2
));
```

### Random

[](#random)

The `ConnectionManagerRandom($connectors)` works much like `ConnectionManagerConsecutive` but instead of using a fixed order, it always uses a randomly shuffled order.

```
$random = new ConnectionManagerRandom(array(
    $connector1,
    $connector2
));
```

### Concurrent

[](#concurrent)

The `ConnectionManagerConcurrent($connectors)` establishes connections by trying to connect through ALL of the given `ConnectionManager`s at once, until the first one succeeds.

```
$concurrent = new ConnectionManagerConcurrent(array(
    $connector1,
    $connector2
));
```

### Selective

[](#selective)

The `ConnectionManagerSelective($connectors)` manages a list of `Connector`s and forwards each connection through the first matching one. This can be used to implement networking access control lists (ACLs) or firewall rules like a blacklist or whitelist.

This allows fine-grained control on how to handle outgoing connections, like rejecting advertisements, delaying unencrypted HTTP requests or forwarding HTTPS connection through a foreign country.

If none of the entries in the list matches, the connection will be rejected. This can be used to implement a very simple whitelist like this:

```
$selective = new ConnectionManagerSelective(array(
    'github.com' => $connector,
    '*:443' => $connector
));
```

If you want to implement a blacklist (i.e. reject only certain targets), make sure to add a default target to the end of the list like this:

```
$reject = new ConnectionManagerReject();
$selective = new ConnectionManagerSelective(array(
    'ads.example.com' => $reject,
    '*:80-81' => $reject,
    '*' => $connector
));
```

Similarly, you can also combine any of the other connectors to implement more advanced connection setups, such as delaying unencrypted connections only and retrying unreliable hosts:

```
// delay connection by 2 seconds
$delayed = new ConnectionManagerDelay($connector, 2.0);

// maximum of 3 tries, each taking no longer than 2.0 seconds
$retry = new ConnectionManagerRepeat(
    new ConnectionManagerTimeout($connector, 2.0),
    3
);

$selective = new ConnectionManagerSelective(array(
    '*:80' => $delayed,
    'unreliable.example.com' => $retry,
    '*' => $connector
));
```

Each entry in the list MUST be in the form `host` or `host:port`, where `host` may contain the `*` wildcard character and `port` may be given as either an exact port number or as a range in the form of `min-max`. Passing anything else will result in an `InvalidArgumentException`.

> Note that the host will be matched exactly as-is otherwise. This means that if you only block `youtube.com`, this has no effect on `www.youtube.com`. You may want to add a second rule for `*.youtube.com` in this case.

Install
-------

[](#install)

The recommended way to install this library is [through Composer](https://getcomposer.org/). [New to Composer?](https://getcomposer.org/doc/00-intro.md)

This project follows [SemVer](https://semver.org/). This will install the latest supported version:

```
composer require clue/connection-manager-extra:^1.4
```

See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

This project aims to run on any platform and thus does not require any PHP extensions and supports running on legacy PHP 5.3 through current PHP 8+ and HHVM. It's *highly recommended to use the latest supported PHP version* for this project.

Tests
-----

[](#tests)

To run the test suite, you first need to clone this repo and then install all dependencies [through Composer](https://getcomposer.org/):

```
composer install
```

To run the test suite, go to the project root and run:

```
vendor/bin/phpunit
```

The test suite is set up to always ensure 100% code coverage across all supported environments. If you have the Xdebug extension installed, you can also generate a code coverage report locally like this:

```
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-text
```

License
-------

[](#license)

This project is released under the permissive [MIT license](LICENSE).

> Do you use this project in a commercial setting? Sponsoring with invoicing is available, contact me ([@clue](https://github.com/clue)) for details.

###  Health Score

55

—

FairBetter than 97% of packages

Maintenance84

Actively maintained with recent releases

Popularity36

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 89.3% 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

Every ~284 days

Recently: every ~793 days

Total

18

Last Release

81d ago

Major Versions

v0.7.1 → v1.0.02017-05-09

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/776829?v=4)[Christian Lück](/maintainers/clue)[@clue](https://github.com/clue)

---

Top Contributors

[![clue](https://avatars.githubusercontent.com/u/776829?v=4)](https://github.com/clue "clue (134 commits)")[![SimonFrings](https://avatars.githubusercontent.com/u/44357440?v=4)](https://github.com/SimonFrings "SimonFrings (14 commits)")[![PaulRotmann](https://avatars.githubusercontent.com/u/85174210?v=4)](https://github.com/PaulRotmann "PaulRotmann (2 commits)")

---

Tags

randomreactphpSocketConnectionacltimeoutretrynetworkfirewallrepeatdelayreject

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/clue-connection-manager-extra/health.svg)

```
[![Health](https://phpackages.com/badges/clue-connection-manager-extra/health.svg)](https://phpackages.com/packages/clue-connection-manager-extra)
```

###  Alternatives

[ccxt/ccxt

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

43.2k341.0k1](/packages/ccxt-ccxt)[friendsofphp/php-cs-fixer

A tool to automatically fix PHP code style

13.5k251.2M25.2k](/packages/friendsofphp-php-cs-fixer)[rector/rector-src

Instant Upgrade and Automated Refactoring of any PHP code

136406.3k14](/packages/rector-rector-src)[react/socket

Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP

1.3k135.6M458](/packages/react-socket)[react/react

ReactPHP: Event-driven, non-blocking I/O with PHP.

9.1k3.7M65](/packages/react-react)[team-reflex/discord-php

An unofficial API to interact with the voice and text service Discord.

1.1k420.9k26](/packages/team-reflex-discord-php)

PHPackages © 2026

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