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:

  1. Parameter-Synchronisation – Tweakpane-Werte live ins Studio und zurück
  2. Artwork-State – Welche Agents sind aktiv? Wie sieht der SceneGraph aus?
  3. Snapshots on Demand – Studio fragt, Artwork liefert Screenshot
  4. 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:

  1. URL-Parameter: ?studio=http://...
  2. Localhost: Versucht localhost:3090
  3. 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);