Search code examples
laravelwebsocketlaravel-6phpwebsocketlaravel-websockets

Laravel websocket is getting error when i send a message from my JS client


Im building a websocket service in my Laravel app versión 6.2, and using the laravel-websockets package version 1.3 (https://github.com/beyondcode/laravel-websockets).

So, it works fine, but im customizing my websocket to according the documentation to redefine onOpen, onClose, onError and onMessage methods. After this, i test with a client all of them methods and they still to works fine (onOpen, onClose, onError), except onMessage method, this last execute the following exception:

Exception `ErrorException` thrown: `Undefined property: Ratchet\Server\IoConnection::$app`
Unknown app id: exception `ErrorException` thrown: `Undefined property: Ratchet\Server\IoConnection::$app`.

I dont know whats Happening, but here is me custom websocket class to catch the client events:

<?php

namespace App\Websocket;

use Ratchet\ConnectionInterface;
use Ratchet\RFC6455\Messaging\MessageInterface;
use Ratchet\WebSocket\MessageComponentInterface;

class Handler implements MessageComponentInterface
{

    public function onOpen(ConnectionInterface $connection)
    {
        // TODO: Implement onOpen() method.
        \Log::debug('ON OPEN');
        // \Log::debug([$connection]);
    }

    public function onClose(ConnectionInterface $connection)
    {
        // TODO: Implement onClose() method.
        \Log::debug('ON CLOSE');
    }

    public function onError(ConnectionInterface $connection, \Exception $e)
    {
        // TODO: Implement onError() method.
        \Log::debug('ON ERROR');
        // \Log::debug([$connection]);
        \Log::debug($e);
    }

    public function onMessage(ConnectionInterface $connection, MessageInterface $msg)
    {
        // TODO: Implement onMessage() method.
        \Log::debug('ON MESSAGE');
    }
}

Solution

  • I found the answer here beyondcode/laravel-websockets issue #342 You have to create an instance of app attribute at onOpen method, here is the code:

    <?php
    
    namespace App\Websocket;
    
    use BeyondCode\LaravelWebSockets\Apps\App;
    use Ratchet\ConnectionInterface;
    use Ratchet\RFC6455\Messaging\MessageInterface;
    use Ratchet\WebSocket\MessageComponentInterface;
    
    class Handler implements MessageComponentInterface
    {
    
        public function onOpen(ConnectionInterface $connection)
        {
            // TODO: Implement onOpen() method.
            \Log::debug('ON OPEN');
            $socketId = sprintf('%d.%d', random_int(1, 1000000000), random_int(1, 1000000000));
            $connection->socketId = $socketId;
            $connection->app = App::findById('YOUR_APP_ID');
        }
    
        public function onClose(ConnectionInterface $connection)
        {
            // TODO: Implement onClose() method.
            \Log::debug('ON CLOSE');
        }
    
        public function onError(ConnectionInterface $connection, \Exception $e)
        {
            // TODO: Implement onError() method.
            \Log::debug('ON ERROR');
            // \Log::debug([$connection]);
            // \Log::debug($e);
        }
    
        public function onMessage(ConnectionInterface $connection, MessageInterface $msg)
        {
            $connection->send('Hello World!');
            // TODO: Implement onMessage() method.
            \Log::debug(['ON MESSAGE', $msg]);
        }
    }
    

    Sure, you hace to customize a Service provider to init the application socket data, here is the documentation: Custom App Providers