https://a.storyblok.com/f/270183/1368x665/130eed24e1/25oct_dev_blog_laravel-liveware-reverb-echo.jpg

Mensajería RCS con Laravel, Livewire, Reverb y Echo

Publicado el October 21, 2025

Tiempo de lectura: 13 minutos

Abstract graphic depecting messaging on a phoneTime to get our hands dirty with RCS and Laravel!TLDR; Puede encontrar el código de demostración aquí.

Laravel Livewire es una poderosa forma de eliminar la complejidad del frontend. En este tutorial, lo usaremos para construir un RCS (Servicios de Comunicación Enriquecidos) con Mensajes API de VonageNo puedo creer que me haya tomado tanto tiempo poner mis manos en Laravel Livewireconsiderando que la versión 1.0.0 fue lanzada en 2020. Livewire se inspira en Ruby on Rails biblioteca Hotwire y hace algo que realmente me apasiona: elimina el complejo código frontend. Como parte de lo que se conoce como el proyecto TALL está siendo muy adoptada.

RCS son las siglas de Servicios de Comunicación Enriquecidosy es un protocolo de mensajería moderno y más avanzado que el estándar de facto de mensajería SMS. El SMS se vio mejorado con la llegada del MMS (Multimedia Messaging), pero también era notablemente más lento debido a que este último seguía dependiendo de la red GSMA. RCS sólo utiliza datos, por lo que no importa si usas Wi-Fi o 4/5G: en nuestro mundo hiperconectado de infraestructura de datos, esto significa que tu mensajería es ahora significativamente más rápida. También se implementa en las mismas aplicaciones de mensajería de los dispositivos móviles que la mensajería SMS nativa, por lo que RCS está listo para funcionar en la mayoría de los dispositivos fabricados en los últimos 5 años.

Bueno, ¿qué mejor caso de uso para hacer algo en tiempo real usando Livewire que implementar RCS en una aplicación web de mensajería? Eso es lo que vamos a hacer en este tutorial.

Requisitos previos

  • PHP 8.4+

  • Instalador de Laravel

  • Nodo 22+

  • Npm 6+

  • Una cuenta de Vonage

  • ngrok

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

Instalar Laravel

El instalador de Laravel es una envoltura limpia alrededor de Composer que puedes instalar de forma global para arrancar cómodamente nuevas aplicaciones Laravel. Cuando instales, elige el kit de inicio Livewire, la autenticación integrada de Laravel, Volt puede omitirse, y por último, la elección del framework de pruebas no importa. Ahora tendrás una aplicación Laravel completa instalada. Asegúrate de ejecutar las migraciones integradas para crear la tabla Users para la autenticación.

Instalar Livewire

Caleb Porzio lanzó Livewire en 2020 y causó bastante revuelo en su momento. Ya he dicho que elimina las complejidades del frontend, pero ¿qué es exactamente? Puede que tú, lector, seas como yo. Soy un desarrollador back-end que constantemente se rasca la cabeza ante las tareas front-end más básicas. Livewire envía componentes PHP frontend como si fueran componentes JavaScript. Por lo tanto, el manejo del estado y el comportamiento se hace todo dentro del código PHP que conoces y amas, con una API bien documentada para explorar. Para instalar Livewire, utilice Composer:

composer install livewire/livewire

Crear migraciones y modelos

Hay dos entidades para mensajería que necesitaremos: a Message y a Conversation. La relación aquí es que los mensajes pertenecen a una Conversación, y una Conversación pertenece a un usuario. Esta es una relación importante a tener en cuenta y establecer, ya que cuando lleguemos a la difusión de eventos (es decir, mensajes entrantes), el frontend tendrá que ser capaz de vincularlo a un usuario.

Cree sus migraciones en la línea de comandos:

php artisan make:model Conversation --migration
php artisan make:model Message --migration

Tenga en cuenta que, dado que estamos creando el modelo en lugar de la migración, utilizamos la nomenclatura en singular en lugar de en plural. La migración se ha generado añadiendo --migración al comando, así que ahora podemos definir el aspecto de estas entidades en la base de datos.

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');
   }
};

