conveyor-laravel-broadcaster maintained by kanata-php
Conveyor Laravel Broadcaster
This is a Laravel Integration for Socket Conveyor. It allows you to use the Conveyor WebSocket server as a broadcasting driver for Laravel. This package doesn't need Jacked Server, but just know that that web server is great!
This package allows the usage of Conveyor as a broadcasting driver in Laravel.
To understand how to broadcast with Laravel, visit Broadcasting.
Requirements
- PHP
^8.2 - Laravel 11 or 12
- A running Conveyor WebSocket server (see Extra)
The companion server package
kanata-php/socket-conveyordeclaresext-openswoole: ^22. This package overrides the platform requirement viaconfig.platformincomposer.json, so newer openswoole versions install cleanly without--ignore-platform-reqflags.
Quick Start
Table of Contents
- Step 1: Install the package via composer
- Step 2: Publish the configuration
- Step 3: Add Service Provider
- Step 4: Enable Laravel broadcasting
- Step 5: Add broadcasting config
- Step 6: Set configuration
- Step 7: Create the tokens table
- Step 8: Install the Conveyor JS Client
- Extra: Simple Conveyor Server for this example
Step 1: Install the package via composer
composer require kanata-php/conveyor-laravel-broadcaster
Step 2: Publish the configuration
php artisan vendor:publish --provider="Kanata\LaravelBroadcaster\ConveyorServiceProvider"
Step 3: Add Service Provider
Laravel 10 backwards:
<?php
return [
// ...
'providers' => [
// ...
Kanata\LaravelBroadcaster\ConveyorServiceProvider::class,
],
// ...
];
Laravel 11 onwards:
<?php
return [
// ...
Kanata\LaravelBroadcaster\ConveyorServiceProvider::class,
];
Step 4: Enable Laravel broadcasting
This is for Laravel 11 and forward, if in any other version just skip this step!
php artisan install:broadcasting --without-reverb --without-node
Step 5: Add broadcasting config
Add the following to your config/broadcasting.php file:
<?php
return [
// ...
'conveyor' => [
'driver' => 'conveyor',
'protocol' => env('CONVEYOR_PROTOCOL', 'ws'),
'host' => env('CONVEYOR_URI', 'localhost'),
'port' => env('CONVEYOR_PORT', 8181),
'query' => env('CONVEYOR_QUERY', ''),
],
];
Step 6: Set configuration
Set the configurations for the WebSocket server in the .env file:
# ...
BROADCAST_CONNECTION=conveyor
# ...
CONVEYOR_URI=127.0.0.1
CONVEYOR_PORT=8181
CONVEYOR_QUERY="token=my-secure-conveyor-token"
# ...
CONVEYOR_QUERYis the url query where we add the token you set to protect your WebSocket server.
Step 7: Create the tokens table
This package issues short-lived JWT tokens stored in a conveyor_tokens table. The package no longer ships a migration, so you must add one in your application:
php artisan make:migration create_conveyor_tokens_table
Then in the generated migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('conveyor_tokens', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->foreignId('user_id');
$table->string('aud')->nullable();
$table->text('token');
$table->string('aud_protocol')->nullable();
$table->integer('allowed_uses')->nullable();
$table->integer('uses')->nullable();
$table->dateTime('expire_at')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('conveyor_tokens');
}
};
php artisan migrate
Step 8: Install the Conveyor JS Client:
npm install socket-conveyor-client
Important: Don't forget to run
npm run build!
Add this to the bootstrap.js file of your Laravel app so the Conveyor client is available globally:
import Conveyor from "socket-conveyor-client";
window.Conveyor = Conveyor;
Remember to run npm install and npm run dev or npm run prod to compile the assets.
Info: If you want to send one-off messages to the Conveyor WebSocket server, you can just dispatch an event like follows:
<?php namespace App\Events; use Illuminate\Broadcasting\InteractsWithBroadcasting; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; class TestEvent implements ShouldBroadcastNow { use InteractsWithBroadcasting; public function __construct( public string $message, public string $channel, ) { $this->broadcastVia('conveyor'); } public function broadcastOn(): array { return [ new PrivateChannel($this->channel), ]; } }event(new App\Events\TestEvent( message: 'my message', channel: 'my-channel'));
Important: notice that we are using
ShouldBroadcastNowinstead ofShouldBroadcast. Conveyor doesn't need queueing and is much faster this way. If you want, you can still use queues.
Example of usage in a view with authorization at this point:
<html>
<head>
<title>WS Client</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<textarea id="msg"></textarea>
<button id="btn-base">Base</button>
<button id="btn-broadcast">Broadcast</button>
<ul id="output"></ul>
<script type="text/javascript">
// page elements
const msg = document.getElementById('msg')
const btnBase = document.getElementById('btn-base')
const btnBroadcast = document.getElementById('btn-broadcast')
const output = document.getElementById('output')
const connect = () => {
window.conveyor = new window.Conveyor({
protocol: '{{ $protocol }}',
uri: '{{ $uri }}',
port: {{ $wsPort }},
channel: '{{ $channel }}',
token: '{{ \Kanata\LaravelBroadcaster\Conveyor::getToken($channel) }}',
onMessage: (e) => output.innerHTML = e,
onReady: () => {
btnBase.addEventListener('click', () => window.conveyor.send(msg.value))
btnBroadcast.addEventListener('click', () => window.conveyor.send(msg.value, 'broadcast-action'))
},
});
};
document.addEventListener("DOMContentLoaded", () => connect());
</script>
</body>
</html>
Then, add the route for this view at your routes/web.php file:
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;
Route::get('/ws-client', function () {
Auth::loginUsingId(1); // here we authorize for the sake of the example.
return view('ws-client', [
'protocol' => config('broadcasting.connections.conveyor.protocol'),
'uri' => config('broadcasting.connections.conveyor.host'),
'wsPort' => config('broadcasting.connections.conveyor.port'),
'channel' => 'private-my-channel',
]);
});
Extra: Simple Conveyor Server for this example
You can use this simple server to test your broadcasting (and in production...):
<?php
// file: server.php
include __DIR__ . '/vendor/autoload.php';
use Conveyor\ConveyorServer;
use Conveyor\Events\MessageReceivedEvent;
use Conveyor\Events\PreServerStartEvent;
(new ConveyorServer())
// if you want to see messages in the console
->eventListeners([
Conveyor\Constants::WEBSOCKET_SERVER_TOKEN => 'my-secure-conveyor-token',
Conveyor\Constants::EVENT_MESSAGE_RECEIVED => function (MessageReceivedEvent $event) {
var_dump($event->data);
},
])
->port(8181)
->start();
Remember to install conveyor with composer require kanata-php/socket-conveyor and run the server with php server.php.
License
Released under the MIT License.