Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Client Laravel Package

thruway/client

Thruway Client is a PHP WAMP v2 client built on ReactPHP, enabling WebSocket pub/sub and RPC over persistent connections. It supports asynchronous messaging, topic subscriptions, and remote procedure calls for real-time PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require thruway/client

There is no Laravel auto-discovery, facade, config publish, or service provider in this package. Treat it as a low-level PHP WAMP client and build the Laravel glue yourself.

Look first at:

  1. The package README and any examples/ directory.
  2. vendor/thruway/client/src/Connection.php and ClientSession.php — these are the entry points.
  3. Your WAMP router docs (Crossbar, Thruway router, etc.) for realm, auth, and websocket URL.

Minimal first use case: an Artisan command that connects to a WAMP router, subscribes to a topic, and logs payloads.

// app/Console/Commands/WampListen.php
use Thruway\ClientSession;
use Thruway\Connection;

public function handle()
{
    $connection = new Connection([
        'realm' => config('thruway.realm'),
        'url'   => config('thruway.url'),
    ]);

    $connection->on('open', function (ClientSession $session) {
        $session->subscribe('com.example.events', function ($args) {
            logger()->info('WAMP event', $args);
        });
    });

    $connection->on('error', fn ($e) => logger()->error($e->getMessage()));
    $connection->open(); // starts the ReactPHP event loop
}

Add a minimal config/thruway.php:

return [
    'url'   => env('WAMP_URL', 'ws://127.0.0.1:8080/ws'),
    'realm' => env('WAMP_REALM', 'realm1'),
];

Run it as a long-lived daemon:

php artisan wamp:listen

Implementation Patterns

Wrap the client in a Laravel service. Bind a factory or singleton in a service provider, but be deliberate about lifecycle. A singleton connection is useful in long-running workers and dangerous in PHP-FPM.

$this->app->singleton('wamp.connection', function () {
    return new Connection([
        'realm' => config('thruway.realm'),
        'url'   => config('thruway.url'),
        'authmethods' => ['wampcra'],
        'authid' => config('thruway.authid'),
        'authrole' => config('thruway.authrole'),
        'onChallenge' => function ($session, $challenge, $canceller) {
            return $canceller->answer(config('thruway.secret'));
        },
    ]);
});

Prefer a small WampClient wrapper class over injecting Thruway\Connection directly. That gives you one place for reconnection, logging, serialization, and test mocking.

Publish from Artisan commands or queued jobs. Opening a WAMP connection per HTTP request is usually the wrong tradeoff: connection setup, auth, and event-loop execution add latency and failure modes. Use a daemon or a short-lived command when possible.

$connection->on('open', function (ClientSession $session) use ($payload) {
    $session->publish('com.example.events', [$payload], null, ['acknowledge' => true])
        ->then(function () use ($session) {
            $session->getConnection()->close();
        });
});
$connection->open();

Subscribe in a long-running consumer. The natural Laravel pattern is an Artisan command supervised by Supervisor/systemd. Dispatch Laravel events or jobs from WAMP callbacks so business logic stays out of the event loop.

$session->subscribe('com.example.orders', function ($args) {
    Event::dispatch(new WampOrderReceived($args));
    // or: ProcessWampOrder::dispatch($args)->onQueue('wamp');
});

Use RPC for request/response. For remote procedure calls, wrap the promise and integrate it with Laravel’s timeout/retry expectations. Avoid unbounded waits inside HTTP requests.

$session->call('com.example.calculate', [$input])->then(
    fn ($result) => logger()->info('RPC result', $result),
    fn ($error) => logger()->error('RPC failed', [$error])
);

Register procedures when Laravel is the callee. Keep handlers fast: validate, dispatch a job, return an acknowledgement. Long-running work in the event-loop callback blocks all other WAMP traffic on that connection.

Reconnect explicitly. Treat close and error as normal operational events. Reopen with backoff, and rebuild subscriptions after reconnect. Do not assume the package reconnects for you.

Separate concerns by transport. Use WAMP for real-time pub/sub and RPC, Laravel queues for durable background work, and Laravel events for in-process decoupling. WAMP is not a replacement for your queue.

Gotchas and Tips

  • Maintenance risk is real. The package has a low star count, a 2022 last release, and a low overall score. Check Composer constraints against your PHP/Laravel/ReactPHP versions before committing. Pin versions and add integration tests around the connection lifecycle.
  • Not Laravel-native. No package discovery, no config publish, no facade. You own the service provider, config, reconnect logic, and logging integration.
  • Do not open connections per HTTP request. PHP-FPM request lifecycles and persistent websocket clients are a poor fit. Prefer Artisan daemons, queue workers, or Octane only with careful singleton and event-loop handling.
  • The event loop is the program. open() starts ReactPHP’s loop and blocks. Calls are asynchronous; code after open() may not run as expected. Understand when the loop exits and close connections explicitly.
  • Long-lived connections need supervision. Routers drop idle connections, networks flap, and auth tokens expire. Implement heartbeat/keepalive behavior if your router requires it, plus reconnect with exponential backoff.
  • Callbacks block the loop. Heavy database work, HTTP calls, or large payload processing inside subscribe/register callbacks will stall all messages on that connection. Dispatch Laravel jobs instead.
  • Error handling is easy to miss. Register handlers for error, close, and challenge failures. Log connection state transitions; otherwise failures look like silent hangs.
  • Serialization and router compatibility matter. Confirm JSON vs MsgPack support on both client and router. Payload shape differences are a common source of “message received but empty” bugs.
  • Auth configuration is router-specific. WAMP-CRA, ticket, and anonymous auth require matching router configuration. Verify authid, authrole, and challenge handling against your router, not just the client README.
  • Testing is awkward. Wrap the client behind an interface and fake it in Laravel tests. Integration-test against a real router in CI if WAMP is critical.
  • Debug with router logs first. Enable client logging and compare with router-side logs. Most issues are realm mismatch, URL/path mismatch, auth failure, or subscription before the session is fully open.
  • Extension points are low-level. Custom serializers, transports, and session behavior are possible but not Laravel-friendly. Keep customizations isolated in your wrapper rather than scattered through application code.
  • Budget for replacing it. Given the maintenance signals, keep the WAMP surface area small: one wrapper, one config file, one daemon command. That makes a future swap to another WAMP client or a different transport far cheaper.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib