> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket (Jetstream / Firehose)

> Funzionalità WebSocket di Laravel Bluesky. Come gestire eventi in tempo reale con Bluesky Jetstream e AT Protocol Firehose. Spiega l'uso di JetstreamServeCommand e FirehoseServeCommand.

## Panoramica

`laravel-bluesky` offre due comandi WebSocket per collegarsi agli stream in tempo reale di Bluesky.

* **Jetstream** — endpoint WebSocket con filtri, proprio di Bluesky. Leggero, in formato JSON.
* **Firehose** — stream grezzo di eventi di AT Protocol. Riceve tutti i dati in formato binario DAG-CBOR.

```mermaid theme={null}
graph LR
    subgraph "Rete Bluesky"
        J["Jetstream<br>jetstream1.us-west.bsky.network<br>JSON / con filtri"]
        F["Firehose<br>bsky.network<br>DAG-CBOR / tutti i dati"]
    end
    subgraph "App Laravel"
        WS["JetstreamServeCommand<br>FirehoseServeCommand<br>(Workerman)"]
        E["Laravel Events<br>JetstreamCommitMessage<br>FirehoseCommitMessage, ecc."]
        L["Listener / Job"]
    end

    J -->|WebSocket| WS
    F -->|WebSocket| WS
    WS --> E --> L
```

<Warning>
  I processi long-running via WebSocket richiedono **un server sempre attivo, come VPS o EC2**, oppure un **custom worker di Laravel Cloud**. Non funzionano in ambienti serverless come Laravel Vapor o Vercel.
</Warning>

## Installazione

