IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Requeriments

Llegiu abans:

Laravel_Broadcasting_Events#Redis

I entengueu el patró Pub/Sub per entendre la relació entre la vostra aplicació de backend Laravel, laravel-echo-server i l'aplicació de frontend (laravel-echo)

Laravel echo server utilitza:

  • Laravel
  • Redis
  • Si cal persistència (presence channels) es pot utilitzar Redis mateix però també suporta MySQL

Introducció

És una api javascript escrita pel creador de Laravel (Taylor Otwell) per a facilitar el treball amb esdeveniments de broadcast a la part de front-end/Javascript.

Esta pensat per treballar amb els esdeveniments de broadcast de Laravel. Vegeu abans doncs l'article Laravel Broadcasting Events. Com la part del servidor tenim dos opcions/drivers suportats:

  • Pusher: cal utilitzar pusher (servei de pagament que inicialment té un compte free amb límit d'ús). L'avantatge és que no cal tenir infraestructura pròpia.
  • Redis: realment no és una implementació completa sinó que s'utilitza redis com a sistema de persistència ("base de dades"). S'utilitza Redis per que s'adapta molt bé al suportar el patróPub/Sub. En aquest cas cal tenir infraestructura pròpia i implementar un servidor d'esdeveniments (típicament s'utilitza node.js/socket.io però es pot implementar amb qualsevol altre solució de backend). Existeix una implementació de servidor per a laravel que és de la comunitat (no de Laravel) anomenada laravel-echo-server [1]]:

Intro

In many modern web applications, WebSockets are used to implement realtime, live-updating user interfaces. When some data is updated on the server, a message is typically sent over a WebSocket connection to be handled by the client. This provides a more robust, efficient alternative to continually polling your application for changes.

To assist you in building these types of applications, Laravel makes it easy to "broadcast" your events over a WebSocket connection. Broadcasting your Laravel events allows you to share the same event names between your server-side code and your client-side JavaScript application.

Laravel Echo is a JavaScript library that makes it painless to subscribe to channels and listen for events broadcast by Laravel. You may install Echo via the NPM package manager.

Instal·lació

Utilitzeu npm:

$ npm install --save laravel-echo

Resources:

Laravel echo server

Socket.io server for Laravel Echo. Driver alternatiu (a Pusher) per tal de fer Broadcast Events amb Laravel

Instal·lació

La podeu fer local o global:

$ npm install -g laravel-echo-server

Configuració

La configuració es guarda a un fitxer json que anomenem laravel-echo-server.json. Per crear aquest fitxer executeu:

$ laravel-echo-server init
Do you want to run this server in development mode? Yes
Which port would you like to serve from? 6001
Which database would you like to use to store presence channel members? redis
Enter the host of your Laravel authentication server. http://localhost
Will you be serving on http or https? http
Do you want to generate a client ID/Key for HTTP API? No 
Configuration file saved. Run laravel-echo-server start to run server.

Segons l'exemple el fitxer de configuració quedarà:

cat laravel-echo-server.json 
{
	"authHost": "http://localhost",
	"authEndpoint": "/broadcasting/auth",
	"clients": [],
	"database": "redis",
	"databaseConfig": {
		"redis": {},
		"sqlite": {
			"databasePath": "/database/laravel-echo-server.sqlite"
		}
	},
	"devMode": false,
	"host": null,
	"port": "6001",
	"protocol": "http",
	"socketio": {},
	"sslCertPath": "",
	"sslKeyPath": ""
}

Més info sobre les opcions de configuració a Github:

https://github.com/tlaverdure/laravel-echo-server/blob/master/README.md#configurable-options

Execució

El servidor s'executa amb la comanda:

$ laravel-echo-server start 
L A R A V E L  E C H O  S E R V E R

version 1.2.7

⚠ Starting server in DEV mode...

✔  Running at localhost on port 6001
✔  Channels are ready.
✔  Listening for http events...
✔  Listening for redis events...

Server ready!

Comproveu abans que el port s'activa amb:

$ sudo nmap localhost -p 6000
Starting Nmap 6.47 ( http://nmap.org ) at 2017-03-20 13:57 CET
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000051s latency).
Other addresses for localhost (not scanned): 127.0.0.1
PORT     STATE  SERVICE
6000/tcp closed X11

I després de l'execució.

$ nmap -p 6001 localhost
Starting Nmap 6.47 ( http://nmap.org ) at 2017-03-20 13:59 CET
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000051s latency).
Other addresses for localhost (not scanned): 127.0.0.1
PORT     STATE SERVICE
6001/tcp open  X11:1

API HTTP

Api que proporciona endpoints per accedir a la informació gestionada pel servidor laravel echo server.

Obtenir l'status del servidor:

GET /apps/:APP_ID/status

Obtenir els canals:

GET /apps/:APP_ID/channels

Informació d'un canal concret:

GET /apps/:APP_ID/channels/:CHANNEL_NAME

Llista d'usuaris a un canal:

GET /apps/:APP_ID/channels/:CHANNEL_NAME/users

Recursos:

Configuració dels clients

Els clients són necessaris per utilitzar la API HTTP que proporciona el servidor

Per crear una clau:

 $ laravel-echo-server client:add
API Client added!
appId: cba5d9824748e5ef
key: 668061c1c01bfb6e1c5b2c9038882060

Els clients es guarden al fitxer de configuració json laravel-echo-server.json:

cat laravel-echo-server.json
{
	"authHost": "http://localhost",
	"authEndpoint": "/broadcasting/auth",
	"clients": [
		{
			"appId": "cba5d9824748e5ef",
			"key": "668061c1c01bfb6e1c5b2c9038882060"
		}
	],
	"database": "redis",
	"databaseConfig": {
		"redis": {},
		"sqlite": {
			"databasePath": "/database/laravel-echo-server.sqlite"
		}
	},
	"devMode": true,
	"host": null,
	"port": "6001",
	"protocol": "http",
	"socketio": {},
	"sslCertPath": "",
	"sslKeyPath": ""
}

IMPORTANT: No podeu indicar el fitxer de configuració de qualsevol lloc amb

$ laravel-echo-server start 

Resources:

Configuració SSL/HTTPS

Cal crear un site temporal per tal de fer el challenge. Suposem per exemple que anem a utilitzar la URL i port:

laravel.echo.server.2dam.acacha.org:6001

Per publicar Laravel echo server. Necessitem crear un site per al port normal 80:

http://laravel.echo.server.2dam.acacha.org

Per tant per exemple amb nginx creem la carpeta pel projecte:

$ mkdir -p ~/Code/laravel.echo.server.2dam.acacha.org
$ cd ~/Code/laravel.echo.server.2dam.acacha.org
$ touch index.php
$ pwd
 /home/sergi/Code/laravel.echo.server.2dam.acacha.org

Poseu dins del fitxer index una pàgina HTML de prova o simplement un fitxer de text. Creem el fitxer de configuració de Nginx:

/etc/nginx/sites-available/laravel.echo.server.2dam.acacha.org

Amb el contingut:

server {
    listen 80;
    server_name laravel.echo.server.2dam.acacha.org;
    root "/home/sergi/Code/laravel.echo.server.2dam.acacha.org";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/laravel.echo.server.2dam.acacha.org-error.log error;

    sendfile off;

    client_max_body_size 100m;

    location ~ /\.ht {
        deny all;
    }
}

Feu el link:

$  sudo ln -s /etc/nginx/sites-available/laravel.echo.server.2dam.acacha.org /etc/nginx/sites-enabled/laravel.echo.server.2dam.acacha.org 

I reiniciu nginx:

$ sudo /etc/init.d/nginx restart 

Comproveu que la URL va bé al navegador:

laravel.echo.server.2dam.acacha.org

I creeu el certificat:

$ sudo letsencrypt certonly --webroot -w /home/sergi/Code/laravel.echo.server.2dam.acacha.org -d  laravel.echo.server.2dam.acacha.org

Ara teniu a la carpeta:

$ /etc/letsencrypt/live/laravel.echo.server.2dam.acacha.org

Els certificats SSL. Poseu aquests links al fitxer de configuració laravel-echo-server.json de laravel echo server:

       "protocol": "https"
       "sslCertPath": "/etc/letsencrypt/live/laravel.echo.server.2dam.acacha.org/fullchain.pem",
       "sslKeyPath": "/etc/letsencrypt/live/laravel.echo.server.2dam.acacha.org/privkey.pem"

En el meu cas el fitxer de configuració le creat a la carpeta:

/home/sergi/laravel-echo-server-https

I el contingut complet és:

{
	"authHost": "http://localhost",
	"authEndpoint": "/broadcasting/auth",
	"clients": [],
	"database": "redis",
	"databaseConfig": {
		"redis": {},
		"sqlite": {
			"databasePath": "/database/laravel-echo-server.sqlite"
		}
	},
	"devMode": false,
	"host": null,
	"port": "6002",
	"protocol": "https",
	"socketio": {},
	"sslCertPath": "/etc/letsencrypt/live/laravel.echo.server.2dam.acacha.org/fullchain.pem",
	"sslKeyPath": "/etc/letsencrypt/live/laravel.echo.server.2dam.acacha.org/privkey.pem"
}

I la configuració de supervisor:

$ cat /etc/supervisor/conf.d/laravel-echo-server-https.conf
[program:laravel-echo-server-https]
directory=/home/sergi/laravel-echo-server-https
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/laravel-echo-server start
autostart=true
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/home/sergi/laravel-echo-server-https.log

I feu:

$ sudo /etc/init.d/supervisor restart 

i comproveu que s'està executant:

$ ps aux | grep laravel-echo

Laravel echo with laravel-echo-server

Socket.IO If you are going to pair the Redis broadcaster with a Socket.IO server, you will need to include the Socket.IO JavaScript client library in your application. You may install it via the NPM package manager:

npm install --save socket.io-client Next, you will need to instantiate Echo with the socket.io connector and a host.

import Echo from "laravel-echo"

window.io = require('socket.io-client');

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});


