【问题标题】:How to extend laravel websockets server (by BeyondCode) to directly trigger laravel events?如何扩展 laravel websockets 服务器(通过 BeyondCode)直接触发 laravel 事件?
【发布时间】:2020-12-11 02:20:35
【问题描述】:

我研究了很长时间,据我了解,从我的 laravel 基础应用程序来看,BeyondCode 由 websockets 服务器触发的 websocket 事件只是单向消息传递。

消息可以从 laravel 基础应用发送到客户端(客户端对消息做出反应)。没有实现来自其他 websocket 客户端的事件被发送到 websocket 服务器并且我的 laravel 基础应用程序对其做出反应(触发事件)。

要在我的 laravel 基础应用上触发事件,可以使用 webhook。这是对通用生成路由的标准 http 请求。

我理解对了吗?

如果我无法接收消息/事件,为什么我的 laravel 基础应用程序提供 websocket 服务器?为什么在这种情况下我应该只使用一个方向的 websockets?

我还是个 laravel 新手。我想更改/覆盖一些类,查看BeyondCode\LaravelWebSockets\WebSockets\Channels\Channel,以便在正确的套接字发送正确的事件时使某些通道触发事件。

我怎样才能用我自己的类覆盖BeyondCode\LaravelWebSockets\WebSockets\Channels\Channel 类而不弄乱BeyondCode 的websocket 包?我不想接触供应商的东西。

websocket 服务器是完全独立的,还是可以从服务器类中访问我的基础应用程序?如果这样做,我需要注意什么?

【问题讨论】:

    标签: php laravel websocket pusher


    【解决方案1】:

    你不需要覆盖任何东西,你的 laravel 后端会向 websockets 服务器发送一个事件,websockets 服务器会在相应的通道中将事件发送回你的前端

    【讨论】:

    • 感谢您的回答,但我正在寻找相反的方法。据我了解,您描述的方式是 laravel 的标准广播,以 pusher 作为驱动程序。
    • 很抱歉没有收到您的问题
    【解决方案2】:

    您可以将库复制到您的项目目录中,并在您的composer.json 中设置路径:

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

    或者您可以创建另一个存储库并 fork 库,然后再次编辑 composer.json:

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

    确保您在要求中有库:

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

    然后运行composer install

    您可以在这里找到更多信息或不同的解决方案: https://getcomposer.org/doc/05-repositories.md

    【讨论】:

    • 非常感谢。接下来的几天我需要更深入地研究你的解决方案。当我像这样将它包含到我的项目中时,我可以注入我自己的类并且仍然接收超出代码更新吗?
    • 如果您选择第一个解决方案 - 否。如果您选择第二个,则取决于您将在 Beyondcode 存储库中所做的更改合并到您的更改中。
    • 在熟悉 laravel 之后,我认为一种解决方案就是您描述的方法。另一个更轻量级且更适合 laravel 框架的解决方案可能是为 websockets 包编写我自己的 ServiceProvider 使用我的类来覆盖/扩展超越代码功能并将我的服务提供者注入到超越代码包中,如下所述:stackoverflow.com/questions/23789615/…
    【解决方案3】:

    需要一些时间来解决这个问题,但现在我找到了一个最小覆盖供应商代码的答案。

    感兴趣的文件位于 Channels 文件夹下:

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

    在Channel.php、PresenceChannel.php 和PrivateChannel.php 中处理所有推送服务器相关事件。喜欢,订阅和发送消息。 ArrayChannelManager 类控制用于 PrivateChannel、PresenceChannel 和 Channel 的类。

    Laravel-websockets 让您可以为您的项目使用自己的频道管理器,在 /config/websockets.php -> 'channel_manager' 中指定。

    为了将 Laravel 事件添加到推送服务器事件中,我重载了 ArrayChannelManager 和 PrivateChannel(如果需要,您也可以重载其他通道)并添加 Laravel 排队事件。在/config/websockets.php 中,我使用我的重载类作为channel_manager。

    /config/websockets.php:

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

    我重载的 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;
        }
        
        
    };
    

    在我重载的PrivateChannel 文件中,我将MyPusherLaravelEvent 挂钩到推送订阅事件:

    <?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);
        }
    }
    

    使用 Laravel 队列事件将事件处理与推送服务器分开很重要。 https://laravel.com/docs/8.x/events#queued-event-listeners

    您还可以将您的事件挂钩到 Channel::broadcast... 函数,然后解析内容以对您的服务器的某些客户端命令作出反应。

    以通用方式重载函数,因此可以更新供应商代码,而不会因重载而破坏它。

    【讨论】:

      猜你喜欢
      • 2019-09-06
      • 2022-10-24
      • 1970-01-01
      • 2020-05-02
      • 2017-11-03
      • 2021-09-01
      • 2020-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多