Lo importante es que puede ver que hay un campo source que sólo tendrá dos valores:

  • internal

  • external

Esto es importante para que el frontend pueda renderizar correctamente una vista similar a una conversación.

También hemos añadido las relaciones necesarias, así que ahora definimos las relaciones en los 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);
   }

Sembrar la base de datos

Hay dos cosas que tenemos que sembrar:

  • Un usuario de prueba (en lugar de registrarse a través de la interfaz de usuario)

  • Una conversación de marcador de posición para los mensajes que se adjuntará a. En realidad, querrás crear estas conversaciones dinámicamente, pero para los propósitos de este tutorial, cada mensaje será atado a un marcador de posición.

Genera el MessagesSeeder en la línea de comandos:

php artisan make:seeder MessagesSeeder

Ahora, la sembradora se encargará de los dos marcadores de posición que necesitamos:

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
       ]);
   }
}

Ejecutar las migraciones y los sembradores ahora pondrá todo en su lugar en la base de datos antes de empezar a interactuar con ellos:

php artisan migrate
php artisan db:seed

Escriba el controlador

Con nuestros datos configurados, es hora de crear una ruta y un controlador.

php artisan make:controller MessagesController

Por ahora, el controlador sólo va a hacer una cosa, que es renderizar una vista.

<?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');
   }
}

Esa vista, messages, aún no existe, así que vamos a crearla:

php artisan make:view messages

Y codifícalo:

<!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 último, une todos estos elementos en una ruta:

routes/web.php

Route::get('/messages', [MessagesController::class, 'index']);

Escribir un componente Livewire

Es hora de introducir algo de funcionalidad. En lugar del enfoque tradicional de Modelo-Vista-Controlador, esta aplicación se basará en la funcionalidad dentro de un componente Livewire. Para desarrolladores PHP, componentes Livewire se verán como un controlador regular con su propio modelo de vista emparejado, pero los cambios de estado serán empujados al frontend. Crea un controlador Livewire en la línea de comandos:

php artisan livewire:make RcsComponent

Este componente Livewire se incluirá en la vista message vista. Este componente cargará todos los mensajes de la conversación sembrada, y luego hace dos cosas:

  • La opción de enviar un mensaje, que se enviará a Vonage utilizando el SDK DE PHP. El envío de este mensaje recarga el componente volviendo a obtener los mensajes mediante el método ORMy Livewire enviará el estado actualizado a Vonage.

  • Escuchará los cambios que se produzcan en la conversación sembrada y los cargará cuando un controlador reciba un webhook de Vonage

Escribir la plantilla de componentes

Las plantillas Livewire se encuentran en un directorio diferente al de las plantillas normales. Blade normales. Vaya a la plantilla del nuevo componente e introduzca algunos 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>

Esto crea un panel de mensajes al estilo "WhatsApp". El componente toma cualquier colección que haya sido incluida como $messagese incluye la sintaxis para volver a llamar al código PHP en el componente Livewire para enviar un mensaje, utilizando el método sendMessage(). Aún no hemos codificado eso, así que dirígete a la lógica del componente Livewire y codifica lo siguiente:

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();
   }
}

Hay mucho que desentrañar aquí, así que repasemos la lógica:

  • La propiedad class $postMessage actúa como estado del componente. Este estado es el mensaje actual que se está manejando, y si nos fijamos en la plantilla para el componente, se puede ver que hay una sintaxis que une el frontend y el backend: wire:model.defer="postMessage"

  • La propiedad de clase $messages también actúa como estado para el componente, y es la colección completa de mensajes adjuntos a la conversación. Esta propiedad se muestra en la plantilla que hemos creado anteriormente for $messages as $message)

  • Aquí hay tres métodos mágicos específicos de Livewire: mount() se ejecuta cuando el componente se renderiza por primera vez, refresh() se ejecuta cuando se produce cualquier cambio de estado, y render() se ejecuta al final del ciclo de vida del componente, de ahí el código para extraer la plantilla.

  • mount() llama a un método que se reutiliza en render() que se llama loadMessages()

  • loadMessages() utiliza el ORM de Eloquent para hacer dos cosas. En primer lugar, hemos hecho un poco de trampa con la recuperación de un archivo Conversationya que utiliza una variable de entorno, CONVERSATION_IDque es nuestra semilla Conversation. Todos los mensajes asociados a ese ID se recuperan y se escriben en la propiedad $messages propiedad.

