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

# Echtzeit-Stream

> Abonniere Live-Anwendungsevents über einen Server-Sent-Events-Stream (SSE).

`api.ApplicationRealtime(appID)` öffnet einen [Server-Sent-Events](https://developer.mozilla.org/docs/Web/API/Server-sent_events)-Stream und gibt einen `*rest.RealtimeStream` zurück. Iteriere ihn mit `stream.Next()` bis `io.EOF`.

```go theme={null}
client := rest.NewClient(os.Getenv("SQUARECLOUD_API_KEY"))
defer client.Close()

api := rest.New(client)
```

## Den Stream konsumieren

```go theme={null}
stream, err := api.ApplicationRealtime("abc123def456abc123def456")
if err != nil {
	panic(err)
}
defer stream.Close()

for {
	event, err := stream.Next()
	if err == io.EOF {
		break // stream ended (e.g. 10-minute TTL reached)
	}
	if err != nil {
		panic(err)
	}

	fmt.Println(event.Name, string(event.Data))
}
```

Rufe stets `defer stream.Close()` auf — ein nicht geschlossener Stream hält einen der Verbindungs-Slots deines Kontos belegt.

## Event-Aufbau

Der Stream emittiert zwei Arten von Frames:

* **System-Events** — Nachrichten zum Verbindungslebenszyklus: `REALTIME_CONNECTING`, `REALTIME_TIMEOUT`, `REALTIME_DISCONNECTED`, `REALTIME_RECONNECT` und `REALTIME_ERROR`.
* **`message`-Events** — das Anwendungs-Payload. `Data` ist für das SDK opak, üblicherweise JSON — unmarshale es selbst:

```go theme={null}
if event.Name == "message" {
	var payload map[string]any
	if err := json.Unmarshal(event.Data, &payload); err == nil {
		fmt.Println(payload)
	}
}
```

## Verbindungslimits

<Warning>
  Ein einzelnes Konto kann höchstens **5 gleichzeitige Verbindungen** offen halten und jede Verbindung dauert bis zu **10 Minuten** (ihre TTL). Ist die TTL erreicht, endet der Stream mit `io.EOF` — verbinde dich in einer Schleife neu, um abonniert zu bleiben.
</Warning>

```go theme={null}
for {
	stream, err := api.ApplicationRealtime("abc123def456abc123def456")
	if err != nil {
		panic(err)
	}

	for {
		event, err := stream.Next()
		if err != nil {
			break // io.EOF on TTL — reconnect
		}
		fmt.Println(event.Name, string(event.Data))
	}

	stream.Close()
}
```

## Abbruch

Hänge einen `context.Context` mit `rest.WithContext` an, um den Stream von außen zu stoppen:

```go theme={null}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

stream, err := api.ApplicationRealtime("abc123def456abc123def456", rest.WithContext(ctx))
if err != nil {
	panic(err)
}
defer stream.Close()

// cancel() from another goroutine ends the stream
```
