Zum Inhalt

Custom Server Trigger — Browser sendet an SB

Browser-Overlay (oder beliebige App) sendet Nachrichten an SB → SB-Action wird getriggert mit dem Message-Inhalt als Variable.

Trigger: Core → WebSocket → Custom Server Sub-Triggers: Connection Opened / Connection Closed / Message

Connection Opened Trigger

Feuert wenn ein Client (Browser) sich verbindet.

Variable Inhalt
%clientId% Eindeutige ID des Clients (Session-GUID)
%clientAddress% IP-Adresse

Use-Case: Welcome-State an Browser senden wenn Overlay geladen wurde.

Connection Closed Trigger

Feuert wenn Client disconnected.

Variable Inhalt
%clientId% Welcher Client

Use-Case: Cleanup-State, "Browser ist offline".

Message Trigger

Feuert wenn Client eine Nachricht an SB sendet.

Variable Inhalt
%clientId% Wer hat geschickt
%data% Message-Inhalt (String, oft JSON)

Use-Case A: Browser-Button → SB-Action

In einem HTML-Overlay ein Button der bei Click an SB sendet:

Browser-HTML

<button id="brbBtn">BRB Modus an</button>
<script>
const ws = new WebSocket('ws://localhost:8080/');
ws.onopen = () => console.log('connected');

document.getElementById('brbBtn').onclick = () => {
  ws.send(JSON.stringify({
    type: 'command',
    command: 'brb-toggle'
  }));
};
</script>

SB-Action

[Event] Browser Message
Trigger: Core → WebSocket → Custom Server → Message
├── 1. If/Else: %data% Contains "brb-toggle"
│   ├── OBS Set Active Scene: BRB
│   └── Break
└── 2. (weitere Message-Typen handeln)

So baust du Custom-Web-Interfaces als Controll-Panel für SB.

Use-Case B: Browser-Game schickt Score an SB

Ein Browser-basiertes Game speichert High-Scores in SB:

Browser

function gameOver(finalScore) {
  ws.send(JSON.stringify({
    type: 'score',
    user: 'PlayerName',
    score: finalScore
  }));
}

SB

[Event] Game Score
Trigger: Core → WebSocket → Custom Server → Message
├── 1. If/Else: %data% Contains "\"type\":\"score\""
│   ├── (Parse JSON aus %data% — komplex ohne C#)
│   ├── Send Message: "🏆 High Score: %data%"
│   └── Break

JSON-Parsing in SB ohne C# ist limitiert. Pragmatisch: Plain-Text-Protocol nutzen statt JSON, oder C# verwenden.

Use-Case C: Connection-State-Awareness

Wenn dein Overlay offline ist, soll SB nichts an es senden.

[Sys] Overlay Connected
Trigger: Custom Server → Connection Opened
└── Global (Set): overlayConnected = true (Non-Persisted)

[Sys] Overlay Disconnected
Trigger: Custom Server → Connection Closed
└── Global (Set): overlayConnected = false (Non-Persisted)

Bei anderen Actions: prüfe vor Send-to-Browser:

[Event] Sub
├── 1. Global (Get): overlayConnected → connected
├── 2. If/Else: %connected% Equals true
│   └── (Sende Update an Browser via Broadcast)
└── 3. (rest der Sub-Logic)

Plain-Text vs JSON

JSON-Parsing ohne C# ist umständlich. Für simple Cases reicht Plain-Text:

Browser:

ws.send('cmd=brbToggle');
ws.send('cmd=clipNow');
ws.send('cmd=scoreUpdate&val=1337');

SB:

├── If/Else: %data% Equals "cmd=brbToggle"
├── If/Else: %data% Equals "cmd=clipNow"
├── If/Else: %data% Contains "cmd=scoreUpdate"
│   └── Set Argument: scoreValue = $regex(%data%, val=(\d+), $1)$

Regex-Capture für Werte. Funktioniert ohne C#.

Variante: Custom-Frontend als Mod-Tool

Eigenes HTML-Dashboard für Stream-Setup:

  • Buttons für Scene-Switches
  • Slider für Audio-Volume
  • Live-View von Globals
  • Quick-Quote-Add

Alles via WebSocket-Verbindung zu SB. Du baust dein eigenes Stream-Deck als Web-App.

Sicherheit beim Custom Server

  • LAN-only, kein Internet-Exposure ohne Password
  • WS-Verbindungen sind nicht verschlüsselt (außer du machst WSS via Proxy)
  • Validierung: nimm nicht jeden String aus %data% als safe an

Häufige Fallen

  • Trigger feuert nicht — Server in SB nicht aktiv? Settings prüfen
  • Multiple Browser-Tabs — jeder Tab = eigener Client mit eigenem clientId. Action feuert pro Tab
  • Reconnect-Loop — Browser-Code muss bei Disconnect mit Backoff reconnecten, sonst hängt's
  • JSON in %data% — als String gespeichert. Quotes escapen: \"type\":\"x\"

Quellen