Документация EN | RU
Для Centrifugo 2.8 - 3.x используйте версию 1.2.6
- Совместимость с последней версией Centrifugo 5.x 🚀
- Обертка над Centrifugo HTTP API 🔌
- Аутентификация с помощью токена JWT (HMAC) 🗝️
- PHP >= 8.0
- Laravel 8.75 - 11.x
- guzzlehttp/guzzle 6 - 7
- Centrifugo Сервер 4.x или новее (см. здесь)
Установить через composer, выполнив команду в консоле:
composer req opekunov/laravel-centrifugo-broadcaster
Откройте ваш config/app.php
и раскомментируйте следующую строку:
return [
// .... //
'providers' => [
// Uncomment BroadcastServiceProvider
App\Providers\BroadcastServiceProvider::class,
],
// .... //
];
Откройте ваш config/broadcasting.php
и добавьте туда новое подключение (connections
):
return [
// .... //
'centrifugo' => [
'driver' => 'centrifugo',
'secret' => env('CENTRIFUGO_SECRET'),
'apikey' => env('CENTRIFUGO_APIKEY'),
'api_path' => env('CENTRIFUGO_API_PATH', '/api'), // Centrifugo api endpoint (по умолчанию '/api')
'url' => env('CENTRIFUGO_URL', 'http://localhost:8000'), // Centrifugo api url
'verify' => env('CENTRIFUGO_VERIFY', false), // Проверка ssl хоста если centrifugo использует его
'ssl_key' => env('CENTRIFUGO_SSL_KEY', null), // Самоподписанный SSl ключ для хоста (require verify=true),
'show_node_info' => env('CENTRIFUGO_SHOW_NODE_INFO', false), // Показывать информацию о ноде в ответе
'timeout' => env('CENTRIFUGO_TIMEOUT', 3), // Общее время ожидания запроса к centrifugo api в секундах (по умолчанию 3)
'tries' => env('CENTRIFUGO_TRIES', 1), //Количество повторов запроса в случае неудачи (по умолчанию 1)
'token_expire_time' => env('CENTRIFUGO_TOKEN_EXPIRE', 120), //Базовое время, через которое истечет токен. Используется в подписках на каналы /broadcasting/auth
],
// .... //
];
Также вы должны добавить эти две строчки в ваш .env
файл:
CENTRIFUGO_SECRET=token_hmac_secret_key-from-centrifugo-config
CENTRIFUGO_APIKEY=api_key-from-centrifugo-config
CENTRIFUGO_URL=http://localhost:8000
Эти строки необязательны:
CENTRIFUGO_SSL_KEY=/etc/ssl/some.pem
CENTRIFUGO_VERIFY=false
CENTRIFUGO_API_PATH=/api
CENTRIFUGO_SHOW_NODE_INFO=false
CENTRIFUGO_TIMEOUT=10
CENTRIFUGO_TRIES=1
CENTRIFUGO_TOKEN_EXPIRE=120
Не забудьте изменить параметр BROADCAST_DRIVER
в файле .env!
BROADCAST_DRIVER=centrifugo
Настройте ваш сервер Centrifugo, детальнее в официальной документации
Для отправки событий, почитайте официальную документацию для Laravel
Laravel
// routes/channels.php
// ВАЖНО. В Centrifugo 4 символ '$' перед приватным каналом считается устаревшим. Не используйте его. https://centrifugal.dev/docs/server/channels#private-channel-prefix-
Broadcast::channel('private:channel', function (){
// Логика авторизации, пример:
return \Auth::user()->group === 'private-channel-group';
});
Broadcast::channel('public:channel', function (){
return true;
});
Frontend. Смотрите документацию centrifugal/centrifuge-js
// Пример:
import {Centrifuge} from 'centrifuge';
// Устанавливаем базовый путь Laravel broadcasting.
// Не забудьте добавить 'path' => [..., 'broadcasting/auth'] в файл cors.php вашего приложения
const subscribeTokenEndpoint = 'http://127.0.0.1/broadcasting/auth'
const centrifuge = new Centrifuge('ws://localhost:8001/connection/websocket', {
//CONNECTION_TOKEN необходимо получить через Centrifuge::generateConnectionToken(...)
token: 'CONNECTION_TOKEN'
})
// Устанавливаем подписку
const sub = centrifuge.newSubscription('test:test', {
getToken: function (ctx) {
return customGetToken(subscribeTokenEndpoint, ctx);
},
})
// Получение токена подписки от вашего Laravel приложения.
// Важно! В этом примере получение токена подписки реализуется через базовый fetch() без передачи параметров для идентификации пользователя в вашем Laravel приложении. Используйте методы подходящие вашему приложению
function customGetToken(endpoint, ctx) {
return new Promise((resolve, reject) => {
fetch(endpoint, {
method: 'POST',
headers: new Headers({'Content-Type': 'application/json'}),
body: JSON.stringify(ctx)
})
.then(res => {
if (!res.ok) {
throw new Error(`Unexpected status code ${res.status}`);
}
return res.json();
})
.then(data => {
resolve(data.token);
})
.catch(err => {
reject(err);
});
});
}
sub.subscribe();
centrifuge.connect();
Создайте событие (для примера - SendMessage) с помощью artisan php artisan make:event SendMessageEvent
<?php
// App/Events/SendMessageEvent.php
namespace App\Events;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
//Используйте "implements ShouldBroadcast" если хотите добавлять событие в очереди
class SendMessageEvent implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* @var string Текст сообщения
*/
private $messageText;
public function __construct(string $messageText)
{
$this->messageText = $messageText;
}
/**
* The event's broadcast name.
*
* @return string
*/
public function broadcastAs()
{
//Пример имени события. Будет отображено Web Socket JSON
return 'message.new';
}
/**
* Get the data to broadcast.
*
* @return array
*/
public function broadcastWith()
{
return ['message' => $this->messageText];
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('public:chat');
// или return new PrivateChannel('private:chat');
// в Centrifuge 4 все каналы являются защищенными, а префикс '$' считается устаревшим. https://centrifugal.dev/docs/server/channels#private-channel-prefix-
}
}
Простой пример использования клиента:
<?php
declare(strict_types = 1);
namespace App\Http\Controllers;
use Opekunov\Centrifugo\Centrifugo;
use Illuminate\Support\Facades\Auth;
class ExampleController
{
public function example(Centrifugo $centrifugo)
{
//или $centrifugo = new Centrifugo();
//или centrifugo()
// Отправить сообщение в канал
$centrifugo->publish('news', ['message' => 'Hello world']);
// Сгенерировать токен для подключения
$token = $centrifugo->generateConnectionToken((string)Auth::id(), 0, [
'name' => Auth::user()->name,
]);
// Сгенерировать токен подписки
$expire = now()->addDay(); //или вы можете использовать формат Unix: $expire = time() + 60 * 60 * 24;
$apiSign = $centrifugo->generatePrivateChannelToken((string)Auth::id(), 'channel', $expire, [
'name' => Auth::user()->name,
]);
//Получить список активных каналов.
$centrifugo->channels();
//Получить информацию о канале news, список активных клиентов
$centrifugo->presence('news');
}
}
Название | Описание |
---|---|
publish(string $channel, array $data) | Отправка сообщения в канал |
broadcast(array $channels, array $data) | Отправить сообщение в несколько каналов. |
publishMany(array $data) | Отправка нескольких сообщений на несколько каналов. $data - массив массивов данных [канал, данные] |
presence(string $channel) | Получите информацию о присутствии в канале (все клиенты в настоящее время подписаны на этот канал). |
presenceStats(string $channel) | Получите краткую информацию о канале (количество клиентов). |
history(string $channel) | Получить информацию об истории канала (список последних сообщений, отправленных в канал). |
historyRemove(string $channel) | Удалить информацию из истории канала. |
unsubscribe(string $channel, string $user) | Отписать пользователя от канала. |
disconnect(string $userId) | Отключить пользователя по его ID. |
channels() | Cписок текущих активных каналов. |
info() | Статистическая информация о запущенных серверных узлах. |
generateConnectionToken(string|int $userId, int|Carbon $exp = 0, array $info = []) | Генерация токена для подключения |
generateSubscriptionToken(string|int $userId, string $channel, int|Carbon $exp = 0, array $info = [], array $override = []) | Генерация приватного токена для приватного канала |
Лицензия MIT. Пожалуйста прочитайте Файл лицензии для получения дополнительной информации.