Weave Code
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

Ratchet Laravel Package

cboden/ratchet

Ratchet is a PHP library for building asynchronous WebSocket servers. Compose apps from simple interfaces, reuse components, and deploy behind proxies or on ports 80/443. Includes docs and examples for chat-style real-time messaging.

View on GitHub
Deep Wiki
Context7
## Getting Started

### **Minimal Setup**
1. **Installation**
   ```bash
   composer require cboden/ratchet

Ratchet v0.4.4 now requires PHP 8.0+ and the ext-pcntl and ext-posix extensions. Verify compatibility with:

composer validate --strict
  1. Basic WebSocket Server Create a minimal server in public/ws-server.php (updated for ReactPHP context):

    <?php
    use Ratchet\Server\IoServer;
    use Ratchet\Http\HttpServer;
    use Ratchet\WebSocket\WsServer;
    use MyApp\WebSocket\MyWebSocket;
    use React\EventLoop\Factory;
    
    require __DIR__.'/../vendor/autoload.php';
    
    $loop = Factory::create();
    $server = IoServer::factory(
        new HttpServer(
            new WsServer(
                new MyWebSocket($loop) // Pass ReactPHP loop for context
            )
        ),
        8080,
        '0.0.0.0'
    );
    
    $server->run();
    $loop->run();
    
  2. Define a WebSocket Class Update the constructor to accept ReactPHP context:

    <?php
    namespace MyApp\WebSocket;
    
    use Ratchet\MessageComponentInterface;
    use Ratchet\ConnectionInterface;
    use React\EventLoop\LoopInterface;
    
    class MyWebSocket implements MessageComponentInterface {
        protected $loop;
    
        public function __construct(LoopInterface $loop) {
            $this->loop = $loop;
        }
    
        public function onOpen(ConnectionInterface $conn) {
            echo "New connection! ({$conn->resourceId})\n";
        }
    
        // ... (rest of methods remain unchanged)
    }
    
  3. Run the Server

    php public/ws-server.php
    

    Test with a WebSocket client (e.g., wscat):

    wscat -c ws://localhost:8080
    

First Use Case: Real-Time Chat

Extend MyWebSocket to broadcast messages (updated for ReactPHP context):

public function onMessage(ConnectionInterface $from, $msg) {
    $this->loop->futureTick(function() use ($from, $msg) {
        foreach ($this->clients as $client) {
            if ($client !== $from) {
                $client->send("{$from->resourceId}: {$msg}");
            }
        }
    });
}

Implementation Patterns

1. Structuring Large Applications

  • ReactPHP Integration: Use the loop context for async operations:

    public function onMessage($msg) {
        $this->loop->addTimer(0.1, function() use ($msg) {
            // Non-blocking DB call via Laravel Queues
            dispatch(new ProcessMessage($msg))->onQueue('websockets');
        });
    }
    
  • Dependency Injection with ReactPHP: Bind the loop in Laravel’s service provider:

    public function register() {
        $this->app->singleton(LoopInterface::class, function() {
            return Factory::create();
        });
    
        $this->app->bind(MyWebSocket::class, function($app) {
            return new MyWebSocket($app->make(LoopInterface::class));
        });
    }
    

2. Integrating with Laravel

  • Route WebSocket to Laravel: Updated Nginx config for ReactPHP compatibility:

    location /ws {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
  • Authenticate with ReactPHP: Use async token validation:

    public function onOpen(ConnectionInterface $conn) {
        $token = $conn->httpRequest->getHeader('Authorization')[0] ?? null;
        $this->loop->futureTick(function() use ($conn, $token) {
            if (!auth()->validateToken($token)) {
                $conn->close();
                return;
            }
            $this->clients->attach($conn);
        });
    }
    

3. Handling Events with ReactPHP

  • Publish/Subscribe with Async: Use ReactPHP futures for event dispatching:
    public function onMessage($msg) {
        $future = new React\Promise\Deferred();
        event(new MessageReceived($msg, $future));
        $future->promise()->then(
            function($result) use ($msg) {
                foreach ($this->clients as $client) {
                    $client->send($result);
                }
            }
        );
    }
    

4. Scaling with ReactPHP

  • Load Balancing: Updated Redis balancer example:
    use Ratchet\Balancer\RedisBalancer;
    
    $balancer = new RedisBalancer('127.0.0.1', 6379, $loop);
    $server = IoServer::factory(
        new BalancingServer(
            new WsServer(new MyWebSocket($loop)),
            $balancer
        ),
        8080
    );
    

5. Testing with ReactPHP

  • Unit Test Handlers: Mock ReactPHP loop:

    $loop = Mockery::mock(LoopInterface::class);
    $handler = new MyWebSocket($loop);
    $conn = Mockery::mock(ConnectionInterface::class);
    $handler->onOpen($conn);
    
  • Integration Test: Use ReactPHP test utilities:

    use React\Test\Loop;
    
    $loop = new Loop();
    $client = new React\Socket\Connector($loop, ['timeout' => 10]);
    $socket = yield $client->connect('ws://localhost:8080');
    yield $socket->send('Hello');
    

Gotchas and Tips

1. Common Pitfalls

  • Blocking Calls in ReactPHP: Avoid synchronous operations in event handlers. Use:

    $this->loop->addTimer(0, function() {
        // Non-blocking code here
    });
    
  • Memory Leaks with ReactPHP: Always detach connections in onClose:

    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
        $this->loop->futureTick(function() use ($conn) {
            // Additional cleanup
        });
    }
    
  • Guzzle HTTP Client: Updated API calls (v0.4.4+):

    // Old (deprecated)
    // $client = new GuzzleHttp\Client(['base_uri' => 'https://api.example.com']);
    
    // New
    $client = new \GuzzleHttp\Client(['base_uri' => 'https://api.example.com']);
    

2. Debugging

  • Log with ReactPHP Context:

    \Log::info("WebSocket event", [
        'connection_id' => $conn->resourceId,
        'loop_context' => spl_object_hash($this->loop)
    ]);
    
  • Check for Stuck Processes: Use reactphp CLI tools:

    reactphp run -- php public/ws-server.php
    

3. Configuration Quirks

  • ReactPHP Loop Binding: Ensure the loop is passed to all components:

    $server = IoServer::factory(
        new HttpServer(new WsServer(new MyWebSocket($loop))),
        8080
    );
    
  • SSL/TLS with ReactPHP: Updated SecureServer example:

    use Ratchet\Server\SecureServer;
    
    $secureServer = IoServer::factory(
        new SecureServer(
            new HttpServer(new WsServer(new MyWebSocket($loop))),
            'path/to/cert.pem',
            'path/to/privkey.pem',
            null,
            null,
            true // Enable ALPN for HTTP/2 compatibility
        ),
        8443
    );
    

4. Extension Points

  • Custom ReactPHP Middleware:

    use Ratchet\WebSocket\Middleware\MessageComponentMiddleware;
    
    $middleware = new MessageComponentMiddleware(
        new MyWebSocket($loop),
        function($next) {
            return function($conn, $msg) {
                // Pre-process message
                return $next($conn, $msg);
            };
        }
    );
    
  • Metrics with ReactPHP: Use reactphp-metrics:

    use React\Metrics\Metrics;
    
    public function onOpen($conn) {
        Metrics::increment('websocket.connections');
    }
    

5. Laravel-Specific Tips

  • Artisan Command with ReactPHP:
    class StartWebSocketServer extends Command {
        public function handle() {
            $loop = Factory::create();
            $server = app(WebSocketServer::class);
            $server->run();
            $loop->run();
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui