Cómo usar Laravel con Socket.IO

Los Websockets son geniales. Son realmente útiles si desea mostrar actividades en tiempo real de sus usuarios (o quizás algunos trabajos en cola).

Ahora, si le tiene miedo a la palabra " Websockets ", no lo tenga. Daré las instrucciones sobre cómo puede usarlo y estaré disponible para responder sus preguntas si es necesario.

Tuve este desafío donde lo necesitaba para mostrar una lista de personas que actualmente están viendo una URL específica en Laravel . Entonces comencé a pensar. Una parte de mí quería hacer un truco rápido (afortunadamente, ese no es mi lado más fuerte). Mientras que el otro quería construir algo genial, reutilizable y duradero.

"¿Por qué no usas Pusher?"

Aquí está la cosa.

Laravel viene con Pusher habilitado. Aunque Pusher parece una solución rápida " Plug and play " (que lo es), tiene limitaciones. Visite //pusher.com/pricing

Y la mayoría de los tutoriales te engañan con su título de implementación de Websockets cuando en realidad solo quieren darte Pusher. (Y mi parte favorita es cuando dicen que puedes cambiar fácilmente a socket.io)

"Queremos tener un número ilimitado de conexiones"

No queremos preocuparnos por las limitaciones.

Empecemos.

Estoy usando vagrant / homestead.

Para ello, necesitaremos leer sobre la transmisión de eventos.

Cosas a tener en cuenta aquí (para no tener que repetir las cosas):

1. Interfaz ShouldBroadcast para eventos

2. Habilitación de rutas de transmisión y uso de rutas / canales.php para autenticar usuarios

3. Canal público: todos pueden escuchar

4. Canal privado: debes autorizar a los usuarios antes de que puedan unirse a un canal.

5. Canal de presencia: como Privado, pero puede pasar muchos metadatos adicionales en ese canal y obtener una lista de las personas que se han unido al método channel.broadcastOn () Event

Crea tu evento

php artisan make:event MessagePushed

Incluso puede seguir el ejemplo específico en la documentación de Event Broadcasting. (Que deberíamos realmente).

Instalar Redis

Antes de esto, en realidad tenía configuradas las colas con Supervisor / Redis / Horizon. Horizon es genial y puedes encontrar información sobre eso aquí //laravel.com/docs/5.6/horizon

Una vez que sus colas funcionen, ese evento MessagePushed necesitará usar colas.

Nota : Para que todo esto funcione, asegúrese de editar su archivo .env:

BROADCAST_DRIVER=redis
QUEUE_DRIVER=redis
(this is from the horizon setup actually, but we will need that for later)
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

Instalar Laravel Echo Server

Entonces, esta parte es en realidad donde instalamos el servidor socket.io que está incluido dentro de laravel-echo-server. Puede encontrarlo aquí: //github.com/tlaverdure/laravel-echo-server

Nota : ¡Consulta los requisitos en la parte superior!

Ejecute lo siguiente (como se indica en el documento)

npm install -g laravel-echo-server

Y luego ejecute el init para obtener su archivo laravel-echo-server.json generado en la raíz de la aplicación (que necesitaremos configurar).

laravel-echo-server init

Una vez que haya generado su archivo laravel-echo-server.json, debería verse así.

{
"authHost": "//local-website.app",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "my-app-id",
"key": "my-key-generated-with-init-command"
}
],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
},
"port": "6379",
"host": "127.0.0.1"
},
"devMode": false,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": ""
}

Nota : Si desea enviar esto a su servidor público, asegúrese de agregar laravel-echo-server.json a su .gitignore. G enerate este archivo en el servidor, de lo contrario tendrá que cambiar su authHost todo el tiempo.

Ejecute su Laravel Echo Server

Tienes que ejecutarlo para iniciar websockets.

laravel-echo-server start 

(dentro de su raíz, donde se coloca su laravel-echo-server.json)

Debería comenzar con éxito. (Ahora querremos agregar esto al supervisor en su servidor, para que se inicie automáticamente y se reinicie en caso de que falle)

Dentro de su /etc/supervisor/conf.d/laravel-echo.conf (simplemente cree este archivo dentro de su carpeta conf.d ) coloque lo siguiente:

[program:laravel-echo]
directory=/var/www/my-website-folder
process_name=%(program_name)s_%(process_num)02d
command=laravel-echo-server start
autostart=true
autorestart=true
user=your-linux-user
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/my-website-folder/storage/logs/echo.log

Una vez que se posiciona en su raíz de Laravel, puede ejecutar

pwd

para obtener la ruta de su 'directorio' arriba y el prefijo 'stdout_logfile'.

Su usuario será su usuario de Linux (vagabundo o Ubuntu o algún otro)

Guarde el archivo y salga.

Si usó vim laravel-echo.conf, cuando esté dentro, presione I (como Estambul) en su teclado para editar un archivo con VIM y luego escriba ESC siguiendo lo siguiente: wq! Para cerrar el archivo y guardarlo.

A continuación, debemos ejecutar los siguientes comandos:

sudo supervisorctl stop all sudo supervisorctl reread
sudo supervisorctl reload

Después de eso, verifique si laravel echo se está ejecutando

sudo supervisorctl status

Instalar el cliente Laravel Echo y Socket IO

npm install --save laravel-echo
npm install --save socket.io-client

Y luego en su bootstrap.js (estoy usando Vue js) registre su Echo

import Echo from "laravel-echo"window.io = require('socket.io-client');
// Have this in case you stop running your laravel echo server
if (typeof io !== 'undefined') { window.Echo = new Echo({ broadcaster: 'socket.io', host: window.location.hostname + ':6001', });}

Ahora compruebe de nuevo cómo escuchar sus eventos en canales específicos.

Siguiendo la documentación sobre Laravel Broadcasting que compartimos anteriormente, si configuras tu método broadcastOn () para devolver un nuevo PresenceChannel (explicaré el caso particular que hice, pero no dudes en hacer preguntas en caso de que necesites implementar algo más. Encuentro esto para ser de mayor complejidad que simplemente usar un canal público, por lo que podemos reducir la escala sin problemas), entonces queremos escuchar ese canal en el lado de Javascript (frontend).

Aquí hay un ejemplo concreto:

  1. Envié un evento a un canal de presencia (estaba tratando con encuestas)
public function broadcastOn()
{
return new PresenceChannel('survey.' . $this->survey->id);
}

2. Después de presionar el evento, pasará por channels.php. Allí queremos crear una autorización para este usuario. (Recuerde devolver una matriz para la autorización del canal de presencia y no un booleano).

Broadcast::channel('survey.{survey_id}', function ($user, $survey_id) {
return [
'id' => $user->id,
'image' => $user->image(),
'full_name' => $user->full_name
];
});

3. Luego, en mi componente VueJs que se carga en la página que quiero monitorear, defino un método que se iniciará desde el método created () al cargar:

listenForBroadcast(survey_id) {
Echo.join('survey.' + survey_id)
.here((users) => {
this.users_viewing = users;
this.$forceUpdate();
})
.joining((user) => {
if (this.checkIfUserAlreadyViewingSurvey(user)) {
this.users_viewing.push(user);
this.$forceUpdate();
}
})
.leaving((user) => {
this.removeViewingUser(user);
this.$forceUpdate();
});
},

Obviamente saqué algo de código fuera del contexto aquí, pero tengo esta matriz 'users_viewing' para mantener a mis usuarios actuales que se unieron al canal.

Y eso sería realmente.

Espero que hayas podido seguirme mientras traté de ser lo más detallado posible.

¡Feliz codificación!

Sigueme en Twitter

Agrégame en LinkedIn