在 docker 环境中使用 laravel websockets 包

Posted

技术标签:

【中文标题】在 docker 环境中使用 laravel websockets 包【英文标题】:Using laravel websockets package in docker environment 【发布时间】:2019-09-27 09:10:17 【问题描述】:

用例 1:

步骤

在 laravel 项目的同一个容器中安装包 像这样在.env & boradcasting.php 中配置推送器设置
PUSHER_APP_ID=123456789
PUSHER_APP_KEY=AZERTYUIOP
PUSHER_APP_SECRET=QSDFGHJKLMWXCVBN
PUSHER_APP_CLUSTER=mt1
PUSHER_APP_HOST=localhost # or 127.0.0.1
'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER'),
                // 'encrypted' => false,
                'host' => env('PUSHER_APP_HOST'),
                'port' => 6001,
                'scheme' => 'http',
            ],
        ],
在项目容器的Dockerfile 中暴露端口6001。 通过在容器内运行 php artisan websockets:serve 来使用包。 通过从 tinker 会话调度 WebSocketsTestEvent 事件来测试包
class WebSocketsTestEvent implements ShouldBroadcast

    use Dispatchable, InteractsWithSockets, SerializesModels;

    protected $message;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($message)
    
        $this->message = $message;
    

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    
        return new PrivateChannel('test');
    

用例 2:

步骤

在 laravel 项目的同一个容器中安装包 在.env 中配置推送器设置,如下所示:
PUSHER_APP_ID=123456789
PUSHER_APP_KEY=AZERTYUIOP
PUSHER_APP_SECRET=QSDFGHJKLMWXCVBN
PUSHER_APP_CLUSTER=mt1
PUSHER_APP_HOST=ssms-app # or the @IP of the conatiner
websockets 容器创建 Dockerfile,如下所示:
FROM php:7.3.3-alpine

RUN apk add --no-cache \
    wget \
    curl \
    # git \
    shadow \
    build-base \
    autoconf \
    # hiredis \
    libxml2-dev \
    zlib-dev \
    libevent \
    libevent-dev \
    openssl-dev \
    gmp-dev \
    icu-dev

RUN docker-php-ext-install \
        pcntl \
        mbstring \
        pdo \
        pdo_mysql \
        tokenizer \
        xml \
        sockets \
        gmp \
        bcmath \
        intl

        # Libevent
RUN pecl install event

RUN apk update

# Cleanup
# apk del .build-deps && \
RUN rm -rf /var/cache/apk/* && \
    rm -rf /tmp/*

RUN mkdir -p /var/www

RUN groupmod -g 1000 www-data && \
    usermod -u 1000 www-data

USER www-data

WORKDIR /var/www/html

EXPOSE 6001

CMD ["php", "artisan", "websockets:serve"]
像这样配置docker-compose.yaml

  ssms-app:
    build:
      context: ./docker/app
      args:
        uid: $UID
    container_name: ssms-app
    environment:
      - APACHE_RUN_USER=#$UID
      - APACHE_RUN_GROUP=#$UID
    volumes:
      - .:/var/www/html
    ports:
      - $HOST_PORT:80
      # - 6001:6001
    links:
      - ssms-redis
      - ssms-sockets
    networks:
      backend:
        aliases:
          - ssms-app

  ssms-sockets:
    build:
      context: ./docker/websockets
    container_name: ssms-sockets
    volumes:
      - .:/var/www/html
    ports:
      - 6001:6001
    networks:
      backend:
        aliases:
          - ssms-sockets

观察:

在这两种情况下,我都会遇到相同的问题:

仪表板中的图表,在访问http://localhost:8080/laravel-websockets后不显示。

注意:这可以通过在config/websockets.php 中设置'perform_dns_lookup' => true 来解决。

没有任何痕迹表明事件是由仪表板中的包广播的。

此外,当我从仪表板使用 事件创建器 时,我在控制台中收到 422 状态代码 许多开发人员在 docker 环境中使用它时遇到了同样的问题,但有些用例适用于某些用例,但不适用于其他用例

最后,有什么解决办法吗?我被困了大约 3 天

【问题讨论】:

关于事件创建者,我使用的是频道:home,事件:App\Events\NewMessage,以及 JSON 格式的消息: "message": "Hello World" 对我来说它正在工作,我也在使用 @987654342 @ 而不是 PrivateChannel 你有没有想过这个问题?我处于同样的情况,我无法弄清楚为什么我无法从任何地方连接到 websocket。 @Flobbo 实际上我没有弄明白,但问题已经解决,直到现在还没有答案!。 我也很久没在这个项目工作了,抱歉 感谢您的回复。看来这根本不可能。 【参考方案1】:

也许尝试编辑 .env 文件以使用 host.docker.internal 像这样

PUSHER_APP_ID=123456789
PUSHER_APP_KEY=AZERTYUIOP
PUSHER_APP_SECRET=QSDFGHJKLMWXCVBN
PUSHER_APP_CLUSTER=mt1
PUSHER_APP_HOST=host.docker.internal

比运行php artisan config:cache

【讨论】:

【参考方案2】:

0

美好的一天,我通过使用 Laravel Echo 映像构建我的 docker,然后设置我的应用程序和门户(第二个应用程序)来在 Docker 构建上运行一个 websocket 服务器,以使用套接字服务器进行身份验证,反之亦然。这是我用来构建我的 docker 堆栈的 Laravel echo docker 镜像https://github.com/oanhnn/docker-laravel-echo-server

我不认为使用工匠 websockets:serve 会起作用,因为您在容器中运行套接字并且需要为其公开端口。好吧,至少我无法让它以这种方式工作,所以我用 laravel echo 做到了。

【讨论】:

以上是关于在 docker 环境中使用 laravel websockets 包的主要内容,如果未能解决你的问题,请参考以下文章

在 docker 环境中使用 laravel websockets 包

将Docker链接到本地​​MySQL数据库[重复]

高级工具推荐|使用 Docker 搭建 Laravel 本地环境

使用Docker compose编排Laravel应用

docker中lnmp环境部署laravel框架

docker 从入门到自动化构建 PHP 环境 | Laravel China 社区