Мое приложение Laravel 11 ничего не транслирует с помощью Laravel Reverb. Я использую специальную конфигурацию Docker для развертывания своей среды, а Laravel действует как REST API, взаимодействующий с автономным интерфейсом React.
Мой файл reverb.php в каталоге config/ нетронут, поскольку я только что обновил файл .env.
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=12345
REVERB_APP_KEY=MYVERYSECRETKEY
REVERB_APP_SECRET=SUPERSECRET
REVERB_HOST = "localhost"
REVERB_PORT=9090
REVERB_SCHEME=http
В файле broadcasting.php этот драйвер установлен в качестве драйвера, насколько я понимаю, Laravel Reverb запускает собственную конфигурацию reverb.php.
'default' => env('BROADCAST_DRIVER', 'null'),
При запуске php artisan queue:listen в контейнере Docker я вижу, как запускаются события и все работает как надо...
Когда я бегу php artisan channel:list, я вижу channel_for_everyone
При работе в контейнере Docker php artisan reverb:start --debug я вижу некоторые журналы ping.
Connection Established ............ 310096377.635725104
Message Handled ................... 475763427.215883647
Message Received .................. 726544741.227378338
{
"event": "pusher:ping",
"data": []
}
С интерфейсом на вкладке «Сеть» снова все выглядит нормально, он пингует /broadcasting/auth и мою настройку ws://localhost:9090/app/
Request URL: http://localhost:8000/broadcasting/auth
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:8000
Referrer Policy: strict-origin-when-cross-origin
Request URL: ws://localhost:9090/app/MYVERYSECRETKEY?protocol=7&client=js&version=8.4.0-rc2&flash=false
Request Method: GET OK
Status Code: 101 Switching Protocols
Само соединение вроде в порядке? Следует отметить одну вещь: если я доберусь до конечной точки, чтобы запустить событие, я не увижу журналов широковещательной рассылки php artisan reverb:start --debug
Мое событие, которое на данный момент является действительно простым и перехватывается и регистрируется при запуске queue:listen, но никогда не транслируется, хотя метод broadcastOn() срабатывает, и я могу его поймать с помощью dd()
class CommentCreatedEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(
) {
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
//dd('inside broadcaseOn() in Event'); <- Gets here
return [
new PrivateChannel('channel_for_everyone'), // can see value of channel
];
}
}
Даже если я сделаю канал не приватным, я все равно ничего не получу!
public function broadcastOn()
{
return [
new Channel('channel_for_everyone'),
];
}
в моем channels.phpdd() внутри channel_for_everyone никогда не попадает, но файл загружается на 100%, как когда я dd() выше, это будет dd('it will hit here!);
dd('it will hit here!);
Broadcast::channel('channel_for_everyone', function ($user) {
dd('callback hit for channel_for_everyone', $user); // Will not hit
return true;
});
Мой код React очень простой, я создал перехватчик для выполнения, и он регистрирует успешное соединение, просто ни одно событие не регистрируется.
const useLaravelEcho = () => {
useEffect(() => {
console.info('Initialising Echo...');
const pusher = Pusher; // we need to make an instance
const echoConfig = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
authEndpoint: import.meta.env.VITE_AUTH_ENDPOINT,
});
// Listen for successful connection
echoConfig.connector.pusher.connection.bind('connected', () => {
console.info('Successfully connected to Echo server.');
});
// Listen for connection errors
echoConfig.connector.pusher.connection.bind('error', (error: any) => {
console.error('Error connecting to Echo server:', error);
});
console.info('Subscribing to channel...');
echoConfig.private('channel_for_everyone')
.listen('CommentCreatedEvent', (event: any) => {
console.info('Event received:', event);
});
}, []);
};
export default useLaravelEcho;
Когда я проверяю консоль в браузере:
Initialising Echo...
useLaravelEcho.ts:32 Subscribing to channel...
useLaravelEcho.ts:24 Successfully connected to Echo server.
Я знаю, что это, должно быть, какая-то ошибка конфигурации, но я просто не могу найти проблему, поскольку у меня нет ошибок или журналов, которые можно было бы отключить!
Есть ли у кого-нибудь идеи?
что вы получите, если запустите эту команду php artisan channel:list?
У меня установлен * в allowed_origins, и channel_for_everyone отображается при беге php artisan channel:list






Зафиксированный! В конце концов возникло несколько проблем.
Бэкэнд REST API:
BROADCAST_DRIVER установлено значение reverb, а для BROADCAST_CONNECTION установлено значение reverb:Это было неясно, и параметры по умолчанию в комментариях Supported: "pusher", "ably", "redis", "log", "null" не указаны reverb как вариант. Я думал, что установка null проигнорирует это, и мой файл конфигурации реверберации будет контролировать это.
Код:
public function reverb(ReverbRequest $request): Response
{
$socketId = $request->input('socket_id');
$channelName = $request->input('channel_name');
// this generates the required format for the response
$stringToAuth = $socketId . ':' . $channelName;
$hashed = hash_hmac('sha256', $stringToAuth, env('REVERB_APP_SECRET'));
try {
// Generate the required format for the response
$stringToAuth = $socketId . ':' . $channelName;
$hashed = hash_hmac('sha256', $stringToAuth, env('REVERB_APP_SECRET'));
return response(['auth' => env('REVERB_APP_KEY') . ':' . $hashed]);
} catch (Exception $e) {
return response(['code' => 403, 'message' => 'Cannot authenticate reverb'], 403);
}
}
Внешний интерфейс
Код:
const useLaravelEcho = () => {
const [{ user }] = useUserContext();
const { showNotificationToast } = useShowToast();
const echoInstance = useRef<Echo | null>(null);
useEffect(() => {
if (!user) return;
// Ensure only one Echo instance is created
if (!echoInstance.current) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const pusher = Pusher; // Needed for the Echo configuration to work
echoInstance.current = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
authEndpoint: import.meta.env.VITE_AUTH_ENDPOINT,
auth: {
headers: {
'Authorization': 'Bearer ' + user?.access_token
}
}
});
// Listen for successful connection
echoInstance.current.connector.pusher.connection.bind('connected', () => {
console.info('Successfully connected to Echo server.');
});
// Listen for connection errors
echoInstance.current.connector.pusher.connection.bind('error', (error: any) => {
console.error('Error connecting to Echo server:', error);
});
}
const channel = echoInstance.current.private('channel_for_everyone')
.listen(CommentCreatedEvent', (event: any) => {
showNotificationToast({text: `You have received a new message from ${event?.user?.name}`);
});
// Cleanup function to remove listeners and Echo instance on unmount or dependency change
return () => {
if (echoInstance.current) {
channel.stopListening('CommentCreatedEvent');
echoInstance.current.disconnect();
echoInstance.current = null;
}
};
}, [user, showNotificationToast]);
return null;
};
Отредактировали ли вы
allowed_originsв файле конфигурации реверберации, чтобы добавить свой хост, или вы можете разрешить все источники, используя*?