010 - StudioLink
StudioLink ist das Echtzeit-Kommunikationssystem über Sockets.
Die Idee
Du arbeitest an einem Artwork, schraubst an den Tweakpane-Einstellungen – und all diese Änderungen erscheinen live im Art.Works! Studio. Du siehst Parameter-Werte, kannst Snapshots auslösen, die Animation steuern. Alles in Echtzeit, ohne Reload.
StudioLink macht das möglich. Es ist ein bidirektionaler Kanal zwischen Artworks und Studio, basierend auf Sockets.
Kernfunktionen:
- Parameter-Synchronisation – Tweakpane-Werte live ins Studio und zurück
- Artwork-State – Welche Agents sind aktiv? Wie sieht der SceneGraph aus?
- Snapshots on Demand – Studio fragt, Artwork liefert Screenshot
- Logging – Console.log landet im Studio statt in Browser-DevTools
Erweiterte Visionen (in Entwicklung):
- Artworks kommunizieren miteinander (Shape verlässt rechts Artwork A, erscheint links in Artwork B)
- Externe Datenquellen (Wetter-APIs, Sensoren) in Artworks einspeisen
- Roboter/Plotter über StudioLink steuern
Architektur
┌─────────────────────────────────────────┐
│ Studio (Electron) │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Socket │ │ Studio Renderer │ │
│ │ Server │ │ │ │
│ │ Port 3090 │ └────────┬────────┘ │
│ └──────┬──────┘ │ │
│ │ ┌─────────────┘ │
│ │ │ ┌──────────────────┐ │
│ │ │ │ Studio Backend │ │
│ │ │ └────────┬─────────┘ │
└─────────┼────┼────────────┼─────────────┘
│ │ │
┌─────┴────┴────────────┴─────┐
│ │
┌───┴───┐ ┌─────────┐ ┌───────┴───┐
│Artwork│ │ Artwork │ │ Artwork │
│ 1 │ │ 2 │ │ 3 │
│webview│ │ webview │ │ Browser │
└───────┘ └─────────┘ └───────────┘Komponenten
| Klasse | Datei | Funktion |
|---|---|---|
StudioSocketAPI |
StudioSocketAPI.ts |
Low-level Socket Wrapper |
StudioLinkManager |
StudioLinkManager.ts |
High-level Manager |
Room-Struktur
| Room | Beschreibung | Mitglieder |
|---|---|---|
studio |
Studio UI | Studio Renderer |
artwork:{id} |
Spezifisches Artwork | Artwork + Studio (Observer) |
backend |
Backend Services | Backend Process |
logs |
Zentraler Log-Channel | Alle |
Message Types
Logs
type LogMessage = {
type: 'log';
level: 'debug' | 'info' | 'warn' | 'error';
component: string;
message: string;
timestamp: string;
metadata?: any;
};Control Commands (Studio → Artwork)
| Type | Beschreibung |
|---|---|
request-parameter-dump |
Parameter anfordern |
apply-parameter |
Parameter ändern |
request-snapshot |
Screenshot anfordern |
control-animation |
Play/Pause/Reset |
Data Messages (Artwork → Studio)
| Type | Beschreibung |
|---|---|
parameter-dump |
Komplettes ParameterObject |
parameter-update |
Einzelne Änderung |
snapshot-data |
Canvas als Base64 |
artwork-state |
Agents, Scene-Struktur |
StudioSocketAPI
Low-level Socket Wrapper.
Konfiguration:
| Option | Typ | Default | Beschreibung |
|---|---|---|---|
serverUrl |
string |
'http://localhost:3090' | Server-URL |
artworkId |
string |
- | Artwork-Identifikation |
autoConnect |
boolean |
true | Auto-Verbinden? |
reconnection |
boolean |
true | Reconnect bei Abbruch? |
API:
| Methode | Beschreibung |
|---|---|
connect() |
Verbindung herstellen |
disconnect() |
Verbindung trennen |
emit(event, data) |
Event senden |
on(event, handler) |
Event-Handler registrieren |
joinRoom(room) |
Room beitreten |
leaveRoom(room) |
Room verlassen |
StudioLinkManager
High-level Manager mit Auto-Detect und Tweakpane-Support.
Features:
- Auto-Detect Server
- Parameter-Sync
- Tweakpane-Integration
- Auto-Send bei Änderungen
- Snapshot-Handling
Konfiguration:
| Option | Typ | Default | Beschreibung |
|---|---|---|---|
artworkId |
string |
- | Artwork-ID |
autoSync |
boolean |
true | Auto-Sync Parameter |
syncInterval |
number |
100 | Sync-Interval (ms) |
enableLogs |
boolean |
true | Logs an Server senden |
API:
| Methode | Beschreibung |
|---|---|
init(parameter) |
Initialisieren |
syncParameter() |
Manueller Sync |
sendSnapshot(canvas) |
Screenshot senden |
requestParameter() |
Parameter anfordern |
Datenfluss
Artwork StudioLink Socket Server Studio UI
│ │ │ │
│ Parameter │ │ │
│ changed │ │ │
│────────────────>│ │ │
│ │ parameter-update │ │
│ │─────────────────>│ │
│ │ │ broadcast to │
│ │ │ studio room │
│ │ │───────────────>│
│ │ │ │ Update
│ │ │ │ Inspector
│ │ │ │
│ │ │ apply-parameter│
│ │ │<───────────────│
│ │ to artwork:{id} │ │
│ │<─────────────────│ │
│ Update local │ │ │
│<────────────────│ │ │
│ │ │ │Auto-Detect
StudioLinkManager erkennt automatisch:
- URL-Parameter:
?studio=http://... - Localhost: Versucht
localhost:3090 - Electron: Erkennt webview-Kontext
Snapshot-System
Studio Server Artwork
│ │ │
│ request-snapshot │ │
│──────────────────>│ │
│ │ request-snapshot │
│ │──────────────────>│
│ │ │ canvas.toDataURL()
│ │ │
│ │ snapshot-data │
│ │<──────────────────│
│ snapshot-data │ (base64) │
│<──────────────────│ │
│ │ │
│ Display/Save │ │
│ │ │Erweiterte Visionen
Aktuell implementiert:
- Parameter-Synchronisation
- Snapshot-Übertragung
- Logging
Geplant:
- Artworks kommunizieren miteinander
- Shape verschwindet rechts → erscheint links im nächsten Frame
- Externe Datenquellen (Wetter, APIs)
- Roboter/Plotter-Steuerung
Der Socket Server
Der Server ist der zentrale Hub – er routet Messages zwischen allen Teilnehmern.
Wo läuft er?
| Kontext | Beschreibung |
|---|---|
| Im Studio | Art.Works! Studio hat einen integrierten Server (Port 3090) |
| Standalone | apps/node-collab-server für Tests ohne Studio |
| Docker | apps/node-collab-server-docker für Produktion |
Das Room-Konzept:
Socket "Rooms" gruppieren Verbindungen. Ein Artwork tritt dem Room artwork:001 bei. Das Studio tritt allen Artwork-Rooms als Observer bei. So kann das Studio alle Artworks überwachen, und Messages gezielt an einzelne Artworks senden.
┌─────────────────────────┐ ┌─────────────────────────┐
│ Room: artwork:001 │ │ Room: artwork:002 │
│ ┌───────────────────┐ │ │ ┌───────────────────┐ │
│ │ Artwork 001 │ │ │ │ Artwork 002 │ │
│ └───────────────────┘ │ │ └───────────────────┘ │
│ ┌───────────────────┐ │ │ ┌───────────────────┐ │
│ │ Studio (Observer) │ │ │ │ Studio (Observer) │ │
│ └───────────────────┘ │ │ └───────────────────┘ │
└─────────────────────────┘ └─────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Room: logs │
│ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ │
│ │ Artwork 001 │ │ Artwork 002 │ │ Studio │ │
│ └─────────────┘ └─────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────┘Server-Events:
| Event | Beschreibung |
|---|---|
connection |
Neuer Client verbunden |
disconnect |
Client getrennt |
join-room |
Client tritt Room bei |
leave-room |
Client verlässt Room |
message |
Message an Room weiterleiten |
Verwendung
// Im Artwork
import { StudioLinkManager } from '@carstennichte/cc-toolbox';
const studioLink = new StudioLinkManager({
artworkId: 'my-artwork-001',
autoSync: true
});
studioLink.init(parameter);