Per le funzionalità WebSocket è necessario [Workerman](https://github.com/walkor/workerman).

```bash theme={null}
composer require workerman/workerman
```

## Jetstream

### Panoramica

Jetstream è il servizio WebSocket con filtraggio fornito da Bluesky. Puoi filtrare per tipo di collezione e DID utente, ricevendo solo gli eventi necessari in modo efficiente.

| Caratteristica | Descrizione                              |
| -------------- | ---------------------------------------- |
| Formato dati   | JSON                                     |
| Filtraggio     | Possibile per collezione e DID           |
| Volume dati    | Leggero a seconda del filtro             |
| Uso            | Monitoraggio di post, like, follow, ecc. |

### Come avviarlo

```bash theme={null}
# Ricevi tutti i messaggi (nessun filtro)
php artisan bluesky:ws start

# Debug: mostra tutti i messaggi ricevuti
php artisan bluesky:ws start -v
```

### Filtro per collezione

Con l'opzione `-C` restringi le collezioni ricevute. Puoi specificarne più di una.

```bash theme={null}
# Ricevi solo post e like
php artisan bluesky:ws start -C app.bsky.feed.post -C app.bsky.feed.like

# Ricevi solo i follow
php artisan bluesky:ws start -C app.bsky.graph.follow
```

Collezioni principali:

| Collezione              | Contenuto                      |
| ----------------------- | ------------------------------ |
| `app.bsky.feed.post`    | Creazione/eliminazione di post |
| `app.bsky.feed.like`    | Like                           |
| `app.bsky.feed.repost`  | Repost                         |
| `app.bsky.graph.follow` | Follow                         |
| `app.bsky.graph.block`  | Block                          |

### Filtro per DID

Con l'opzione `-D` ricevi solo gli eventi di utenti specifici.

```bash theme={null}
# Ricevi solo i post di determinati utenti
php artisan bluesky:ws start -C app.bsky.feed.post -D did:plc:xxx -D did:plc:yyy
```

### Gestione degli eventi

Il comando Jetstream emette eventi Laravel in base al tipo di messaggio ricevuto.

| Classe evento              | Quando                                                 |
| -------------------------- | ------------------------------------------------------ |
| `JetstreamMessageReceived` | A ogni messaggio ricevuto                              |
| `JetstreamCommitMessage`   | Alla creazione/aggiornamento/eliminazione di un record |
| `JetstreamIdentityMessage` | Su eventi di identity, come cambio handle              |
| `JetstreamAccountMessage`  | All'attivazione/disattivazione dell'account            |

Crea un listener per gestire gli eventi.

```bash theme={null}
php artisan make:listener JetstreamPostListener
```

```php theme={null}
namespace App\Listeners;

use Revolution\Bluesky\Events\Jetstream\JetstreamCommitMessage;

class JetstreamPostListener
{
    public function handle(JetstreamCommitMessage $event): void
    {
        // Verifica il tipo di collezione
        $collection = data_get($event->message, 'commit.collection');

        if ($collection !== 'app.bsky.feed.post') {
            return;
        }

        // Tipo di operazione: create / update / delete
        $operation = $event->operation;

        // DID dell'autore del post
        $did = $event->message['did'];

        // Contenuto del record
        $record = data_get($event->message, 'commit.record');
        $text = data_get($record, 'text', '');

        info("[$operation] $did: $text");
    }
}
```

## Firehose

### Panoramica

Firehose è lo stream grezzo di eventi di AT Protocol. Ricevi in formato binario (DAG-CBOR) tutte le operazioni sui record della rete Bluesky.

| Caratteristica | Descrizione                                                 |
| -------------- | ----------------------------------------------------------- |
| Formato dati   | Binario DAG-CBOR (il pacchetto lo decodifica in automatico) |
| Filtraggio     | Nessuno (ricevi tutti i dati)                               |
| Volume dati    | Molto elevato                                               |
| Uso            | Raccolta e archiviazione di tutti i dati                    |

<Info>
  La decodifica DAG-CBOR viene fatta automaticamente dal pacchetto. Negli event listener ricevi i dati come normali array PHP.
</Info>

### Come avviarlo

```bash theme={null}
php artisan bluesky:firehose start

# Debug: mostra i messaggi ricevuti
php artisan bluesky:firehose start -v
```

### Gestione degli eventi

Anche il comando Firehose gestisce i messaggi tramite eventi Laravel.

| Classe evento             | Quando                                                 |
| ------------------------- | ------------------------------------------------------ |
| `FirehoseMessageReceived` | A ogni messaggio ricevuto (dati grezzi inclusi)        |
| `FirehoseCommitMessage`   | Alla creazione/aggiornamento/eliminazione di un record |
| `FirehoseIdentityMessage` | Su eventi di identity                                  |
| `FirehoseAccountMessage`  | Su eventi di account                                   |
| `FirehoseSyncMessage`     | Su eventi di sincronizzazione del repository           |

```bash theme={null}
php artisan make:listener FirehosePostListener
```

```php theme={null}
namespace App\Listeners;

use Revolution\Bluesky\Events\Firehose\FirehoseCommitMessage;

class FirehosePostListener
{
    public function handle(FirehoseCommitMessage $event): void
    {
        // Verifica il tipo di collezione
        if ($event->collection !== 'app.bsky.feed.post') {
            return;
        }

        // Tipo di operazione: create / update / delete
        $action = $event->action;

        // DID dell'autore del post
        $did = $event->did;

        // Contenuto del record (array decodificato)
        $record = $event->record;
        $text = data_get($record, 'value.text', '');

        info("[$action] $did: $text");
    }
}
```

## Configurazione

In `config/bluesky.php` puoi modificare l'host di connessione e le impostazioni di logging.

```php theme={null}
// Jetstream
'jetstream' => [
    'host' => env('BLUESKY_JETSTREAM_HOST', 'jetstream1.us-west.bsky.network'),
    'max' => env('BLUESKY_JETSTREAM_MAX', 0), // maxMessageSizeBytes (0 = senza limite)
    'logging' => [
        'driver' => env('BLUESKY_JETSTREAM_LOG_DRIVER', 'daily'),
        'days' => 7,
        'path' => env('BLUESKY_JETSTREAM_LOG_PATH', storage_path('logs/jetstream.log')),
    ],
],

// Firehose
'firehose' => [
    'host' => env('BLUESKY_FIREHOSE_HOST', 'bsky.network'),
    'logging' => [
        'driver' => env('BLUESKY_FIREHOSE_LOG_DRIVER', 'daily'),
        'days' => 7,
        'path' => env('BLUESKY_FIREHOSE_LOG_PATH', storage_path('logs/firehose.log')),
    ],
],
```

Esempio di configurazione in `.env`:

```ini theme={null}
BLUESKY_JETSTREAM_HOST=jetstream2.us-east.bsky.network
BLUESKY_JETSTREAM_MAX=1000000
```

## Combinazione con Labeler

Puoi avviare contemporaneamente il server Labeler e Jetstream / Firehose. Puoi usare i dati di Jetstream o Firehose per gestire le richieste di labeling ricevute dal Labeler.

```bash theme={null}
# Labeler + Jetstream (monitora gli eventi follow)
php artisan bluesky:labeler:server start --jetstream -C app.bsky.graph.follow

# Labeler + Firehose (ricevi tutti i dati)
php artisan bluesky:labeler:server start --firehose
```

<Info>
  Per i dettagli su Labeler consulta la [pagina Labeler](/it/packages/laravel-bluesky/labeler).
</Info>

## Gestione dei processi long-running

I comandi WebSocket sono processi che restano attivi a lungo. In produzione usa uno strumento di gestione dei processi come Supervisor.

### Esempio di configurazione Supervisor

`/etc/supervisor/conf.d/bluesky-jetstream.conf`:

```ini theme={null}
[program:bluesky-jetstream]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan bluesky:ws start -C app.bsky.feed.post
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/jetstream-worker.log
stopwaitsecs=3600
```

```bash theme={null}
# Ricarica Supervisor e avvia
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start bluesky-jetstream:*
```

### Configurazione del daemon su Laravel Forge

Se usi Laravel Forge, aggiungi il daemon dalla sezione **Daemons**.

* **Command**: `php artisan bluesky:ws start -C app.bsky.feed.post`
* **Directory**: `/var/www/html`
* **User**: `forge`

### Configurazione dei processi in background su Laravel Cloud

I comandi WebSocket si connettono allo stream di Bluesky come **client WebSocket**, quindi funzionano anche su Laravel Cloud. Configurali come processi in background (custom worker) di Laravel Cloud.

Nelle impostazioni dei processi in background di Laravel Cloud, aggiungi un **Custom Worker**.

**Per Jetstream:**

```bash theme={null}
php artisan bluesky:ws start
```

**Per Firehose:**

```bash theme={null}
php artisan bluesky:firehose start
```

<Info>
  L'arresto e il riavvio del processo al deploy sono gestiti automaticamente da Laravel Cloud. A parte la configurazione del processo in background non serve nient'altro.
</Info>

### Attenzione

* Se il processo termina inaspettatamente, con `autorestart=true` si riavvia automaticamente.
* Per evitare memory leak, valuta riavvii periodici.
* Con Firehose, che riceve grandi quantità di messaggi, si consiglia di eseguire il lavoro nel listener in modo asincrono (Queue Job).

```php theme={null}
// Esempio di dispatch verso un Queue Job dal listener

namespace App\Listeners;

use App\Jobs\ProcessFirehosePost;
use Revolution\Bluesky\Events\Firehose\FirehoseCommitMessage;

class FirehosePostListener
{
    public function handle(FirehoseCommitMessage $event): void
    {
        if ($event->collection !== 'app.bsky.feed.post') {
            return;
        }

        // Delega l'elaborazione pesante a un Queue Job
        ProcessFirehosePost::dispatch($event->did, $event->record, $event->action);
    }
}
```

<Info>
  Source: [src/Console/WebSocket](https://github.com/invokable/laravel-bluesky/tree/main/src/Console/WebSocket)
</Info>


## Related topics

- [Laravel Cloud — la panoramica completa del PaaS dedicato a Laravel](/it/blog/laravel-cloud.md)
- [Streaming](/it/packages/laravel-copilot-sdk/streaming.md)
- [Laravel Reverb](/it/reverb.md)
- [Laravel Nostr](/it/packages/laravel-nostr.md)
- [Laravel Notification for Discord (Webhook)](/it/packages/laravel-notification-discord-webhook.md)
