PHPackages                             varspool/websocket-bundle - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. varspool/websocket-bundle

ActiveLibrary[HTTP &amp; Networking](/categories/http)

varspool/websocket-bundle
=========================

PHP WebSocket client/server library

491.4k7[3 PRs](https://github.com/varspool/WebsocketBundle/pulls)PHP

Since Dec 8Pushed 10y ago4 watchersCompare

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

READMEChangelogDependenciesVersions (2)Used By (0)

VarspoolWebsocketBundle
=======================

[](#varspoolwebsocketbundle)

Alpha stability. Provides websocket services, including an in-built server, multiplexing, semantic configuration.

There may be [better ways](http://somethingemporium.com/2012/10/websockets-with-symfony2)to do Websockets in Symfony2, some of which will result in you not even needing a third-party bundle. The amount of code needed to use [Ratchet](http://socketo.me/), for instance, is so small you may decide to forgo custom configuration and using the Container to configure your server.

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

[](#installation)

VarspoolWebsocketBundle depends on:

- Wrench (formerly for php-websocket), version 2.0.1+ ([varspool/Wrench](https://github.com/varspool/Wrench))

And, of course, Symfony2. Mostly, the bundle is a light compatibility layer over WebSocket 2.0 that allows it to be used with the Service Container.

### Configuring dependencies

[](#configuring-dependencies)

#### Composer

[](#composer)

If you're using Composer, add the following packages to your project's requires:

```
{
    "require": {
        "varspool/websocket-bundle": "dev-master",
        "wrench/wrench": "dev-master"
    }
}
```

#### deps file

[](#deps-file)

If you're using bin/vendors to configure your dependencies, add the following lines to your `deps` file:

```
[wrench]
    git=git://github.com/varspool/Wrench.git
    version=origin/master

[VarspoolWebsocketBundle]
    git=git://github.com/varspool/WebsocketBundle.git
    target=/bundles/Varspool/WebsocketBundle
    version=origin/master
```

Or, fork to your own repository first so you can send in pull requests and improve upstream 👍. Once you've done this you can use `bin/vendors` to obtain the bundles:

```
$ bin/vendors update

[...]
  > Installing/Updating wrench
  > Installing/Updating VarspoolWebsocketBundle

```

##### app/autoload.php

[](#appautoloadphp)

Register the Varspool and Wrench namespaces in your autoloader (not necessary if you're using Composer with Symfony 2.1):

```
# app/autoload.php
$loader->registerNamespaces(array(
    // [...]
    'Varspool' => __DIR__.'/../vendor/bundles',
    'Wrench'   => __DIR__.'/../vendor/wrench/lib'
));
```

### app/AppKernel.php

[](#appappkernelphp)

Register the `VarspoolWebsocketBundle`:

```
# app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        //...
        new Varspool\WebsocketBundle\VarspoolWebsocketBundle(),
    );
}
```

Usage
-----

[](#usage)

### Server-side starts with a server

[](#server-side-starts-with-a-server)

Any PHP process can only run a single Websocket server, serving a variable number of clients. Performance is untested, and once you get into production you might want to replace the server side. (The Multiplex interfaces descibed below might help: put a message queue between your PHP application code and a lightweight Websocket server.)

To start a server, the bundle provides a `websocket:listen` console command, accessible through `app/console`:

```
Usage:
 websocket:listen [server_name]

Arguments:
 server_name      The server name (from your varspool_websocket configuration) (default: default)

```

The listen command takes a single required argument: the name of the server configuration to use. Servers are defined in your Symfony2 configuration, whether YAML, XML or PHP. You must define at least one to get started (we suggest "default"). Here's what a definition might look like:

```
varspool_websocket:
    servers:
        default: # Server name
            listen: ws://192.168.1.103:8000 # default: ws://localhost:8000

            # Applications this server will allow
            applications:
                - echo
                - multiplex

            # Origin control
            check_origin: true
            allow_origin: # default: just localhost (not useful!)
                - "example.com"
                - "development.localdomain"

            # Other defaults
            max_clients:             30
            max_connections_per_ip:  5
            max_requests_per_minute: 50
```

Once you've configured a server, run the websocket:listen command. When it runs, the server will start up and serve applications you've defined in your configuration.

### Applications

[](#applications)

The server on its own doesn't do anything until you write an **application**for it. The server calls methods on your applications once they are registered.

Registering your application is easy. The server looks for services tagged as `varspool_websocket.application`. So, to run an application, export a service with that tag.

A single server daemon can serve one or more applications. So, you'll also have to include a `key` attribute with your tag. This ends up in your application URL. For example, if you use this service definition:

```

```

And your server is configured to listen on 192.168.1.10:8000, then the URL of your application will be:

```
ws://192.168.1.10:8000/chat

```

Applications are not registered on servers unless they are specified in the server configuration. So, to enable the above application on the default server, you configuration would need to contain:

```
# app/config.yml
varspool_websocket:
    servers:
        default:
            # ...
            applications:
                - chat

```

Here's another example service definition, this time in YAML:

```
services:
    websocket_example:
        class: Application\ExampleBundle\Application\ExampleApplication
        tags:
            - { name: varspool_websocket.application, key: foobar }
```

For a simple example of an application, see `Application\EchoApplication`.

I suggest you make your application classes extend `Varspool\WebsocketBundle\Application\Application`, but it's optional. A tiny bit of type checking is done to see if your application would like logging support, but that's about it. So, you're free to extend whatever class you like: just implement a compatible interface. (This is the same approach taken by php-websocket so far: an abstract `WebSocket\Application` class is provided, but the Server does no typechecking.)

Finally, here's what that the listen command looks like when you run it with a few services defined:

```
$ app/console websocket:listen default
info: Listening on 192.168.1.103:8080 with ssl off
info: Server created
info: Registering application: test (Application\TestBundle\Application\TestApplication)
info: Registering application: auth (Application\TestBundle\Application\AuthApplication)
info: Registering application: multiplex (Varspool\WebsocketBundle\Application\MultiplexApplication)
info: Registering application: echo (Varspool\WebsocketBundle\Application\EchoApplication)

```

### Client-side

[](#client-side)

Of course, you'll need a browser that supports websockets.

As for Javascript libraries, they're mostly up to you. But unless you're already using Coffeescript, you might find the ones shipped along with php-websocket a pain to install.

### Multiplexing

[](#multiplexing)

One thing I would recommend is multiplexing your javascript components' connections. The SockJS way of doing that is [pretty elegant](http://www.rabbitmq.com/blog/2012/02/23/how-to-compose-apps-using-websockets/), and is supported by an application shipped along with this bundle.

#### Client-side multiplexing

[](#client-side-multiplexing)

This bundle is compatible with the multiplex protocol that the [SockJS websocket-multiplex front-end library](https://github.com/sockjs/websocket-multiplex) uses. See [sockjs/websocket-multiplex](https://github.com/sockjs/websocket-multiplex) for downloads. They even have a handy CDN:

```

```

This Javascript library provides a `WebSocketMultiplex` object. You can feed it any object compatible with a native `WebSocket`. So, to start with you can feed it a native WebSocket, and later on, when you decide to install a SockJS server (or one is implemented in PHP) you can feed it a SockJS object. So, like this:

```
var url         = 'ws://example.com:8000/multiplex';

var socket;
if (window.MozWebSocket) {
    socket = new MozWebSocket(url);
} else if (window.WebSocket) {
    socket = new WebSocket(url);
} else {
    throw "No websocket support detected"
}

socket.binaryType = 'blob';

var real_socket = new WebSocket(url);
var multiplexer = new WebSocketMultiplex(real_socket);

var foo  = multiplexer.channel('bar');
// foo.send(), events: open, close, error, message

var logs = mutliplexer.channel('log_server');
// logs.send(), events: open, close, error, message
```

#### Server-side multiplexing

[](#server-side-multiplexing)

The default configuration for this bundle (in Varspool/WebsocketBundle/Resources/config/services.xml) defines a server-side multiplex application, with a key of "multiplex". Make sure this key is listed in your config, under the allowed applications for your server.

When you're using the multiplex *application*, run by a *server*, your socket is further abstracted into *channels*, identified by a *topic* string. All the server-side *listeners* to a channel are notified of each message received from a client. The listeners can then decide to reply to just the client who sent the message, or to all clients subscribed to a channel.

- Clients cannot send messages to other clients, unless you specifically relay them.
    - Channels provide a handy abstraction to do so: `$channel->send('foo', 'text', false, array('except' => $client))`
- Listeners cannot send messages to other listeners.
    - But you can use whatever you like for that: listeners can be DI'd into the service container.

##### The Listener/ConnectionListener interfaces

[](#the-listenerconnectionlistener-interfaces)

On the server side, you need only implement `Multiplex\Listener` to be able to listen to events on a channel:

```
/**
 * @param Channel $channel   The channel is an object that holds all the active
 *          client connections to a given topic, and all the server-side
 *          subscribers. You can ->send($message) to the channel to broadcast
 *          it to all the subscribed client connections. ->getTopic() identifies
 *          the topic the message was received on.
 *
 * @param string $message    The received message, as a string
 *
 * @param Connection $client The client connection the message was received
 *          from. You can ->send($string) to the client, but it is a raw Websocket
 *          connection, so if you want to send a multiplexed message to a single
 *          client, you'll probably use
 *          `Varspool\WebsocketBundle\Multiplex\Protocol::toString($type, $topic, $payload)`
 *          and the Protocol::TYPE_MESSAGE constant.
 */
public function onMessage(Channel $channel, $message, Connection $client);
```

Then just tag your service with `varspool_websocket.multiplex_listener` and the topic you want to listen to:

```

```

All done. Your `onMessage` method will be called with the details of messages clients sent to the multiplex topic you specified. You might also like to do something as clients "connect" to (actually, subscribe) and "disconnect" from (either a real disconnect, or an unsubscribe) your service. To do this, implement the additional `Multiplex\ConnectionListener` interface as well:

```
use Varspool\WebsocketBundle\Multiplex\Listener;
use Varspool\WebsocketBundle\Multiplex\ConnectionListener;
use Varspool\WebsocketBundle\Multiplex\Channel;
use Wrench\Connection;

class GameServer implements Listener, ConnectionListener
{
    public function onMessage(Channel $channel, $message, Connection $client)
    {
        $client->send('Hello, player!');
        $channel->send('Oh, wow, guys...' . $client->getClientId() . ' is here';
    }

    public function onConnect(Channel $channel, Connection $client)
    {
        $client->send('Welcome to the dungeon');
    }

    public function onDisconnect(Channel $channel, Connection $client)
    {
        $channel->send($client->getClientId() . ' is leaving! OH NOES!');
    }
}
```

##### The MultiplexService parent service

[](#the-multiplexservice-parent-service)

For convenience, if you want to implement both of these interfaces, and some other useful functionality (like getting access to the server or mulitplex application instances), just extend `Services\MultiplexService`, and export it in your config with `varspool_websocket.multiplex_service` as its parent.

Here's what that looks like in YAML (with bonus: mulitple channel listener):

```
# config.yml
services:
    example.websocket_auth:
        class:  Application\ExampleBundle\Services\AuthService
        parent: varspool_websocket.multiplex_service
        tags:
            -
                name:  varspool_websocket.multiplex_listener
                topic: auth
            -
                name:  varspool_websocket.multiplex_listener
                topic: login
```

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

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

### Community

Maintainers

![](https://www.gravatar.com/avatar/f7972f8f29b6eda4b2ffa4d6e087a3551b2d909090d2bbcdb212b29a86fed07b?d=identicon)[dominics](/maintainers/dominics)

---

Top Contributors

[![dominics](https://avatars.githubusercontent.com/u/97427?v=4)](https://github.com/dominics "dominics (23 commits)")[![Alarmfifa](https://avatars.githubusercontent.com/u/3095492?v=4)](https://github.com/Alarmfifa "Alarmfifa (1 commits)")

---

Tags

phpwebsocketswrench

### Embed Badge

![Health badge](/badges/varspool-websocket-bundle/health.svg)

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

###  Alternatives

[friendsofsymfony/rest-bundle

This Bundle provides various tools to rapidly develop RESTful API's with Symfony

2.8k73.3M318](/packages/friendsofsymfony-rest-bundle)[php-http/discovery

Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations

1.3k309.5M1.2k](/packages/php-http-discovery)[nyholm/psr7

A fast PHP7 implementation of PSR-7

1.3k235.4M2.4k](/packages/nyholm-psr7)[pusher/pusher-php-server

Library for interacting with the Pusher REST API

1.5k94.8M292](/packages/pusher-pusher-php-server)[spatie/crawler

Crawl all internal links found on a website

2.8k16.3M52](/packages/spatie-crawler)[react/http

Event-driven, streaming HTTP client and server implementation for ReactPHP

78126.4M414](/packages/react-http)

PHPackages © 2026

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