MultiPlayer Game mit socket.io auf Uberspace

      0
MultiPlayer Game mit socket.io auf Uberspace

Ich hoste meine Webseiten und alle möglichen Spielereien auf uberspace.de und zähle mich damit zu einem von vielen glücklichen Ubernauten. Support ist spitze; die Dokumentation ausführlich und hilfreich. Trotzdem stehe ich manchmal vor sehr speziellen Problemen, die in ihrer Gänze natürlich nicht von den Ubernauten abgedeckt werden. So habe ich beispielsweise vor Kurzem einen UNO™ Klon mit socket.io umgesetzt, und wollte diesen nun für meine Freunde erreichbar machen. In diesem Artikel halte ich fest, wie mir das gelungen ist.

Voraussetzungen

Neben einem eigenen Uberspace benötigst du natürlich auch eine Anwendung, die aus einem Server und einem Client besteht. Da ich vor allem mit dem Thema CORS Schwierigkeiten hatte, skizziere ich kurz einmal meine Einstellungen für die Verbindung zwischen den beiden Parteien.

Server

Mein node Server ist eine einzelne Javascript Datei app.js, die lokal via nodemon gestartet werden kann. Für den Server benötigen wir die folgenden node Pakete, die ihr mit npm oder yarn installieren könnt.

yarn add cors dotenv express socket.io@3

Ich verwende socket.io Version 3, da ich mit Version 4 leider Probleme mit der Verbindung hatte. Um die Konfiguration zu vereinfachen, indem ich lokal und auf dem Uberspace unterschiedliche Konfigurationen ausrolle, nutze ich eine .env für die folgenden Parameter.

  • SERVER_HOST: Muss für den Uberspace 0.0.0.0 sein, lokal „localhost“
  • SERVER_PORT: Vom Uberspace vorgegeben, siehe Abschnitt „Uberspace Einrichtung
  • CLIENT_URL: Die URL mit der du auf den Server zugreifen möchtest, also deine Uberspace URL
  • SSL_CRT_PATH + SSL_KEY_PATH: Damit die Verbindung über HTTPS funktioniert, musst du die Zertifikate für deine Domain angeben. Die Dateien werden automatisch für deinen Uberspace erstellt.

Der Uberspacename „supercooler“ dient hier als Beispiel. Ersetze ihn durch deinen echten Uberspacenamen.

# Server:: .env

SERVER_HOST=0.0.0.0
SERVER_PORT=41234
CLIENT_URL=https://supercooler.uberspace.de

SSL=true
SSL_CRT_PATH=/home/supercooler/etc/certificates/supercooler.uber.space.crt
SSL_KEY_PATH=/home/supercooler/etc/certificates/supercooler.uber.space.key

Und hier nun der eigentliche Server-Code.

// Server:: app.js

const fs = require('fs') // Für das Einlesen des Zertifikats + des Keys

require('dotenv').config() // Lädt die .env Datei, sodass man mit `process.env.{VARIABLE}` darauf zugreifen kann

// Create http(s) server based on SSL config
const useSSL = process.env.SSL === 'true'
const Http = createServer()

// Create socket server
const SocketIO = require('socket.io')(Http, {
    allowEIO3: true,
    cors: {
        origin: process.env.CLIENT_URL,
        credentials: true,
    },
})

const port = process.env.SERVER_PORT || 41234
const hostname = process.env.SERVER_HOST || 'localhost'

Http.listen(port, hostname, () => {
    console.log(`Listening on ${useSSL ? 'https' : 'http'}://${hostname}:${port}`)
    console.log(`Allowed client url: ${process.env.CLIENT_URL}`)
})

/**
 * Hier wird je nach Einstellung ein HTTP oder HTTPS Server stellt
 */
function createServer () {
    const cors = require('cors')
    const Express = require('express')()
    Express.use(cors({ origin: '*' }))

    if (useSSL) {
        return require('https').createServer({
            key: fs.readFileSync(process.env.SSL_KEY_PATH),
            cert: fs.readFileSync(process.env.SSL_CRT_PATH),
        }, Express)
    } else {
        return require('http').createServer(Express)
    }
}

Client

Mein Client besteht aus einer VueJS Applikation. Das spielt aber natürlich keine Rolle. Für den Client verwende ich das node Paket vue-socket.io-extended. Installiere es mit folgendem Befehl:

yarn add vue-socket.io-extended socket.io-client

Die Verbindung zum socket.io Server wird in der main.js der Vue Applikation konfiguriert und eingebunden. In der .env Datei musst du dann nur noch die URL zu deinem Server inklusive dem vom Uberspace vorgegebenem Port (siehe Abschnitt „Uberspace Einrichtung„) als VUE_APP_SERVER_URL eintragen. Lokal kannst du die Variable auf http://localhost:41234 setzen.

Wenn wir also nach dem Beispiel von oben gehen, sieht die URL so aus:

// Client:: .env

VUE_APP_SERVER_URL=https://supercooler.uberspace.de:41234/supercooler-server
// Client:: main.js

import VueSocketIOExt from 'vue-socket.io-extended'
import { io } from 'socket.io-client'

const socket = io.connect(process.env.VUE_APP_SERVER_URL, { secure: process.env.NODE_ENV === 'production' })

Vue.use(VueSocketIOExt, socket)

So viel zum Code. Damit lässt sich die Anwendung lokal mit mehreren Browser-Fenster bereits testen. Im nächsten Abschnitt schauen wir uns an, wie wir das Ganze live kriegen.

Uberspace Einrichtung

Server

Das wichtigste zuerst: Da es sich um einen node Server handelt, landet dieser nicht im normalen ~/html Verzeichnis, wo du normalerweise deine Webseiten hochladen würdest. Stattdessen erstellen wir ein Verzeichnis direkt im Home-Verzeichnis und laden unsere Server Dateien (server.js und .env) hoch. Das wird so auch in der Uberspace Doku empfohlen. Der Pfad sieht dann beispielsweise so aus:

~/html/supercooler-server

Den Server kannst du mittels node server.js starten.

Als nächstes holen wir uns den bereits erwähnten Port, der vom Uberspace selbst gestellt wird. Führe dazu folgenden Befehl auf der Shell deines Uberspace aus. Als Rückmeldung bekommst du den benötigten Port.

uberspace port add

Der Server ist gestartet, der Port geöffnet – aber wie können wir über diesen nun auf den Server zugreifen, wenn der Server gar nicht im Webroot liegt? Auch dafür haben sich die Ubernauten etwas überlegt: web backends.

Ich persönlich richte bei mir alles über Subdomains meiner eigens konfigurierten nick-hat-boecker.de Domain ein. Wenn du nur die supercooler.uberspace.de Domain hast, kannst du den node Server quasi unter einem Unterverzeichnis konfigurierbar machen. Als Port gibst du natürlich den an, den der Uberspace dir im letzten Befehl ausgespuckt hat.

uberspace web backend set /supercooler-server --http --port {DEIN_PORT}

Client

Der Client ist hier das kleinere Übel. Je nachdem ob du nur den Client in deinem Webspace liegen hast, kopierst du die mit yarn build gebaute Vue Applikation entweder direkt in ~/html oder in einen Unterordner davon.

And that’s it! Nun kannst du deinen Client über https://supercooler.uberspace.de aufrufen und wirst direkt mit dem node Server unter https://supercooler.uberspace.de:41234/supercooler-server verbunden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert