PHPackages                             timostamm/websocket-server - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. timostamm/websocket-server

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

timostamm/websocket-server
==========================

A simple nonblocking server dedicated to websockets.

v4.0.0(7mo ago)01492MITHTMLPHP ^8.0CI passing

Since Oct 17Pushed 7mo ago2 watchersCompare

[ Source](https://github.com/timostamm/websocket-server)[ Packagist](https://packagist.org/packages/timostamm/websocket-server)[ RSS](/packages/timostamm-websocket-server/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (10)Dependencies (4)Versions (11)Used By (0)

WebSocket Server
================

[](#websocket-server)

[![build](https://github.com/timostamm/websocket-server/workflows/CI/badge.svg)](https://github.com/timostamm/websocket-server/actions?query=workflow:%22CI%22)[![Packagist PHP Version](https://camo.githubusercontent.com/1217b12c9c4e86a79ac3a4c1a8fe0687d6937941d9906305e3bdeda55a5d3404/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f74696d6f7374616d6d2f776562736f636b65742d7365727665722f706870)](https://camo.githubusercontent.com/1217b12c9c4e86a79ac3a4c1a8fe0687d6937941d9906305e3bdeda55a5d3404/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f74696d6f7374616d6d2f776562736f636b65742d7365727665722f706870)[![GitHub tag](https://camo.githubusercontent.com/c7b21bf286a925e7324a3d1d23eddbde9891453e4c4bae3ad0cd69a0a873246e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7461672f74696d6f7374616d6d2f776562736f636b65742d7365727665723f696e636c7564655f70726572656c65617365733d26736f72743d73656d76657226636f6c6f723d626c7565)](https://github.com/timostamm/websocket-server/releases/)[![License](https://camo.githubusercontent.com/d6bc2b26794002c24d023acaab01b6dbb953c57ab9cb80ba5b8aa2f2bd5de99a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c7565)](#license)

A simple nonblocking server dedicated to websockets.

- upgrades HTTP requests
- routes HTTP requests to simple websocket-controllers
- can filter HTTP requests
- passes [Autobahn WebSocket Testsuite](https://htmlpreview.github.io/?https://github.com/timostamm/websocket-server/master/autobahn-test/reports/complete/index.html)
- does NOT implement compression
- works well with apache &gt;= 2.4
- installable via `composer require timostamm/websocket-server`
- minimal dependencies ([react/socket](https://packagist.org/packages/react/socket), [ratchet/rfc6455](https://packagist.org/packages/ratchet/rfc6455), [guzzlehttp/psr7](https://packagist.org/packages/guzzlehttp/psr7))
- graceful shutdown via signals (or manually)

Credits for the websocket protocol implementation go to [ratchet/rfc6455](https://github.com/ratchetphp/RFC6455).

#### Example

[](#example)

```
$loop = Factory::create(); // use a react event loop

// start server
$server = new WebsocketServer($loop, [
    'uri' => '127.0.0.1:23080'
]);

// add a controller
$server->route([
    'match' => '/example/*',
    'controller' => new class() implements ControllerInterface
    {
        function onOpen(WebSocket $connection): void
        {
            print $connection . ' connected. Sending a "Hello".' . PHP_EOL;
            $connection->send('Hello');
        }

        function onMessage(WebSocket $from, string $payload, bool $binary): void
        {
            print $from . ' sent: ' . $payload . PHP_EOL;
        }

        function onClose(WebSocket $connection, ?Throwable $error): void
        {
            print $connection . ' disconnected.' . PHP_EOL;
        }

    }
]);

// This error handler will be called when an exception was thrown
// by a filter, a controller method or the underlying tcp server.
$server->on('error', function (Throwable $error) {
    print 'Server error: ' . $error->getMessage() . PHP_EOL;
});

$loop->run(); // the react event loop processes socket connections
```

#### Routing

[](#routing)

This route will match paths starting with `/example/`.

```
$server->route([
    'match' => '/example/*',
    'controller' => $controller
]);
```

Placeholders are implemented using [fnmatch()](http://php.net/manual/en/function.fnmatch.php).

This route will match any path:

```
$server->route([
    'controller' => $controller
]);
```

This route will deny the websocket handshake if the client did not specifiy one of the [subprotocols](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#Miscellaneous):

```
$server->route([
    'protocols' => ['soap'],
    'controller' => $controller
]);
```

#### Request filters

[](#request-filters)

This filter responds with a HTTP 403

```
$server->filter('example/403', function () {
    throw ResponseException::create(403);
});
```

This filter modifies the request

```
$server->filter('example/add-attribute', function (ServerRequestInterface $request) {
    return $request->withAttribute('X-filter', 'passed');
});
```

This filter allows only the specified origins

```
$server->filter('example/origin', new OriginFilter(['example.com']));
```

You can provide your or RequestMatcherInterface and RequestFilterInterface implementations. Filters can also be added via `route()`:

```
$server->route([
    'match' => '/example/*',
    'filter' => function(ServerRequestInterface $request){
        if ($request->getRequestTarget() === '/example/forbidden') {
            throw ResponseException::create(403);
        }
    }
    'controller' => ...
]);
```

#### Authentication

[](#authentication)

This library does not provide session integration, but provides support for bearer token authentication.

Extend `AbstractTokenAuthenticator` with your token verification code and return a user object. The user will be be available in the request attribute "user". If no token is present, the user attribute will be empty.

Use `AuthorizationFilter` to check whether a user is present. Supply a $checkUser function to check whether the user is authorized.

See examples/token-auth.php

#### Apache config

[](#apache-config)

Add the following to a `.htaccess` file to proxy all requests with a `Upgrade: websocket` header to the websocket server.

```

    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^(.*)$          ws://127.0.0.1:23080/$1 [P,L]

```

#### Javascript

[](#javascript)

```
var ws = new WebSocket("ws://localhost:23080/hello/foo");
ws.onmessage = function (event) {
    console.log("message", event.data);
};
```

#### More controller features

[](#more-controller-features)

You can implement one or more of the following interfaces to get access to the loop, clients connected to this controller, etc.

```
class MyCtrl implements ControllerInterface, LoopAwareInterface ConnectionListAwareInterface, OnShutDownInterface, OnLastCloseInterface, OnFirstOpenInterface
{

    function setLoop(\React\EventLoop\LoopInterface $loop, callable $exceptionHandler): void
    {
        print 'Got loop.' . PHP_EOL;
    }

    function setConnections(\SplObjectStorage $webSockets): void
    {
        print 'Got connection list.' . PHP_EOL;
    }

    function onShutDown(): PromiseInterface
    {
         // Will be called when the server is asked to shutdown.
         // Use this hook to finish important tasks, then resolve the promise.
    }

    function onLastClose(WebSocket $socket): void
    {
        print 'Last connection closed.' . PHP_EOL;
    }

    function onFirstOpen(WebSocket $socket): void
    {
        print 'First connection opened.' . PHP_EOL;
    }

    function onOpen(WebSocket $socket): void
    {
        print $socket . ' connected. Sending a "Hello".' . PHP_EOL;
        $socket->send('Hello');
    }

    function onMessage(WebSocket $from, string $payload, bool $binary): void
    {
        print $from . ' received: ' . $payload . PHP_EOL;
    }

    function onClose(WebSocket $socket): void
    {
        print $socket . ' disconnected.' . PHP_EOL;
    }

    function onError(WebSocket $socket, \Throwable $error): void
    {
        print $socket . ' error: ' . $error->getMessage() . PHP_EOL;
    }

}
```

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance62

Regular maintenance activity

Popularity12

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 85.1% 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 ~280 days

Recently: every ~550 days

Total

10

Last Release

237d ago

Major Versions

v1.0.1 → v2.0.02019-09-04

v2.0.0 → v3.0.02019-09-04

v3.1.1 → v4.0.02025-09-16

PHP version history (3 changes)v1.0.0PHP ^7.1.3

v3.1.0PHP ^7.2 || ^8.0

v4.0.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/6364011a12f22cb5046056371bde6170218218c560eddfdc08b4644b7648af78?d=identicon)[timostamm](/maintainers/timostamm)

---

Top Contributors

[![timostamm](https://avatars.githubusercontent.com/u/4289451?v=4)](https://github.com/timostamm "timostamm (63 commits)")[![ducrot](https://avatars.githubusercontent.com/u/3525119?v=4)](https://github.com/ducrot "ducrot (11 commits)")

---

Tags

autobahnphpreactwebsocket-serverwebsockets

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/timostamm-websocket-server/health.svg)

```
[![Health](https://phpackages.com/badges/timostamm-websocket-server/health.svg)](https://phpackages.com/packages/timostamm-websocket-server)
```

###  Alternatives

[laravel/reverb

Laravel Reverb provides a real-time WebSocket communication backend for Laravel applications.

1.5k9.4M48](/packages/laravel-reverb)[google/cloud-core

Google Cloud PHP shared dependency, providing functionality useful to all components.

343121.4M79](/packages/google-cloud-core)[botman/botman

Create messaging bots in PHP with ease.

6.2k1.5M97](/packages/botman-botman)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k17](/packages/civicrm-civicrm-core)[php-tuf/php-tuf

PHP implementation of The Update Framework (TUF)

456.5k1](/packages/php-tuf-php-tuf)[xibosignage/xibo-xmr

Xibo Message Relay

1011.5k](/packages/xibosignage-xibo-xmr)

PHPackages © 2026

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