No hemos añadido la variable de entorno, así que dirígete a tu .env y añádele CONVERSATION_ID=e2efbc00-b65e-4e47-8996-1de0043ed667 a la misma. Ese ID es el mismo UUID que se escribió en la conversación ficticia sembrada.

Es una buena práctica, ya que estamos escribiendo un simulacro de API esencialmente con el funcionamiento de estas entidades, para exponer sus entidades a través de REST. Notarás que el método sendMessage no utiliza el ORM de Eloquent para crear un nuevo mensaje y guardarlo en la base de datos, sino que toma el contenido de $postMessage y lo envía por POST al punto final de la API interna expuesta. Esto requiere un punto final que aún no se ha codificado, así que dirígete a tu archivo de rutas y añádelo:

routes\web.php

Route::post('/create-message', [MessagesController::class, 'store'])->name(messages.store');

Ahora, añade el método store() al método 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);
}

La entrada es validada, entonces, en esta lógica, la Message base de datos persiste la entidad y se adjunta a la entidad Conversation ficticia.

Integración de Livewire

Livewire necesita que se añadan algunos estilos y JavaScript a las plantillas de sus aplicaciones para funcionar. Hay algunos métodos de ayuda incluidos que pueden ser utilizados en Blade. Dirígete a la página de la plantilla padre del componente, y cambia el código por el siguiente:

<!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>

Las tres adiciones aquí son:

  • @livewireStyles para introducir clases CSS esenciales

  • @livewireScripts para incorporar funciones esenciales de JavaScript

  • <livewire:rcs /> añade nuestro componente Livewire a la página.

Escribir el controlador Webhook

Lo siguiente que debe hacer la aplicación es manejar los datos entrantes de Vonage en forma de webhook. Este webhook se configura en el panel de Vonage para que se dispare en una URL definida por el usuario como una carga útil JSON cuando un usuario responda al número configurado en la conversación en el dispositivo del usuario final. HTTP POST. Primero, agrega la ruta:

routes\web.php

