我正在尝试构建我的 docker 示例以与 php8.2、laravel10、websockets 和 redis 一起使用。 我已经准备好了所有必要的 docker 镜像,并将它们与 Caddy 代理结合起来。 我还使用 Horizon 来调试我的广播(在另一个 docker 容器中) 这是我的 docker-compose.yml
services:
### workspace ##################################
workspace:
build:
context: ./workspace
args:
- TZ=${WORKSPACE_TIMEZONE}
- NODE_VERSION=${WORKSPACE_NODE_VERSION}
- YARN_VERSION=${WORKSPACE_YARN_VERSION}
- APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
environment:
- APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
tty: true
networks:
- frontend
- backend
### php-fpm ##############################################
php-fpm:
build:
context: ./php-fpm
args:
- APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
restart: unless-stopped
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
expose:
- "9000"
depends_on:
- workspace
- db
- redis
- laravel-echo-server
networks:
- backend
### caddy ###############################################
caddy:
image: caddy:2.2.1
environment:
- CADDY_HOST_LABEL=${CADDY_HOST_LABEL}
- APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
restart: unless-stopped
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
- caddy_data:/data
- caddy_config:/config
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
ports:
- "${CADDY_HOST_HTTP_PORT}:80"
- "${CADDY_HOST_HTTPS_PORT}:443"
depends_on:
- php-fpm
networks:
- frontend
- backend
### db ##################################################
db:
image: mariadb:latest
build:
context: ./db
environment:
- MYSQL_DATABASE=${DB_DATABASE}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- TZ=${WORKSPACE_TIMEZONE}
restart: unless-stopped
volumes:
- ${DATA_PATH_HOST}/db:/var/lib/mysql
expose:
- "3306"
ports:
- "${DB_PORT}:3306"
networks:
- backend
### redis ###############################################
redis:
build: ./redis
restart: unless-stopped
volumes:
- ${DATA_PATH_HOST}/redis:/data
expose:
- "6379"
ports:
- "${REDIS_PORT}:6379"
networks:
- backend
### websockets ##########################################
laravel-echo-server:
image: oanhnn/laravel-echo-server:latest
depends_on:
- redis
environment:
LARAVEL_ECHO_SERVER_AUTH_HOST: http://example.com
LARAVEL_ECHO_SERVER_DEBUG: 'true'
LARAVEL_ECHO_SERVER_DB: redis
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PREFIX: ""
REDIS_DB: 0
expose:
- "6001"
ports:
- 6001:6001
restart: unless-stopped
networks:
- backend
### horizon #############################################
horizon:
build:
context: ./horizon
args:
- APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
restart: unless-stopped
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
depends_on:
- redis
networks:
- backend
version: '3'
networks:
frontend:
backend:
volumes:
mysql:
redis:
caddy_data:
caddy_config:
我正确配置了所有内容,并且我的消息已成功传递,它们出现在 laravel-echo-server 的调试控制台中,它们成功显示在 laravel-horizon 中(任何地方都没有错误消息,或者没有人报告该行为不正确)
现在我已经开始设置我的客户端了。我在 React 中有一个电子 + 前端应用程序。根据文档,我使用 npm 安装了“socket.io-client”和“laravel-echo”。 我已经像这样配置了套接字io:
import Echo from 'laravel-echo';
window.io = require('socket.io-client');
if (typeof io !== 'undefined') {
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001',
});
} else {
console.log("IO ERROR")
}
window.Echo.channel(`laravel_database_translation.1`)
.listen('.App\\Events\\TranslationEvent', (e) => {
console.log(e)
})
我连接到 Websocket,我看到 Internet 选项卡上发生了 ping/pong 请求(在 f12 中)。 但是,当在服务器端时,使用控制台命令,我调度我的事件 - 在我的控制台中我没有收到任何有关此的信息。
我尝试了不同的方法来连接到我的频道,从 .channel('') 方法中删除了“laravel_database_”,更改了 .listen('*') 中事件的命名选项。但我无法通过网络套接字捕获该事件。 之前,我尝试对本地推送器执行相同的操作,但也失败了。我认为切换到 socket-io 会对我有所帮助 - 但我错了。我很确定问题出在我的 docker 容器上,因为我不是 Dockerfile 配置器。但现在看来应该可以了,也许问题不同了。 我在 Laravel 上的活动:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class TranslationEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels, Queueable;
/**
* Create a new event instance.
*/
public function __construct(public $id, public $message)
{
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel
*/
public function broadcastOn()
{
return new Channel('translation.'.$this->id);
}
}
终于! 经过无数次尝试重建 Docker 容器,我终于发现了一个 bug——laravel-echo-server 与本地版本的 laravel-echo 不兼容。使用 laravel-echo 2.3.0 版本,你就会成功!
控制台日志,我等了 10 个小时以上:') 聚苯乙烯 如果你使用2.3.0,那么就知道当时它只支持以下代码格式:
window.Echo.channel('laravel_database_translation') // <== only full name
.listen('.App\\Events\\TranslationEvent', (e) => { // <== only full name
console.log(e);
});