
Compartilhar:
Sou ator formado, com uma dissertação sobre stand-up comedy, e comecei a me dedicar ao desenvolvimento em PHP por meio dos encontros da comunidade. Você pode me encontrar dando palestras e escrevendo sobre tecnologia, ou ouvindo e comprando discos curiosos da minha coleção de vinil.
Mensagens RCS com Laravel, Livewire, Reverb e Echo
Tempo de leitura: 13 minutos
Time to get our hands dirty with RCS and Laravel!Resumo: Você pode encontrar o código de demonstração aqui.
Laravel Livewire é uma forma poderosa de eliminar a complexidade do front-end. Neste tutorial, vamos usá-lo para criar um RCS (Rich Communication Services) com a Messages API for Vonage. Não acredito que demorei tanto tempo para experimentar o Laravel Livewire, considerando que a versão 1.0.0 foi lançada lá em 2020. O Livewire se inspira no biblioteca Ruby on Rails biblioteca Hotwire e faz algo que realmente me toca profundamente: elimina o código complexo do front-end. Como parte do que ficou conhecido como a TALL , está certamente sendo amplamente adotado.
RCS significa Rich Communication Services, e é um protocolo de mensagens moderno e mais avançado do que o padrão de fato das mensagens SMS. O SMS foi aprimorado com o advento do MMS (Multimedia Messaging), mas também ficou visivelmente mais lento, já que este último ainda dependia da rede GSMA. O RCS utiliza apenas dados, portanto, não importa se você está usando Wi-Fi ou 4/5G: em nosso mundo hiperconectado de infraestrutura de dados, isso significa que suas mensagens agora são significativamente mais rápidas. Ele também está implementado nas mesmas applications de mensagens em dispositivos celulares que as mensagens SMS nativas; portanto, o RCS está pronto para uso na maioria dos dispositivos fabricados nos últimos 5 anos.
Bem, que melhor exemplo de uso para fazer algo em tempo real com o Livewire do que implementar o RCS em um aplicativo web de mensagens? É exatamente isso que vamos fazer neste tutorial.
Pré-requisitos
PHP 8.4 ou superior
Instalador do Laravel
Nó 22+
Npm 6 ou superior
Um Account da Vonage
Instalar o Laravel
O instalador do Laravel é um wrapper prático em torno de Composer que você pode instalar globalmente para iniciar novas aplicações Laravel com facilidade. Ao instalar, escolha o kit inicial do Livewire, a autenticação integrada do Laravel, o Volt pode ser ignorado e, por fim, a escolha da estrutura de testes não importa. Agora você terá uma aplicação Laravel completa instalada. Certifique-se de executar as migrações integradas para criar a estrutura da tabela Users para autenticação.
Instalar o Livewire
Caleb Porzio lançou o Livewire em 2020 e causou um grande rebuliço na época. Já mencionei que ele elimina as complexidades do front-end, mas o que exatamente é isso? Você, leitor, talvez seja como eu. Sou um desenvolvedor de back-end que fica constantemente coçando a cabeça diante das tarefas mais básicas do front-end. O Livewire fornece componentes de front-end em PHP como se fossem componentes em JavaScript. Portanto, o gerenciamento de estado e comportamento é feito inteiramente dentro do código PHP que você conhece e adora, com uma API bem documentada para explorar. Para instalar o Livewire, use o Composer:
composer install livewire/livewire Criar migrações e modelos
Existem duas entidades para o envio de mensagens das quais precisaremos: uma Message e uma Conversation. A relação aqui é que as Mensagens pertencem a uma Conversação, e uma Conversação pertence a um usuário. Essa é uma relação importante a ser observada e estabelecida, pois, quando chegarmos à transmissão de eventos (ou seja, mensagens recebidas), o front-end precisará ser capaz de associá-las a um usuário.
Crie suas migrações na linha de comando:
php artisan make:model Conversation --migration
php artisan make:model Message --migrationObserve que, como estamos criando o modelo — e não a migração —, usamos nomes no singular em vez do plural. A migração foi gerada ao adicionar --migration ao comando; agora, podemos definir como essas entidades aparecerão no banco de dados.
create_conversations_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('conversations', function (Blueprint $table) {
$table->id();
$table->string('uuid');
$table->foreignId('user_id')->constrained('users');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('conversations');
}
};
create_messages_migration.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->string('message');
$table->timestamps();
$table->foreignId('conversation_id')->constrained();
$table->string('source');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('messages');
}
};É importante notar que há um source campo, que terá apenas dois valores:
internalexternal
Isso é importante para que o front-end consiga exibir corretamente uma visualização semelhante a uma conversa.
Também adicionamos as relações necessárias; portanto, agora definimos as relações nos modelos:
Models\Conversation.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Conversation extends Model
{
public $timestamps = false;
public function messages(): HasMany
{
return $this->hasMany(Message::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
Models\Messages.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
class Message extends Model
{
use BroadcastsEvents;
public $timestamps = true;
public $table = 'messages';
public $fillable = ['message', 'conversation_id', 'created_at', 'updated_at'];
public function conversation()
{
return $this->belongsTo(Conversation::class);
} Preenchimento inicial do seu banco de dados
Há duas coisas que precisamos definir:
Um usuário de teste (em vez de se cadastrar pela interface do usuário)
Uma conversa provisória à qual as mensagens serão anexadas. Na prática, seria recomendável criar essas conversas dinamicamente, mas, para os fins deste tutorial, todas as mensagens serão vinculadas a uma conversa provisória.
Gere o MessagesSeeder na linha de comando:
php artisan make:seeder MessagesSeederAgora, o seeder vai lidar com os dois placeholders de que precisamos:
MessagesSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Conversation;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class MessagesSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$user = User::create([
'name' => 'Admin',
'email' => 'admin@admin.com',
'password' => Hash::make('password'),
]);
$conversation = Conversation::create([
'uuid' => 'e2efbc00-b65e-4e47-8996-1de0043ed667',
'user_id' => $user->id
]);
}
}A execução das migrações e dos seeders agora deixará tudo pronto no banco de dados antes de começarmos a interagir com ele:
php artisan migrate
php artisan db:seed Escreva o controlador
Com nossos dados configurados, é hora de criar uma rota e um controlador.
php artisan make:controller MessagesControllerPor enquanto, o controlador vai fazer apenas uma coisa: renderizar uma visualização.
<?php
namespace App\Http\Controllers;
use App\Models\Message;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class MessagesController extends Controller
{
public function index()
{
return view('messages');
}
}Essa opinião, messages, ainda não existe, então vamos criá-la:
php artisan make:view messagesE vamos programar:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Livewire Messenger</title>
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=instrument-sans:400,500,600" rel="stylesheet" />
@vite(['resources/css/app.css', 'resources/js/app.js'])
@fluxAppearance
</head>
<body class="bg-gray-100 min-h-screen flex flex-col" style="background-image: url('{{ asset('vonage background.png') }}'); background-size: cover; background-position: center;">
<div class="flex items-center space-x-3 p-4 bg-black">
<img src="{{ asset('vonage-logo.png') }}" alt="Vonage Logo" class="h-16 px-4 w-auto">
<h2 class="text-xl font-bold text-white drop-shadow">Laravel Livewire x Reverb x Echo Messenger</h2>
</div>
</body>
</html>Por fim, junte tudo isso em uma rota:
routes/web.php
Route::get('/messages', [MessagesController::class, 'index']); Escreva um componente Livewire
É hora de introduzir algumas funcionalidades. Em vez da abordagem tradicional Modelo-Visão-Controlador, este aplicativo utilizará as funcionalidades de um componente Livewire. Para desenvolvedores de PHP, os componentes Livewire parecerão um controlador comum com seu próprio modelo de visualização emparelhado, mas as alterações de estado serão enviadas para o front-end. Crie um controlador Livewire na linha de comando:
php artisan livewire:make RcsComponentEste componente Livewire será incluído na message visualização. Esse componente carregará todas as mensagens da conversa inicial e, em seguida, realizará duas ações:
A opção de enviar uma mensagem, que será enviada à Vonage usando o SDK do PHP. O envio dessa mensagem recarrega o componente, recuperando novamente as mensagens por meio do ORM, e o Livewire atualizará o estado
Ficará atento a alterações na conversa inicial e as carregará quando um controlador receber um webhook da Vonage
Escreva o modelo do componente
Os modelos do Livewire ficam em um diretório diferente do dos modelos comuns Blade . Acesse o modelo do novo componente e defina alguns estilos:
livewire/rcs-component.blade.php
<div class="flex-1 flex flex-col justify-between px-4">
<div class="overflow-y-auto space-y-2 mb-4 px-2" style="max-height: calc(100vh - 200px);">
@forelse ($messages as $message)
<div class="flex {{ $message->source === 'internal' ? 'justify-end' : 'justify-start' }}">
<div class="max-w-xs md:max-w-md px-4 py-2 rounded-lg
{{ $message->source === 'internal' ? 'bg-green-500 text-white rounded-br-none' : 'bg-white text-gray-800 rounded-bl-none shadow' }}">
<p>{{ $message->message }}</p>
<p class="text-xs text-gray-300 mt-1 text-right">
{{ $message->created_at->diffForHumans() }}
</p>
</div>
</div>
@empty
<p class="text-gray-100 text-center mt-4">No messages found.</p>
@endforelse
</div>
<form wire:submit.prevent="sendMessage" class="flex items-center space-x-2 border-t pt-2 bg-white p-2 rounded shadow">
<input
type="text"
wire:model.defer="postMessage"
placeholder="Type a message"
class="flex-1 border text-black rounded-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-offset-purple-500"
>
<button type="submit" class="bg-purple-500 text-white px-4 py-2 rounded-full hover:bg-purple-400">
Send
</button>
</form>
</div>Isso cria um painel de mensagens no estilo do “WhatsApp”. O componente recebe qualquer coleção que tenha sido incluída como $messages, exibe-a e inclui a sintaxe para chamar o código PHP no componente Livewire para enviar uma mensagem, usando o método sendMessage(). Ainda não codificamos isso, então vá até a lógica do componente Livewire e codifique o seguinte:
Livewire\RcsComponent
<?php
namespace App\Livewire;
use App\Models\Conversation;
use App\Models\Message;
use Illuminate\Support\Facades\Http;
use Livewire\Component;
use Vonage\Client;
use Vonage\Messages\Channel\RCS\RcsText;
class Rcs extends Component
{
public $messages;
public string $postMessage = '';
public function mount()
{
$this->loadMessages();
}
public function loadMessages(): void
{
$conversation = Conversation::where('uuid', env('CONVERSATION_ID'))->first();
$this->messages = Message::where('conversation_id', $conversation->id)->orderBy('timestamp', 'desc')->get();
}
public function sendMessage(): void
{
Http::withHeaders(['Accept' => 'application/json'])
->post(route('messages.store'), [
'message' => $this->postMessage,
'source' => 'internal'
]);
$this->postMessage = '';
$this->loadMessages();
}
public function render()
{
return view('livewire.rcs-component', $this->messages);
}
public function refresh()
{
$this->loadMessages();
}
}Há bastante coisa para analisar aqui, então vamos examinar a lógica:
A propriedade de classe
$postMessagefunciona como estado do componente. Esse estado corresponde à mensagem atual que está sendo processada e, se você observar o modelo do componente, verá que há uma sintaxe que conecta o front-end ao back-end:wire:model.defer="postMessage"A propriedade de classe
$messagestambém funciona como estado do componente e é o conjunto completo de mensagens associadas à conversa. Essa propriedade é, então, renderizada no modelo que criamos anteriormentefor $messages as $message)Existem três métodos mágicos específicos do Livewire aqui:
mount()é executado quando o componente é renderizado pela primeira vez,refresh()é executado sempre que ocorre alguma alteração no estado, erender()é executado no final do ciclo de vida do componente, daí o código para carregar o modelo.mount()chama um método que é reutilizado emrender()que é chamado deloadMessages()loadMessages()usa o ORM Eloquent para fazer duas coisas. Em primeiro lugar, demos uma “trapinha” ao recuperar umConversation, no sentido de que ele usa uma variável de ambiente,CONVERSATION_ID, que é o nosso ID preenchidoConversation. Todas as mensagens associadas a esse ID são então buscadas e gravadas na$messagespropriedade.
Ainda não adicionamos a variável de ambiente, então acesse seu .env e adicione CONVERSATION_ID=e2efbc00-b65e-4e47-8996-1de0043ed667 a ela. Esse ID é o mesmo UUID que foi gravado na conversa fictícia inicial.
É uma boa prática, já que estamos criando uma API simulada com base no funcionamento dessas entidades, expor suas entidades via REST. Você vai perceber que o sendMessage método não usa o ORM Eloquent para criar uma nova mensagem e salvá-la no banco de dados; em vez disso, ele pega o conteúdo de $postMessage e o envia via POST para o endpoint da API interna exposta. Isso requer um endpoint que ainda não foi programado; portanto, acesse seu arquivo de rotas e adicione-o:
routes\web.php
Route::post('/create-message', [MessagesController::class, 'store'])->name(messages.store');Agora, adicione o store() método ao MessagesController:
MessagesController.php
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'message' => 'required|string',
]);
$conversation = Conversation::where('uuid', env('CONVERSATION_ID'))->first();
$message = new Message();
$message->message = $validated['message'];
$message->created_at = now();
$message->updated_at = now();
$message->conversation_id = $conversation->id;
$message->save();
return response()->json([
'status' => 'success',
'data' => $message
], 201);
}A entrada é validada e, em seguida, nessa lógica, a Message entidade é persistida no banco de dados e anexada à Conversation entidade fictícia pré-preenchida.
Integração com o Livewire
Para que o Livewire funcione, é necessário adicionar alguns estilos e código JavaScript aos modelos do seu aplicativo. Há alguns métodos auxiliares úteis incluídos que podem ser usados no Blade. Acesse a página do modelo pai do componente e altere o código da seguinte forma:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Livewire Messenger</title>
@livewireStyles
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=instrument-sans:400,500,600" rel="stylesheet" />
@vite(['resources/css/app.css', 'resources/js/app.js'])
@fluxAppearance
</head>
<body class="bg-gray-100 min-h-screen flex flex-col" style="background-image: url('{{ asset('vonage background.png') }}'); background-size: cover; background-position: center;">
<div class="flex items-center space-x-3 p-4 bg-black">
<img src="{{ asset('vonage-logo.png') }}" alt="Vonage Logo" class="h-16 px-4 w-auto">
<h2 class="text-xl font-bold text-white drop-shadow">Laravel Livewire x Reverb x Echo Messenger</h2>
</div>
<livewire:rcs />
@livewireScripts
</body>
</html>As três novidades aqui são:
@livewireStylespara incluir classes CSS essenciais@livewireScriptspara incorporar funcionalidades essenciais do JavaScript<livewire:rcs />insere nosso componente Livewire na página.
Escreva o controlador do webhook
A próxima funcionalidade que o aplicativo precisa ter é a capacidade de processar dados recebidos da Vonage na forma de um webhook. Esse webhook é configurado no painel da Vonage para ser acionado em uma URL definida pelo usuário como uma carga JSON quando um usuário responde ao número configurado na conversa no dispositivo do usuário final. HTTP POST. Primeiro, adicione a rota:
routes\web.php
Route::post('/messages/webhook', [MessagesController::class, 'webhook'])->name(messages.webhook');Agora, vamos adicionar o webhook() método ao MessagesController.
MessagesContoller.php
public function webhook(Request $request)
{
$payload = $request->all();
$newMessage = Message::create([
'message' => $payload['text'],
'source' => 'external',
'conversation_id' => 1
]);
return response()->json([
'status' => 200
]);
}Originalmente, escrevi essa lógica para reutilizar a API REST, mas havia implicações de segurança em lidar com dois domínios diferentes em tempo de execução; por isso, neste exemplo, dei uma “saída fácil” e usei o Eloquent para gravar a mensagem do webhook no banco de dados e retornar um código 200 para a Vonage.
Já conectamos todas as peças internas, mas provavelmente você já percebeu que ainda não estamos enviando nada para a Vonage ainda. Isso precisa ser feito no seu sendMessage método que está no componente Livewire. O SDK PHP da Vonage requer um ID de aplicativo e um private.key, que é criado no Painel de Controle da Vonage, e um número precisa ser atribuído ao aplicativo.
Para criar um aplicativo, acesse a página “Criar um aplicativo” no Painel da Vonage e defina um Nome para a sua Application.
Se você pretende usar uma API que utilize Webhooks, precisará de uma chave privada. Clique em “Gerar chave pública e privada”; o download deve iniciar automaticamente. Guarde-a em local seguro; essa chave não poderá ser baixada novamente em caso de perda. Ela seguirá a convenção de nomenclatura private_<seu ID de aplicativo>.key. Agora, essa chave pode ser usada para autenticar chamadas de API. Observação: sua chave não funcionará até que seu aplicativo seja salvo.
Escolha os recursos de que você precisa (por exemplo, Voice, Mensagens, RTC etc.) e forneça os webhooks necessários (por exemplo, URLs de eventos, URLs de resposta ou URLs de mensagens recebidas). Esses itens serão descritos no tutorial.
Para salvar e implantar, clique em “Gerar novo aplicativo” para finalizar a configuração. Seu aplicativo já está pronto para ser usado com as APIs da Vonage.
O RCS exige que você se cadastre como agente antes de poder usá-lo. Para obter informações sobre como fazer isso, consulte este artigo.
Sua aplicação precisará estar exposta à internet para que a Vonage possa enviar webhooks para ela. Fazemos isso usando o ngrok. Depois de instalar o ngrok, execute-o na linha de comando:
ngrok http 8080Você receberá uma URL pública que aponta para a sua porta 8080. Essa URL precisa ser inserida no Painel de Controle da Vonage para o seu aplicativo RCS, da seguinte forma:
Configuring our webhooks
Configurar o Vonage em PHP
O sendMessage() no momento não envia nenhuma mensagem, então é hora de configurar isso. Instale o SDK PHP da Vonage usando o Composer na linha de comando:
composer require vonage/clientAgora, usando as credenciais da nossa conta da Vonage e o private.key baixadas do Painel de Controle, configuramos nosso objeto Client e o usamos para enviar a mensagem RCS. Seu sendMessage() deve ficar assim:
public function sendMessage(): void
{
$applicationId = 'your-application-id';
$privateKey = file_get_contents(base_path(config('path-to-your-private-key')));
$credentials = new Client\Credentials\Keypair($privateKey, $applicationId);
$client = new Client($credentials);
$rcsMessage = new RcsText('your-vonage-number, 'your-configured-from-id, $this->postMessage);
$client->messages()->send($rcsMessage);
Http::withHeaders(['Accept' => 'application/json'])
->post(route('messages.store'), [
'message' => $this->postMessage,
'source' => 'internal'
]);
$this->postMessage = '';
$this->loadMessages();
}O Client é criado com um Keypair, que o configura para lidar automaticamente com a autenticação JWT para quaisquer chamadas da Vonage. Em seguida, ele chama a Messages API com o método encadeado messages() e utiliza send(). Esse método, como parte da integração da Messages API, aceita qualquer objeto válido que esteja em conformidade com as interfaces de mensagem internamente. O objeto para enviar uma mensagem RCS é RcsText.
Há algumas variáveis de ambiente que precisam ser configuradas aqui — já verificamos suas credenciais, mas o RCS também exige os números “para” e “de”. O número “para” é o seu dispositivo de destino, e o “de” é a chave configurada no seu agente RCS.
É hora da mágica. A limitação aqui é que, com o Livewire, o componente será atualizado quando você enviar uma mensagem (já que ele usa o refresh(), que, por sua vez, chamará loadMessages() MAS, como o componente do Livewire sabe de um webhook recebido, que deveria então atualizar o estado?
A resposta vem na forma do superbrilhante Model Broadcasting . Em outras palavras, o Laravel permite que você acesse o sistema de eventos existente sempre que um modelo for alterado. Isso significa que, toda vez que um Message é criado (ou seja, quando um webhook chega e é gravado no banco de dados), podemos usar um servidor WebSocket para escutar e instruir o Livewire a refresh().
Há duas bibliotecas que precisamos instalar para fazer isso: Laravel Reverb (o servidor WebSocket de transmissão) e Laravel Echo (biblioteca do lado do cliente para escutar eventos). O Reverb é instalado usando o Console do Laravel:
php artisan install:broadcastingO Echo é instalado usando o npm:
npm install --save-dev laravel-echo pusher-jspusher-js é o protocolo que o Echo utiliza nos bastidores; por isso, ele está incluído no comando.
Integração do Echo
A raiz do JavaScript do seu aplicativo precisa ter uma Echo pronta para receber as transmissões do Reverb. Vá até resources\js e crie um novo arquivo chamado echo.js. Preencha-o da seguinte forma:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
let echo = 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 ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
echo.privateApp.Models.Conversation.1)
.listen('.MessageCreated', (e) => {
console.log(e);
});
window.Echo = echo;Aqui é identificado um canal para ouvir: App.Models.Conversation.1 está codificado de forma estática. Como temos apenas nosso único objeto inicializado Conversation , neste caso, será sempre este. A convenção de nomenclatura do canal vem do nosso channel.php , que ainda não foi escrito, o que acontecerá em breve, mas é interessante notar que .MessageCreated essa é uma convenção de nomenclatura do Model Broadcasting integrado ao Laravel.
echo.private é usado porque os eventos do Model Broadcasting só podem ser emitidos a partir de canais privados. Uma coisa à qual é preciso prestar muita atenção (e eu não prestei no início, o que resultou em duas horas fantásticas de depuração à toa) é que eles só podem ser canais privados porque o Model Broadcasting está vinculado ao mecanismo de autenticação do Laravel. Portanto, para que isso funcione, você precisará estar conectado como o usuário predefinido que criamos.
O echo.js precisa ser incluído no momento da inicialização do aplicativo; portanto, inclua-o no resources\js\app.js arquivo:
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allow your team to quickly build robust real-time web applications.
*/
import './echo'; Integração da reverberação
Temos um mecanismo que monitora os eventos, mas ainda não programamos a transmissão deles. Isso envolve três partes:
Configuração da rota do canal de transmissão
Adicionando a transmissão ao modelo
Configurando o Livewire para reagir a eventos propagados
Configurando o canal de transmissão
Ao instalar o Reverb, o novo arquivo de rotas para os canais é criado como routes\channels.php. É aqui que indicamos ao Reverb para transmitir.
channels.php
Broadcast::channel('App.Models.Conversation.{id}', function ($user, $id) {
return $user->conversations->firstOrFail('id', $id)->exists;
});O channel método espera um valor booleano para indicar se o ID da conversa está disponível para o usuário como porta de autenticação.
Incorporando a transmissão ao modelo
Há duas coisas que você precisará adicionar ao modelo — sendo que, neste caso, o modelo é a Message entidade. O Reverb possui um trait chamado BroadcastEvents que disponibiliza a interface para uso do WebSocket. Você precisará incluí-la no código, o que disponibiliza o broadcastOn método a ser sobrecarregado.
O código final do modelo fica assim:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\BroadcastsEvents;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
class Message extends Model
{
use BroadcastsEvents;
public $timestamps = true;
public $table = 'messages';
public $fillable = ['message', 'conversation_id', 'created_at', 'updated_at'];
public function conversation()
{
return $this->belongsTo(Conversation::class);
}
public function broadcastOn(string $event)
{
return [$this->conversation];
}
}Antes de entrarmos na lógica por trás broadcastOn(), você vai notar que vários campos foram incluídos em $fillable. Essa propriedade especifica quais campos do modelo podem ser preenchidos automaticamente por meio da hidratação; portanto, esses campos foram incluídos na matriz devido à hidratação do Webhook.
Devido à transmissão do modelo, o endereço de canal embutido deste modelo seria App.Model.Conversation, portanto, retornar um valor de $this->conversation resulta no identificador de string de transmissão necessário, que é App.Model.Conversation.{id}. BroadcastEvents emite as ações CRUD neste modelo, mas instruímos o sistema a transmitir no ID da Conversação para escuta.
Juntando tudo isso
Tudo bem, vou admitir: já nos aprofundamos em uma quantidade extraordinária de raciocínio lógico só para não usar JavaScript. Mas, olha, estou tranquilo com isso porque sou o desenvolvedor “mais ou menos” do mundo. Além disso, sabe, adoro a inovação que frameworks como o Laravel continuam promovendo.
Agora há dois servidores que você precisa executar: O Vite precisa estar em execução para compilar os recursos do front-end, e o Reverb precisa estar em execução para transmitir os eventos que o Echo monitora. No seu terminal, inicie-os da seguinte forma:
php artisan reverb:start
npm run devUfa! É muita fiação. Mas vale a pena, né? Com tudo ligado, faça login e comece a enviar algumas mensagens!
I absolutely did not use ChatGPT to sort out my styling
Have a question or want to share what you're building?
Subscribe to the Developer Newsletter
Follow us on X (formerly Twitter) for updates
Watch tutorials on our YouTube channel
Connect with us on the Vonage Developer page on LinkedIn
Stay connected and keep up with the latest developer news, tips, and events.
Compartilhar:
Sou ator formado, com uma dissertação sobre stand-up comedy, e comecei a me dedicar ao desenvolvimento em PHP por meio dos encontros da comunidade. Você pode me encontrar dando palestras e escrevendo sobre tecnologia, ou ouvindo e comprando discos curiosos da minha coleção de vinil.