Socket.IO
Verbinde adaptor:ex mit jeder Art von Webseite oder Web App die über eine Socket.IO Schnittstelle verfügt. Socket.IO erlaubt es in beide Richtungen zwischen APP und Server zu kommunizieren.
Mit dem Socket.IO Plugin kannst du beliebig viele Namespaces verbinden und Nachrichten über Rooms organisieren.
Das Socket.IO Plugin kann auch in ein eigenes Plugin integriert werden um Actions und Funktionalitäten für spezifische Web APPs anzupassen.
Einrichten
Füge das Socket.IO Plugin über Game -> Settings
hinzu und erstelle einen oder mehrere socket.io Namespaces.
Über das Settings Menü kannst du weitere Einstellungs Optionen für den Namespace hinzufügen.
namespace
optional
Der Name des socketio namespace über den sich web clients verbinden können. Die namespace url besteht aus der adaptor:ex server url (z.B. localhost:8081
), dem Game Namen, dem Namen des plugins (hier socketio
) und diesem namespace Namen. Die vollständige URL der Verbindung sieht etwa so aus:
http://localhost:8081/TestGame/socketio/test_namespace
Gibst du keinen expliziten namespace Namen an, wird der Name des Namespace items als namespace name verwendet.
Die volle URl, über die sich der client verbinden kann, wird unter namespace url
angegeben.
Die verfügbaren Basis URLs hängen von deinem Netzwerk und der adaptor:ex Server Konfiguration ab.
add meta data
optional
Wenn add meta data angewählt ist, werden alle Nachrichten, die mit diesem Namespace an den client gesendet werden mit info daten versehen.
Die folgenden properties werden hinzugefügt:
-
timestamp: Uhrzeit und Datum als unix timestamp, an dem die Nachricht gesendet wurde
-
message_id: eine eindeutige ID für die Nachricht
-
room: Der room, an den die Nachricht gesendet wurde
Die Nachricht selbst wird in der data property versendet.
Nachrichten, die so an den client gesendet werden sind immer js Objekte.
Eine Nachricht my message to the client
im room mit der ID my_room
mit zusätzlichen Metadaten könnte so aussehen:
{
"data": "my message to the client",
"timestamp": 1737027084827,
"message_id": "mNeMIgMf",
"room": "my_room"
}
level
optional
Level, das automatisch gestartet wird, wenn der Client eine Message über das Topic create sendet und einen neuen room erstellt.
level argument
optional
Gib den Namen für ein Level Argument, dass die Daten zum room enthält, der mit create neu erstellt wurde.
name
Der Level Argument name über den du im Level auf die room Daten zugreifen kannst.
type
Gibst du string
als Datentyp an, enthält das Level Argument die room id
.
Gibst du object
als Datentyp an, enthält das Level Argument alle Daten die zum room gespeichert wurden.
Gibst du eine Data Collection als Datentyp an, wird mit create room ein neues Item in der entsprechenden Collection angelegt. Über das Level Argument kannst du dann auf das neu erstellte Item zugreifen.
room id pattern
optional
Ein string Format, das verwendet wird, wenn mit create ein neuer room mit automatischer id
erstellt wird.
Gib unter length die Anzahl Zeichen an, die neu erstellte room ids haben werden. In characters kannst du alle Zeichen angeben, die beim automatischen Erstellen von room ids verwendet werden.
In diesem Beispiel werden room ids für diesen Namespace 5 stellige Zahlen:
Rooms erstellen und beitreten
Namespaces im Socket.IO plugin bieten die Möglichkeit rooms über den client erstellen und beitreten zu lassen. Nachrichten, die in einem room ausgetauscht werden, werden nur von clients empfangen, die dem entsprechnden room über join beigetreten sind.
Folgende topics sind für diesen Zweck reserviert.
create
Erstellt einen neuen socket.io room. Die room id und ggf. weitere Eigenschaften werden im entsprechenden Namespace Item gespeichert.
Wenn für den Namespace ein level angegeben ist, wird mit create auch immer eine session des angegebenen Levels gestartet, wenn der room noch nicht existiert.
Wenn für den Namespace ein level mit level argument ist und level argument type ist eine data collection, wird zudem ein Data Item erstellt. Room Informationen werden dann in diesem Data Item statt des Namespace Items gespeichert.
Der client tritt automatisch dem neu erstellten room bei (join)
create gibt über socket.io callback oder emitWithAck einen Fehler zurück, wenn der room bereits existiert.
topic: create
message: Die room id
und ggf. weitere Eigenschaften, die gespeichert werden sollen.
Ist message ein string, wird ein room mit der entsprechenden id angelegt. String message Beispiel:
Ist message ein Objekt werden zusätzlich zur id
alle Eigenschaften des Objektes zum room gespeichert. Um eine eigene id
zu vergeben muss die Nachricht eine id
property enthalten. Objekt message Beispiel:
Ist message leer, oder wird existiert keine id
property, wird eine automatische room id
erstellt. Die Form der id
kann über die Namespace Einstellung room id pattern festgelegt werden.
Die automatisch generierte room id
wird über socket.io callback oder emitWithAck zurückgegeben.
returns: Gibt ein js object zurück, dass die room id
enthält. Zum Beispiel:
join
Der client tritt dem angegebenen room bei. Wird der room in einer Socket.IO action verwendet, ist dieser client in die Kommunikation einbezogen.
join gibt über socket.io callback oder emitWithAck einen Fehler zurück, wenn der room nicht existiert.
topic: join
message: Die room id als string. Beispiel
returns: Gibt die room id und alle Daten, die mit dem room assoziiert sind zurück. Beispiel:
leave
Der client verlässt den angegebenen room wieder.
topic: leave
message: Die room id (string), des room der verlassen werden soll. Beispiel:
Sende message all
um alle rooms zu verlassen.
rooms
Gibt eine Liste aller rooms zurück, denen der client beigetreten ist.
Mit der message all
werden alle rooms zurückgegeben, die im Namespace existieren.
topic: rooms
message: Ist message leer, werden nur die rooms zurückgegeben denen der client mit join beigetreten ist. Mit
werden alle rooms zurückgegeben die im Namespace existieren.
Actions
-
Send Socket.IO Message sendet Daten an einen socket.io client einer Webseite oder Web APP.
-
On Socket.IO Message erlaubt es auf eingehende Nachrichten eines client einer Webseite oder Web APP zu reagieren.
Beispiel
Level File: socketio_example.json
HTML File: socketio_example.html
Öffne dein adaptor:ex Game und richte das Socket.IO Plugin mti einem Namespace ein (Einrichten).
Erstelle eine .html
Datei HTML Webseite und füge die socket.io client library hinzu.
Zum Beispiel:
<html>
<head>
<title>adaptor:ex socket.io plugin example</title>
<meta charset="utf-8">
</head>
<body>
</body>
<script src="https://cdn.socket.io/4.8.1/socket.io.min.js"></script>
<script>
console.log("Let's get started!")
</script>
</html>
Kopiere die namespace url aus den Socket.IO Plugin settings (namespace) und erstelle eine Verbindung zu deinem Namespace im script deiner Webseite.
<script>
console.log("Let's get started!")
const socket = io("http://localhost:8081/Tutorial/socketio/my_app")
</script>
Nun kannst du die socket.io client library Funktionen Nutzen um Daten zwischen deiner Webseite und deinem adaptor:ex Game auszutauschen.
Eine Nachricht zur Webseite Senden
Teste die Verbindung indem du ein neues Level erstellst und eine Send Socketio Message auf die Stage ziehst.
Lasse room frei und gib ein topic und eine einfache message an.
Im script deiner Webseite füge die socket.on Funktion mit dem entsprechenden topic hinzu und nutze console.log
um eingehende Nachrichten in die console zu schreiben.
<script>
console.log("Let's get started!")
const socket = io("http://localhost:8081/Tutorial/socketio/my_app")
socket.on("greetings", message => {
console.log(message)
})
</script>
Öffne die Entwickler Konsole deines Browsers (z.B. mit Ctrl+Shift+I)
In adaptor:ex, erstelle eine neue Session von deinem Level und löse den State mit der Send Socket Message action aus.
Wenn die Verbindung zwischen adaptor:ex und Webseite funktioniert siehts du in der Entwickeler Konsole die Nachricht, die du über die Send Socket Message action gesendet hast.
Eine Nachricht von der Webseite empfangen
Füge deiner Seite ein Interaktionslement, etwa einen Button, hinzu um Daten an den adaptor:ex Server zu senden.
Und verknüpfe den Button mit der socket.emit Funktion.
<script>
const socket = io("http://localhost:8081/Tutorial/socketio/my_app")
function sendGo() {
socket.emit("button", "go", (response) => {
console.log(response)
})
}
</script>
Füge deinem Level in adaptor:ex eine On Socket Message action hinzu, in der du auf Nachrichten auf dem topic button
reagierst.
On Socket.IO Message
Erstelle einen neuen State Go
, der ausgelöst werden soll, wenn der Button geklickt wird. Löst du nun den State mit der On Socket Message action aus und klickst auf der Webseite auf den "GO" Button, sollte deine Session in den Go
State wechseln.
Einen room erstellen
Füge zwei neue Buttons zur Seite hinzu
<body>
<button onclick="createRoom()">CREATE</button>
<button onclick="joinRoom()">JOIN</button>
<button onclick="sendGo()">GO</button>
</body>
Und verknüpfe die Buttons mit der socket.emit Funktion und den topics create und join.
<script>
const socket = io("http://localhost:8081/Tutorial/socketio/my_app")
function createRoom() {
socket.emit("create", "myroom", (response) => {
console.log(response)
})
}
function joinRoom() {
socket.emit("join", "myroom", (response) => {
console.log(response)
})
}
</script>
Klicks du auf create, wird in adaptor:ex ein neuer socket.io room erstellt.
Ergänze den room nun in adaptor:ex in der Send Socket.IO Message und der On Socket Message action.
Öffnest du deine Seite in einem weiteren Browser Fenster oder Tab, werden Nachrichten dann nur mit den Seiten ausgetauscht, die dem room übder den JOIN
button beigetreten sind.
Rooms zur Spiel, Player und Session Verwaltung einsetzen
Die socket.io rooms bieten sich an um unterschiedliche Verläufe von getrennten Spielen oder von Spielern in einer gemeinsamen Spielrunde zu verwalten. Mit dem Socket.IO Plugin kannst du automatisch room IDs erstellen lassen, die mit einer Session deiner adaptor:ex Level verknüpft sind. Nutzer deiner Webseite können so etwa neue Spielrunden erstellen oder einem bestehenden Spiel beitreten.
Öffne die Einstellungen deines Namespace in den Socket.IO Plugin settings unter Game -> Settings
.
Füge im Namespace über das Settings Menü die Optionen level, level argument und room id pattern hinzu.
Gib in der level Option, den Namen deines neu erstelltes Level an (hier socketio
).
Wir können die bereits existierende players
collection nutzen um room Informationen zu speichern. Gib als level argument name einen Namen an unter dem du die room infos adressieren kannst (hier Player
). Als type die collection in der neue room items angelegt werden sollen (hier players
).
Optional kannst du mit room id pattern noch das Format der automatisch generierten room Namen anpassen (hier length: 5
und characters: 0123456789
).
Klicke Save um die Einstellungen zu übernehmen.
In deinem Level, passe die room options in den Send Socket.IO Message und On Socket Message an. Verwende den Wert, den du als level argument name angegeben hast (hier Player
) als variable.
Send Socket.IO Message
Note
Die room id ist im jeweils neu erstellten players Item unter socketio.id
gespeichert. Verwendest du wie hier ein Data Item in der room Option, nutzt die Send Socket.IO Message action die darin gespeicherte id. [[Player]]
ist also ein synonym für [[Player.socketio.id]]
.
Verbinde deine actions über eine Next oder Timeout action mit dem START State und miteinander.
Entferne jetzt den room name in der createRoom
Funktion auf deiner Webseite. So wird dann bei Klick stattdessen ein Name automatisch generiert.
Die neu generierte room id wird in response
zurückgegeben. Sie kann anschließend genutzt werden um sich in Zukunft mit der selben Session zu verbinden.
Erstelle dafür noch ein Ausgabe- und ein Eingabefeld auf deiner Webseite, z.B.:
<body>
<button onclick="createRoom()">CREATE</button>
<span id="new-room"></span><br>
<input id="room" type="text" placeholder="Enter room">
<button onclick="joinRoom()">JOIN</button><br>
<button onclick="sendGo()">GO</button>
</body>
function createRoom() {
socket.emit("create", "", (response) => {
console.log(response)
document.getElementById("new-room").innerText = response.id
})
}
function joinRoom() {
const room = document.getElementById("room").value
socket.emit("join", room, (response) => {
console.log(response)
})
}
Wechsle in deinem Level in den Live Modus und lösche alle bestehenden Sessions . Klickst du nun auf den CREATE
button auf deiner Webseite, wird eine neue Session erstellt. Im HelloWeb State wird dann eine Nachricht an den client gesendet. Sobald der WaitForGo State ausgelöst wurde, wartet die Session darauf, dass der Go
Button gedrückt wird.
Da create automatisch ein join durchführt und dem neu erstellten room beitritt brauchst du an dieser Stelle nicht explizit join zu nutzen. Ab jetzt kannst du aber nach einem page reload oder in einem anderen Browser fenster oder tab dem neu erstellten room und damit der Session deines Levels mit der angegebenen id beitreten.
Werden nun weitere rooms erstellt ist so sichergestellt, das jedes Spiel oder jeder Player einen unabhängigen Session verlauf startet.
Mit jedem room wird in diesem Setup ein eigenes Data Item in der players
collection erstellt. Über das Level Argument (hier Player
) kannst du so auch Daten die für den individuellen Spielverlauf wichtig sind, z.B. mit der Set Variable action speichern.