Resources:


Supervisor

Exemple de configuració:

[program:laravel-echo-server]
directory=/home/sergi/laravel-echo-server
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/laravel-echo-server start
autostart=true
autorestart=true
user=sergi
redirect_stderr=true
stdout_logfile=/home/sergi/laravel-echo-server.log

Un exemple més concret:

cat /etc/supervisor/conf.d/laravel_echo_server.conf
[program:echo-server]
directory=/home/sergi/Code/laravel-echo-server
command=/home/sergi/node-v6.10.2-linux-x64/bin/laravel-echo-server start
autostart=true
autorestart=true
user=sergi
redirect_stderr=true
stdout_logfile=/home/sergi/Code/laravel-echo-server/echoserver.log

Com podeu veure amb un servidor laravel-echo server per màquina és suficient. A més no cal tenir un projecte Laravel complet simplement un carpeta amb el fitxer Json:

$ pwd
/home/sergi/Code/laravel-echo-server
$  laravel-echo-server git:(master) ✗ ls -la
total 24
drwxrwxr-x   2 sergi sergi  4096 abr  4 11:51 .
drwxr-xr-x 346 sergi sergi 16384 abr  4 11:50 ..
-rw-rw-r--   1 sergi sergi   514 abr  4 11:51 laravel-echo-server.json

Exemple de configuració a Forge:

cat /etc/supervisor/conf.d/laravel_echo_server.conf
[program:echo-server]
directory=/home/forge/laravel-echo-server
command=/usr/bin/node /usr/bin/laravel-echo-server start
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/laravel-echo-server/echoserver.log

On la carpeta /home/forge/laravel-echo-server només té el fitxer:

 % cat /home/forge/laravel-echo-server/laravel-echo-server.json 
{
	"authHost": "https://registre.lanparty.iesebre.com",
	"authEndpoint": "/broadcasting/auth",
	"clients": [
		{
			"appId": "APPID",
			"key": "APPKEY"
		}
	],
	"database": "redis",
	"databaseConfig": {
		"redis": {},
		"sqlite": {
			"databasePath": "/database/laravel-echo-server.sqlite"
		}
	},
	"devMode": false,
	"host": null,
	"port": "6001",
	"protocol": "https",
	"socketio": {},
	"sslCertPath": "/etc/nginx/ssl/registre.lanparty.iesebre.com/304446/server.crt",
	"sslKeyPath": "/etc/nginx/ssl/registre.lanparty.iesebre.com/304446/server.key",
	"sslCertChainPath": "",
	"sslPassphrase": "",
	"apiOriginAllow": {
		"allowCors": false,
		"allowOrigin": "",
		"allowMethods": "",
		"allowHeaders": ""
	}
}%

Enrecordeu-vos d'obrir el port Forge a la configuració de firewall!!

Vegeu també

Enllaços externs