0

I researched a long time and as I understand, the websocket event triggering by the websockets server by BeyondCode is, viewed from my laravel base app, only one way messaging.

Messages can be sent from the laravel base app to the clients (which react to the message). It is not implemented that events from other websocket clients are sent to the websocket server and my laravel base app reacts to it (triggers an event).

To trigger events on my laravel base app, webhooks can be used. Which is a standard http request to a generic generated route.

Did I understand this right?

Why do I have a websocket server served by my laravel base app if I cannot receive messages/events with it? Why should I use websockets in this case only one directional?

I'm still a laravel novice. I want to change/overwrite some classes, looking at BeyondCode\LaravelWebSockets\WebSockets\Channels\Channel, to make some channels trigger events if the right socket sends the right event.

How can I overwrite the BeyondCode\LaravelWebSockets\WebSockets\Channels\Channel class with my own class without messing with BeyondCode's websocket package? I don't want to touch vendor stuff.

Is the websocket server completely stand alone or can I access my base app from within the servers classes? What do I need to have in mind if I do so?

Seb
  • 101
  • 6

3 Answers3

1

You may copy the library in your project directory and set the path in your composer.json:

    "repositories": [
        {
            "type": "path",
            "url": "path-to-the-copy-of-the-library"
        }
    ],

Or you may create another repository and fork the library and again edit composer.json:

    "repositories": [
        {
            "type": "vcs",
            "url": "URL-to-your-repository"
        }
    ],

Make sure you have the library in the requirements:

    "require": {
        "beyondcode/laravel-websockets": "*",
    }

Then run composer install

You may find more info or different solutions here: https://getcomposer.org/doc/05-repositories.md

Samuil Banti
  • 1,735
  • 1
  • 15
  • 26
  • Thank you very much. I need to dig deeper into your solution the next days. When I include it like this into my project can I inject my own classes and still receive beyondcode updates? – Seb Feb 12 '21 at 16:56
  • If you choose the first solution - no. If you choose the second one it will depend on you to merge changes done in the beyondcode repo into yours. – Samuil Banti Feb 13 '21 at 14:39
  • 1
    After getting more familiar with laravel I think one solution is the approach you describe. A other solution a bit more lightweight and fits better into the laravel framework could be to write my own ServiceProvider for the websockets package use there my class that overwrites/extends beyondcodes functionality and inject my serviceprovider to beyond codes package like described here: https://stackoverflow.com/questions/23789615/laravel-overriding-a-bundles-service-providers – Seb Mar 01 '21 at 07:47
0

You don't need to overwrite anything, your laravel backend is going to emit an event to the websockets server and the websockets server will send the event back to your front end in the corresponding channel

user3813360
  • 566
  • 9
  • 25
  • Thank you for your answer, but I'm looking for the other way around. As i understand, the way you describe is the standard broadcasting of laravel with pusher as driver. – Seb Aug 21 '20 at 19:17
  • I'm sorry i didn't get your question – user3813360 Aug 21 '20 at 19:18
0

Needed some time to get back to this problem, but now I found a answer with minimum overwriting of vendor code.

The files of interest are below the Channels folder:

|-- laravel-websockets
|   |-- src
|   |   |-- WebSockets
|   |   |   |-- Channels
|   |   |   |   |-- ChannelManagers
|   |   |   |   |-- ArrayChannelManager.php
|   |   |   |-- Channel.php
|   |   |   |-- ChannelManager.php
|   |   |   |-- PresenceChannel.php
|   |   |   |-- PrivateChannel.php

In the Channel.php, PresenceChannel.php and PrivateChannel.php all pusher server relevant events are handled. Like, subscribing and sending messages. The class ArrayChannelManager controls what class is used for PrivateChannel, PresenceChannel, and Channel.

Laravel-websockets gives you the possibility to use your own channel manager for your project, specified in /config/websockets.php -> 'channel_manager'.

To add Laravel events to pusher server events I overloaded ArrayChannelManager and PrivateChannel (you can overload the others Channels too if needed) and added Laravels queued events. In /config/websockets.php I used my overloaded class as channel_manager.

/config/websockets.php:

'channel_manager' => \App\Lib\Overwrite\LaravelWebsockets\ArrayChannelManager::class,

My overloaded ArrayChannelManager:

<?php

namespace App\Lib\Overwrite\LaravelWebsockets;

use BeyondCode\LaravelWebSockets\WebSockets\Channels\Channel;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManagers\ArrayChannelManager as ArrayChannelManagerBase;
use BeyondCode\LaravelWebSockets\WebSockets\Channels\PresenceChannel;
use App\Lib\Overwrite\LaravelWebsockets\PrivateChannel;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Ratchet\ConnectionInterface;

class ArrayChannelManager extends ArrayChannelManagerBase
{

    protected function determineChannelClass(string $channelName): string
    {
        if (Str::startsWith($channelName, 'private-')) {
            return PrivateChannel::class;
        }

        if (Str::startsWith($channelName, 'presence-')) {
            return PresenceChannel::class;
        }

        return Channel::class;
    }
    
    
};

In my overloaded PrivateChannel file I hook a MyPusherLaravelEvent to the pusher subscribe event:

<?php

namespace App\Lib\Overwrite\LaravelWebsockets;

use BeyondCode\LaravelWebSockets\WebSockets\Channels\PrivateChannel as PrivateChannelBase;
use Ratchet\ConnectionInterface;
use stdClass;

class PrivateChannel extends PrivateChannelBase
{
    public function subscribe(ConnectionInterface $connection, stdClass $payload)
    {
        parent::subscribe($connection, $payload);
        \App\Events\MyPusherLaravelEvent::dispatch($this->channelName);
    }
}

Its important to use Laravels queued events to separate the event handling from the pusher server. https://laravel.com/docs/8.x/events#queued-event-listeners

You can also hook your events to the Channel::broadcast... functions and then parse the content to react on certain client commands with your server.

Overload the functions in a generic way, so the vendor code can be updated without you breaking it with your overloads.

Seb
  • 101
  • 6