From 5c4ac55f619b1b6f11c46ea1367294b1c276ab98 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 4 Mar 2026 17:21:03 +0100 Subject: [PATCH] Update README and systemd service configuration for yourchat2. Added installation script `install-systemd.sh` for easier setup and modified `yourchat2.service` to improve service management, including environment file support and enhanced restart policies. --- README.md | 25 ++++- WEB_DIALOG_INTEGRATION.md | 200 ++++++++++++++++++++++++++++++++++++++ install-systemd.sh | 60 ++++++++++++ yourchat2.service | 15 ++- 4 files changed, 291 insertions(+), 9 deletions(-) create mode 100644 WEB_DIALOG_INTEGRATION.md create mode 100755 install-systemd.sh diff --git a/README.md b/README.md index 42d6e9a..8becf0c 100644 --- a/README.md +++ b/README.md @@ -107,11 +107,26 @@ Dann verbindet sich die bestehende Bridge (`chatTcpBridge.js`) direkt mit `yourc ## Systemd (optional) -Es liegt eine Beispiel-Datei `yourchat2.service` im Projekt. -Nach Anpassung des User/Paths: +Es liegt eine Produktions-nahe Unit-Datei `yourchat2.service` im Projekt. +Zusaetzlich gibt es ein Installationsskript `install-systemd.sh`, das: + +- Release-Binary baut +- Unit nach `/etc/systemd/system/yourchat2.service` installiert +- Environment-Datei unter `/etc/yourchat2/yourchat2.env` anlegt (falls nicht vorhanden) +- Service aktiviert und startet + +Installation: ```bash -sudo cp yourchat2.service /etc/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl enable --now yourchat2 +cd ~/Programs/yourchat2 +sudo ./install-systemd.sh ``` + +Danach Konfiguration ueber: + +- `/etc/yourchat2/yourchat2.env` + +Wichtige Variablen fuer produktiven Betrieb: + +- `CHAT_DB_URL` +- `SECRET_KEY` diff --git a/WEB_DIALOG_INTEGRATION.md b/WEB_DIALOG_INTEGRATION.md new file mode 100644 index 0000000..e4d18e0 --- /dev/null +++ b/WEB_DIALOG_INTEGRATION.md @@ -0,0 +1,200 @@ +# Web-Dialog Integration mit `yourchat2` + +Diese Doku beschreibt, wie eine Web-Applikation den Chat-Dialog mit dem Daemon `yourchat2` verbindet. +Sie ist absichtlich auf das Protokoll und die Client-Integration fokussiert (ohne Betriebs-/Startanleitung). + +## Verbindung + +- Transport: WebSocket +- Standard-Endpunkt: `ws://:1235` +- Nachrichtenformat: JSON (ein JSON-Objekt pro WebSocket-Frame) + +## Verbindungs- und Login-Flow + +1. WebSocket verbinden +2. `init` senden +3. Token (`type: 1`) aus der Antwort speichern +4. Alle weiteren auth-pflichtigen Commands mit `token` senden + +### `init` Beispiel + +```json +{ + "type": "init", + "name": "alice_1", + "room": "lobby", + "password": "" +} +``` + +## Wichtige Antworttypen + +- Token: + +```json +{"type":1,"message":""} +``` + +- Raumliste: + +```json +{"type":3,"message":[{"name":"lobby","users":2}]} +``` + +- Raum betreten / Status: + +```json +{"type":5,"message":"room_entered","to":"lobby"} +``` + +- Chatnachricht: + +```json +{"type":"message","userName":"alice","message":"Hallo","color":"#33aaee"} +``` + +- Fehler: + +```json +{"type":"error","message":"invalid_token"} +``` + +## Commands (WebSocket JSON) + +Nach erfolgreichem `init` (mit `token`): + +- Nachricht senden + +```json +{"type":"message","message":"Hallo zusammen","token":"..."} +``` + +- Raum wechseln + +```json +{"type":"join","room":"sports","password":"","token":"..."} +``` + +- Räume abfragen + +```json +{"type":"rooms","token":"..."} +``` + +- Userliste des aktuellen Raums + +```json +{"type":"userlist","token":"..."} +``` + +- Farbe setzen + +```json +{"type":"color","value":"#33aaee","token":"..."} +``` + +- Aktionen + +```json +{"type":"scream","message":"Hallo alle","token":"..."} +{"type":"do","message":"winkt","token":"..."} +{"type":"dice","message":"1d6","token":"..."} +{"type":"roll","value":4,"token":"..."} +``` + +- Dice-Game + +```json +{"type":"start_dice_game","rounds":3,"token":"..."} +{"type":"end_dice_game","token":"..."} +``` + +- Räume neu laden + +```json +{"type":"reload_rooms","token":"..."} +``` + +## Slash-Commands im Dialogtext + +Wenn das Frontend nur `type:"message"` sendet, werden folgende Slash-Kommandos serverseitig erkannt: + +- `/join [password]` +- `/color ` +- `/dice [expr]` +- `/roll [wert]` +- `/start_dice_game ` +- `/end_dice_game` +- `/reload_rooms` +- `/do ` +- `/scream ` +- `/rooms` +- `/userlist` + +Beispiel: + +```json +{"type":"message","message":"/join lounge geheim","token":"..."} +``` + +## Minimales Browser-Beispiel (Vanilla JS) + +```javascript +const ws = new WebSocket("ws://127.0.0.1:1235"); +let token = null; + +ws.onopen = () => { + ws.send(JSON.stringify({ + type: "init", + name: "alice_1", + room: "lobby", + password: "" + })); +}; + +ws.onmessage = (ev) => { + const msg = JSON.parse(ev.data); + + if (msg.type === 1) { + token = msg.message; + return; + } + + if (msg.type === "error") { + console.error("chat error:", msg.message); + return; + } + + if (msg.type === "message") { + console.log(`${msg.userName}: ${msg.message}`); + return; + } + + console.log("chat event:", msg); +}; + +function sendMessage(text) { + if (!token) return; + ws.send(JSON.stringify({ type: "message", message: text, token })); +} +``` + +## Häufige Fehlercodes + +- `missing_name`: `init` ohne `name` +- `invalid_username`: Username entspricht nicht den Regeln +- `loggedin`: Username ist bereits aktiv +- `user_not_allowed`: User nicht erlaubt (DB/Allowlist) +- `not_initialized`: Command vor `init` +- `missing_token`: Token fehlt +- `invalid_token`: Token stimmt nicht +- `room_not_found_or_join_failed`: Raumzugriff verweigert (Passwort/Alter/Regeln) +- `permission_denied`: fehlende Rechte (z. B. Dice-Admin-Operationen) + +## Hinweise für Frontend-Implementierung + +- Token zentral im Chat-State halten +- Reconnect-Strategie einbauen (neues `init`, neues Token) +- Vor Senden auth-pflichtiger Commands Token prüfen +- UI sollte Fehler vom Typ `error` immer sichtbar machen +- Für Slash-Kommandos reicht normales `message`-Senden diff --git a/install-systemd.sh b/install-systemd.sh new file mode 100755 index 0000000..6127217 --- /dev/null +++ b/install-systemd.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -euo pipefail + +SERVICE_NAME="yourchat2" +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICE_SRC="${PROJECT_DIR}/yourchat2.service" +SERVICE_DST="/etc/systemd/system/${SERVICE_NAME}.service" +ENV_DIR="/etc/yourchat2" +ENV_FILE="${ENV_DIR}/yourchat2.env" +BIN_PATH="${PROJECT_DIR}/target/release/yourchat2" + +if [[ "${EUID}" -ne 0 ]]; then + echo "Dieses Skript muss als root ausgefuehrt werden (z. B. via sudo)." >&2 + exit 1 +fi + +if [[ ! -f "${SERVICE_SRC}" ]]; then + echo "Service-Datei nicht gefunden: ${SERVICE_SRC}" >&2 + exit 1 +fi + +echo "[1/6] Build release binary ..." +sudo -u torsten cargo build --release --manifest-path "${PROJECT_DIR}/Cargo.toml" + +if [[ ! -x "${BIN_PATH}" ]]; then + echo "Binary wurde nicht erzeugt: ${BIN_PATH}" >&2 + exit 1 +fi + +echo "[2/6] Install service file ..." +install -m 0644 "${SERVICE_SRC}" "${SERVICE_DST}" + +echo "[3/6] Ensure environment directory ..." +install -d -m 0755 "${ENV_DIR}" + +echo "[4/6] Ensure environment file ..." +if [[ ! -f "${ENV_FILE}" ]]; then + cat > "${ENV_FILE}" <<'EOF' +# yourchat2 environment +# CHAT_WS_ADDR=0.0.0.0:1235 +# CHAT_TCP_ADDR=127.0.0.1:1236 +# CHAT_UNIX_SOCKET=/run/yourchat2/yourchat2.sock +# CHAT_ALLOWED_USERS=alice,bob +# CHAT_DB_URL=postgres://user:pass@host:5432/dbname +# SECRET_KEY=replace-with-real-secret +EOF + chmod 0640 "${ENV_FILE}" + chown root:root "${ENV_FILE}" +fi + +echo "[5/6] Reload and enable service ..." +systemctl daemon-reload +systemctl enable --now "${SERVICE_NAME}.service" + +echo "[6/6] Service status ..." +systemctl --no-pager --full status "${SERVICE_NAME}.service" || true + +echo +echo "Fertig. Konfiguration bei Bedarf in ${ENV_FILE} anpassen." +echo "Danach neu laden mit: systemctl restart ${SERVICE_NAME}.service" diff --git a/yourchat2.service b/yourchat2.service index c701815..9fb176a 100644 --- a/yourchat2.service +++ b/yourchat2.service @@ -1,18 +1,25 @@ [Unit] Description=yourchat2 Rust chat daemon -After=network.target +After=network-online.target +Wants=network-online.target [Service] Type=simple User=torsten +Group=torsten WorkingDirectory=/home/torsten/Programs/yourchat2 +EnvironmentFile=-/etc/yourchat2/yourchat2.env Environment=CHAT_WS_ADDR=0.0.0.0:1235 Environment=CHAT_TCP_ADDR=127.0.0.1:1236 -# Optional: -# Environment=CHAT_UNIX_SOCKET=/run/yourchat2/yourchat2.sock +RuntimeDirectory=yourchat2 +RuntimeDirectoryMode=0750 ExecStart=/home/torsten/Programs/yourchat2/target/release/yourchat2 -Restart=always +Restart=on-failure RestartSec=2 +TimeoutStopSec=15 +LimitNOFILE=65535 +NoNewPrivileges=true +PrivateTmp=true [Install] WantedBy=multi-user.target