Route::post('/messages/webhook', [MessagesController::class, 'webhook'])->name(messages.webhook');

Ahora, añadimos el método webhook() al método 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, escribí esta lógica para reutilizar la API REST, pero había implicaciones de seguridad al tomar dos dominios diferentes en tiempo de ejecución, por lo que he hecho trampa en este ejemplo y he utilizado Eloquent para escribir el mensaje webhook en la base de datos y devolver un 200 a Vonage.

Ahora tenemos todas las partes internas conectadas, pero probablemente no se te haya escapado que aún no estamos enviando nada a Vonage. enviando nada a Vonage todavía. Esto tiene que ocurrir en tu método sendMessage que se encuentra en el componente Livewire. El SDK PHP de Vonage requiere un ID de aplicación y un private.key, que se crea en el Panel de Vonage, y es necesario asignar un número a la aplicación.

  • Para crear una aplicación, vaya a la sección Crear una aplicación en el panel de Vonage y define un nombre para tu aplicación.

  • Si tiene intención de utilizar una API que utilice Webhooks, necesitará una clave privada. Haga clic en "Generar clave pública y privada"; la descarga debería iniciarse automáticamente. Guárdela de forma segura; esta clave no puede volver a descargarse si se pierde. Seguirá la convención de nomenclatura private_<id de su aplicación>.key. Esta clave puede utilizarse ahora para autenticar llamadas a la API. Nota: La clave no funcionará hasta que se guarde la aplicación.

  • Elija las funciones que necesite (por ejemplo, Voice, Messages, RTC, etc.) y proporcione los webhooks necesarios (por ejemplo, URL de eventos, URL de respuestas o URL de mensajes entrantes). Estos se describirán en el tutorial.

  • Para guardar e implementar, haz clic en "Generar nueva aplicación" para finalizar la configuración. Tu aplicación ahora está lista para usar con las API de Vonage.

RCS requiere registrarse como agente antes de poder utilizarlo. Para obtener información sobre cómo hacerlo consulte este artículo.

Tu aplicación deberá estar expuesta a Internet para que Vonage pueda enviarle webhooks. Haremos esto usando ngrok. Con ngrok instalado, ejecútalo en la línea de comandos:

ngrok http 8080

Obtendrás una URL pública que apunta a tu puerto 8080. Esta URL debe colocarse en el panel de Vonage para tu aplicación RCS, de esta manera:

Screenshot showing the Vonage Application dashboard where webhook fields are configuredConfiguring our webhooks

Configurar Vonage en PHP

El sendMessage() actualmente no envía un mensaje, así que es hora de configurarlo. Instala el SDK PHP de Vonage usando Composer en la línea de comandos:

composer require vonage/client

Ahora, con las credenciales de nuestra Account de Vonage y el archivo private.key descargado del Panel, configuramos nuestro objeto Cliente y lo utilizamos para enviar el mensaje RCS. Tu sendMessage() debería verse así:

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();
}

El sitio Client se crea con un Keypairque lo configura para manejar automáticamente la autenticación JWT para cualquier llamada de Vonage. Luego llama a la Messages API con el método encadenado messages() y utiliza el método send(). Este método, como parte de la integración de Messages API, tomará cualquier objeto válido que se ajuste internamente a las interfaces de mensajes. El objeto para enviar un mensaje RCS es RcsText.

Hay un par de variables de entorno para conectar aquí - ya hemos visto sus credenciales, pero RCS también requiere los números "to" y "from". El número "to" es su dispositivo de destino, y el "from" es la clave que está configurada con su agente RCS.

