Solved
brianh

Dec 6th, 2023 01:00 PM

Hello again

I am trying to work with Websockets but I am pulling my hair out a bit. FYI the search command no longer works....

I am creating an app that allows a android application to specify the server address and port number required to connect to my app using websockets. I want to allow the android app to be send a command when it connects to navigate to the HomeActivity.

I have been trying to implement Laravel Websockets however it is not functioning.

Here is what I have done:

  1. I have installed Beyondcode Laravel websockets: https://beyondco.de/docs/laravel-websockets/getting-started/installation
  2. I have configured my environment file as follows:
PUSHER_APP_ID=123
PUSHER_APP_KEY=1232345dfg
PUSHER_APP_SECRET=asdfssa
PUSHER_APP_CLUSTER=mt1
  1. I have modified my app.php file found in the config directory:
       App\Providers\AppServiceProvider::class,
       App\Providers\AuthServiceProvider::class,
       App\Providers\BroadcastServiceProvider::class,
       App\Providers\EventServiceProvider::class,
       App\Providers\RouteServiceProvider::class,
       App\Providers\FortifyServiceProvider::class,
       App\Providers\JetstreamServiceProvider::class,
       BeyondCode\LaravelWebSockets\WebSocketsServiceProvider::class,
  1. I have created a custom Websocket handler called InnWebSocketHandler.php in the App directory:

use BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler;
use Ratchet\ConnectionInterface;
use Ratchet\RFC6455\Messaging\MessageInterface;
use Ratchet\WebSocket\MessageComponentInterface;
use App\Events\NavigateToHomeEvent;
use Illuminate\Support\Facades\Log;

class InnWebSocketHandler extends WebSocketHandler
{
   public function onOpen(ConnectionInterface $connection)
   {
       try {
           Log::info("WebSocket connection opened");

           // Your existing logic...

           broadcast(new NavigateToHomeEvent())->toOthers();
       } catch (\Exception $e) {
           Log::error("Error in WebSocket onOpen: " . $e->getMessage());
       }
   }

   public function onClose(ConnectionInterface $connection)
   {
       // TODO: Implement onClose() method.
   }

   public function onError(ConnectionInterface $connection, \Exception $e)
   {
       // TODO: Implement onError() method.
   }

   public function onMessage(ConnectionInterface $connection, MessageInterface $msg)
   {
       // TODO: Implement onMessage() method.
   }
}

I have created an event in app\Events called NavigatetHomeEvent.php:

use App\InnWebSocketHandler;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class NavigateToHomeEvent implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     */
    public function __construct()
    {
        Log::info("NavigateToHomeEvent constructor");
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn()
    {
        Log::info("Broadcasting NavigateToHomeEvent");
        return new Channel('home-navigation');
    }

    public function broadcastWith()
    {
        return [
            'action' => 'navigate',
            'activity' => 'Home'
        ];
    }
}

I then run the commad php artisan websocket:serve and I can succesfully connect to the websocket. However, the Navigatetohome is not being triggered.

Anyone got any ideas or need more information on this?

brianh

Dec 6th, 2023 01:01 PM

For reference, the output of websocketking: 21:38 38.78 { "event": "pusher:connection_established", "data": "{"socket_id":"958233818.754579047","activity_timeout":30}" }

21:38 38.76 Connected to ws://127.0.0.01:6001/app/1232345dfg 21:38 38.73 Connecting to ws://127.0.0.01:6001/app/1232345dfg

bobbyiliev

Dec 7th, 2023 01:19 AM

Best Answer

Hey Brian!

After a quick skim I suspect that the NavigateToHomeEvent is not being triggered because the event is not being dispatched in the correct context. The broadcast method inside the onOpen method of the InnWebSocketHandler class is only being called after the connection is opened, but the NavigateToHomeEvent needs to be dispatched before the connection is established.

To fix this issue, you can try moving the logic for dispatching the event outside of the onOpen method. For example, you could create a separate middleware or service that handles dispatching events when a connection is established.

Here's an example of how to dispatch the NavigateToHomeEvent before the connection is established:

use Illuminate\Support\Facades\Log;
use App\Events\NavigateToHomeEvent;

class WebSocketEventListener
{
    public function handleConnectionEstablished(ConnectionInterface $connection)
    {
        Log::info("Connection established");

        // Dispatch the NavigateToHomeEvent
        event(new NavigateToHomeEvent());
    }
}

Then, you can register this listener in your app/Providers/EventServiceProvider.php class:

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'App\Events\NavigateToHomeEvent' => [
            'App\WebSocketEventListener',
        ],
    ];
}

I believe that now with this the NavigateToHomeEvent will be dispatched before the connection is established, and your android app should be able to receive the event and navigate to the HomeActivity.

Let me know how it goes!