Es hora de la magia. La limitación aquí es que con Livewire, el componente se actualizará cuando usted envíe un mensaje (ya que utiliza el método refresh(), que entonces llamará a loadMessages() PERO, ¿cómo sabe el componente Livewire acerca de un webhook entrante, que debería entonces actualizar el estado?

La respuesta viene en forma del superbrillante Transmisión de modelos superbrillante. Traducido al español, Laravel le da la capacidad de aprovechar el sistema de eventos existente cada vez que se cambia un modelo. Esto significa que cada vez que un Message (es decir, cuando un webhook entra y se escribe en la base de datos), podemos utilizar un servidor WebSocket para escuchar y decirle a Livewire que refresh().

Hay dos bibliotecas que necesitamos instalar para hacer esto: Laravel Reverb (el servidor de transmisión websocket) y Laravel Echo (librería del lado del cliente para escuchar eventos). Reverb se instala utilizando la consola de Laravel:

php artisan install:broadcasting

Echo se instala usando npm:

npm install --save-dev laravel-echo pusher-js

pusher-js es el protocolo que utiliza Echo bajo el capó, de ahí que se incluya en el comando.

Integración de Echo

La raíz de JavaScript de tu aplicación necesita tener una clase configurada Echo lista para escuchar las emisiones de Reverb. Dirígete a resources\js y crea un nuevo archivo llamado echo.js. Poblarlo de la siguiente manera:

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;

Aquí se identifica un canal para escuchar: App.Models.Conversation.1 está codificado. Como sólo tenemos un objeto Conversation en este caso, siempre será éste. La convención de nomenclatura del canal ha venido de nuestra channel.php que aún no ha sido escrito, lo que sucederá en breve, pero es interesante notar que .MessageCreated es una convención de nomenclatura de Laravel incorporado en el modelo de difusión.

echo.private se utiliza porque los eventos de Difusión de Modelos sólo pueden ser emitidos desde canales privados. Una cosa a la que realmente hay que prestar atención (y yo no lo hice originalmente, lo que supuso unas fantásticas 2 horas de depuración de nada) es que sólo pueden ser canales privados porque Model Broadcasting está ligado al mecanismo de autenticación de Laravel. Por lo tanto, para que esto funcione, usted tendrá que estar conectado como el usuario sembrado que hemos creado.

La página echo.js debe incluirse en el punto de arranque de la aplicación, así que inclúyalo en el archivo resources\js\app.js archivo:

/**
* 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';

Integración de la reverberación

Tenemos algo que escucha los eventos, pero aún no hemos codificado su emisión. Hay tres partes en esto:

  • Configurar la ruta del canal de difusión

  • Añadir la emisión al modelo

  • Configurar Livewire para que reaccione a los eventos que surjan

Configuración del canal de difusión

Al instalar Reverb, el nuevo archivo de rutas para los canales se crea como routes\channels.php. Aquí es donde le decimos a Reverb que emita.

channels.php

Broadcast::channel('App.Models.Conversation.{id}', function ($user, $id) {
   return $user->conversations->firstOrFail('id', $id)->exists;
});

El método channel espera un booleano para identificar si el ID de la conversación está disponible para el usuario como puerta de autenticación.

Añadir la difusión al modelo

Hay dos cosas que tendrá que añadir al modelo - el modelo en este caso es la Message entidad. Reverb tiene un trait llamado BroadcastEvents que abre la interfaz para el uso de WebSocket. Tendrás que incluir esto en el código, lo que abre el método broadcastOn para sobrecargarlo.

El código del modelo final tiene este aspecto:

<?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 entrar en la lógica broadcastOn()observará que se han incluido varios campos en el campo $fillable. Esta propiedad especifica qué campos del modelo pueden ser autopoblados con hidratación, por lo que esos campos han sido incluidos en el array debido a la hidratación Webhook.

Debido a la difusión de modelos, la dirección del canal incorporado de este modelo sería App.Model.Conversationpor lo que devolver un valor de $this->conversation resulta en nuestro identificador de cadena de difusión requerido de App.Model.Conversation.{id}. BroadcastEvents emite las acciones CRUD en este modelo, pero le hemos ordenado que emita en el identificador de conversación para escuchar.

Unirlo todo

OK, lo admito: hemos pasado por una extraordinaria cantidad de lógica para simplemente no JavaScript. Pero, mira, estoy bien con eso porque soy el desarrollador más bueno del mundo. Además, ya sabes, me encanta la innovación que frameworks como Laravel siguen empujando.

Ahora tienes que ejecutar dos servidores: Vite necesita ejecutarse para compilar los activos del frontend, y Reverb necesita ejecutarse para transmitir los eventos que Echo escucha. En tu terminal, ejecútalos:

php artisan reverb:start
npm run dev

¡Uf! Eso es un montón de cableado. Pero merece la pena, ¿verdad? Con todo arrancado, ¡conéctate y empieza a enviar mensajes!

Screenshot showing our complete messenger with some example messagesI absolutely did not use ChatGPT to sort out my styling

¿Tienes alguna pregunta o algo que compartir? Únete a la conversación en Slack de la comunidad de Vonagey mantente actualizado con el Boletín para desarrolladoressíguenos en X (antes Twitter)suscríbete a nuestro canal de YouTube para ver tutoriales en video, y sigue la página de página para desarrolladores de Vonage en LinkedInun espacio para que los desarrolladores aprendan y se conecten con la comunidad. Mantente conectado, comparte tu progreso y entérate de las últimas noticias, consejos y eventos para desarrolladores.

Compartir:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondePromotor senior de desarrollo PHP

Actor de formación con una disertación sobre la comedia, llegué al desarrollo de PHP a través de la escena de las reuniones. Puedes encontrarme hablando y escribiendo sobre tecnología, o tocando/comprando discos raros de mi colección de vinilos.