Compare commits
3
Commits
3c267a500e
...
94af8995cf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94af8995cf | ||
|
|
286a71e47c | ||
|
|
f4221bf436 |
@@ -970,7 +970,24 @@ cp .env.example .env # RVS-Zugang + CONTROL_ENABLED=true eintragen
|
||||
chmod +x aria-host-agent && ./aria-host-agent
|
||||
```
|
||||
|
||||
Oder als Dienst: `host-agent/aria-host-agent.service` (systemd).
|
||||
**Als systemd-Dienst** (Dauerbetrieb) — der Installer kopiert Binary + `.env`
|
||||
an ihre Plätze und richtet den Dienst ein:
|
||||
|
||||
```bash
|
||||
sudo ./install-service.sh /pfad/zur/.env # .env-Pfad direkt
|
||||
sudo ./install-service.sh # oder: ncurses-Dateidialog (dialog)
|
||||
```
|
||||
|
||||
→ Binary nach `/usr/local/bin`, `.env` nach `/etc/aria-host-agent/.env` (0600),
|
||||
Unit installiert + `enable --now`. Danach `journalctl -u aria-host-agent -f`.
|
||||
|
||||
### TLS / SNI — Agent im selben Netz wie der RVS
|
||||
|
||||
Verbindet der Agent direkt auf die **interne RVS-IP** (statt über den externen
|
||||
Hostnamen per NAT-Hairpin), scheitert TLS sonst am fehlenden Cert für die IP
|
||||
(`tlsv1 alert internal error`). Dann in der `.env`: `RVS_HOST=<interne-ip>` +
|
||||
`RVS_SNI=<zert-name>` (z.B. `mobil.hacker-net.de`). Gilt genauso für Satelliten
|
||||
und Compute-Nodes im RZ-Netz (`RVS_SNI` in deren `.env`).
|
||||
|
||||
### sudo
|
||||
|
||||
|
||||
+36
-1
@@ -53,7 +53,42 @@ Overlay stapeln. Zwei Auswege:
|
||||
1. `dist/aria-host-agent` auf den Ziel-Rechner kopieren.
|
||||
2. `.env.example` → `.env` daneben, RVS-Zugang + `CONTROL_ENABLED=true` eintragen.
|
||||
3. Starten: `chmod +x aria-host-agent && ./aria-host-agent`
|
||||
— oder als Dienst: siehe `aria-host-agent.service`.
|
||||
|
||||
### Als systemd-Dienst (empfohlen für Dauerbetrieb)
|
||||
|
||||
Der Installer kopiert Binary + `.env` an ihre Plätze und richtet den Dienst ein:
|
||||
|
||||
```bash
|
||||
# .env-Pfad direkt übergeben:
|
||||
sudo ./install-service.sh /pfad/zur/.env
|
||||
|
||||
# ODER ohne Argument -> ncurses-Dateidialog (dialog) zum Auswählen der .env:
|
||||
sudo ./install-service.sh
|
||||
```
|
||||
|
||||
Er legt ab:
|
||||
- Binary → `/usr/local/bin/aria-host-agent`
|
||||
- `.env` → `/etc/aria-host-agent/.env` (Rechte `0600`, enthält Token/Passwörter)
|
||||
- Unit → `/etc/systemd/system/aria-host-agent.service`, dann `enable --now`.
|
||||
|
||||
Danach: `systemctl status aria-host-agent` · `journalctl -u aria-host-agent -f`.
|
||||
Die Binary sucht er unter `dist/aria-host-agent` bzw. `./aria-host-agent` (oder
|
||||
2. Argument). Braucht `dialog` für den Dateibrowser (bietet die Installation an).
|
||||
|
||||
## TLS / SNI — Agent im selben Netz wie der RVS
|
||||
|
||||
Steht der Rechner im **selben Netz wie der RVS** (z.B. Rechenzentrum) und soll
|
||||
direkt auf dessen **interne IP** verbinden (kein NAT-Hairpin über den externen
|
||||
Hostnamen), scheitert der TLS-Handshake sonst an `tlsv1 alert internal error`
|
||||
(Caddy hat kein Zertifikat für die IP). Lösung — in der `.env`:
|
||||
|
||||
```
|
||||
RVS_HOST=172.0.2.34 # interne RVS-IP
|
||||
RVS_SNI=mobil.hacker-net.de # Name, für den das Caddy-Zert gilt
|
||||
```
|
||||
|
||||
Der Agent verbindet dann auf die IP, präsentiert aber den Namen im TLS-SNI.
|
||||
Zuhause / im Normalfall `RVS_SNI` leer lassen und den Hostnamen als `RVS_HOST`.
|
||||
|
||||
## sudo
|
||||
|
||||
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
# ARIA Host-Agent — Service-Installer (systemd).
|
||||
#
|
||||
# Installiert die Binary nach /usr/local/bin, die .env nach /etc/aria-host-agent
|
||||
# und richtet den systemd-Dienst ein (enable + start).
|
||||
#
|
||||
# Nutzung:
|
||||
# sudo ./install-service.sh /pfad/zur/.env # .env-Pfad direkt uebergeben
|
||||
# sudo ./install-service.sh # ncurses-Dateidialog (dialog)
|
||||
#
|
||||
# Die Binary wird unter ./dist/aria-host-agent oder ./aria-host-agent erwartet
|
||||
# (vorher ./build.sh oder ./build-native.sh ausfuehren), oder als 2. Argument.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
BIN_DST="/usr/local/bin/aria-host-agent"
|
||||
ETC_DIR="/etc/aria-host-agent"
|
||||
UNIT_DST="/etc/systemd/system/aria-host-agent.service"
|
||||
|
||||
die() { echo "FEHLER: $*" >&2; exit 1; }
|
||||
|
||||
[ "$(id -u)" -eq 0 ] || die "Bitte mit sudo/root ausfuehren: sudo $0 $*"
|
||||
|
||||
# ── Binary finden (Arg 2 > dist/ > ./) ──────────────────────────────
|
||||
BIN_SRC="${2:-}"
|
||||
if [ -z "$BIN_SRC" ]; then
|
||||
if [ -x "$SCRIPT_DIR/dist/aria-host-agent" ]; then BIN_SRC="$SCRIPT_DIR/dist/aria-host-agent"
|
||||
elif [ -x "$SCRIPT_DIR/aria-host-agent" ]; then BIN_SRC="$SCRIPT_DIR/aria-host-agent"
|
||||
fi
|
||||
fi
|
||||
[ -n "$BIN_SRC" ] && [ -f "$BIN_SRC" ] || die "Binary nicht gefunden. Erst bauen (./build.sh) oder als 2. Argument uebergeben."
|
||||
|
||||
# ── .env bestimmen: Arg 1, sonst ncurses-Dateidialog ────────────────
|
||||
ENV_SRC="${1:-}"
|
||||
if [ -z "$ENV_SRC" ]; then
|
||||
if ! command -v dialog >/dev/null 2>&1; then
|
||||
echo "Kein .env-Pfad uebergeben und 'dialog' ist nicht installiert."
|
||||
read -r -p "dialog jetzt installieren (apt)? [j/N] " a
|
||||
case "$a" in
|
||||
j|J|y|Y) (apt-get update && apt-get install -y dialog) || die "dialog-Installation fehlgeschlagen — .env-Pfad bitte als Argument uebergeben." ;;
|
||||
*) die "Ohne dialog bitte den .env-Pfad als Argument uebergeben: sudo $0 /pfad/zur/.env" ;;
|
||||
esac
|
||||
fi
|
||||
# dialog --fselect: Dateibrowser; --stdout gibt die Auswahl auf stdout.
|
||||
START_DIR="${SUDO_USER:+/home/$SUDO_USER/}"
|
||||
[ -d "$START_DIR" ] || START_DIR="$SCRIPT_DIR/"
|
||||
ENV_SRC="$(dialog --stdout --title 'ARIA Host-Agent — .env auswaehlen' \
|
||||
--fselect "$START_DIR" 14 72)" || true
|
||||
clear
|
||||
[ -n "$ENV_SRC" ] || die "Abgebrochen — keine .env ausgewaehlt."
|
||||
fi
|
||||
[ -f "$ENV_SRC" ] || die ".env nicht gefunden: $ENV_SRC"
|
||||
|
||||
echo "Binary : $BIN_SRC"
|
||||
echo ".env : $ENV_SRC"
|
||||
|
||||
# ── Installieren ────────────────────────────────────────────────────
|
||||
install -m 0755 "$BIN_SRC" "$BIN_DST"
|
||||
install -d -m 0755 "$ETC_DIR"
|
||||
install -m 0600 "$ENV_SRC" "$ETC_DIR/.env" # 0600: enthaelt Token/Passwoerter
|
||||
|
||||
if [ -f "$SCRIPT_DIR/aria-host-agent.service" ]; then
|
||||
install -m 0644 "$SCRIPT_DIR/aria-host-agent.service" "$UNIT_DST"
|
||||
else
|
||||
die "aria-host-agent.service nicht gefunden neben dem Installer."
|
||||
fi
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now aria-host-agent
|
||||
|
||||
echo
|
||||
echo "✓ Installiert & gestartet."
|
||||
echo " Status: systemctl status aria-host-agent"
|
||||
echo " Log: journalctl -u aria-host-agent -f"
|
||||
echo " .env: $ETC_DIR/.env (aendern -> systemctl restart aria-host-agent)"
|
||||
@@ -7,6 +7,12 @@ RVS_HOST=rvs.example.de
|
||||
RVS_PORT=443
|
||||
RVS_TLS=true
|
||||
RVS_TOKEN=
|
||||
# RVS_SNI: nur noetig, wenn RVS_HOST eine IP ist (Satellit im selben Netz wie der
|
||||
# RVS, direkt auf die interne IP). Dann hier den Zertifikats-/Hostnamen angeben,
|
||||
# damit der TLS-Handshake (SNI) passt. Sonst leer lassen.
|
||||
# RVS_HOST=172.0.2.34
|
||||
# RVS_SNI=mobil.hacker-net.de
|
||||
RVS_SNI=
|
||||
|
||||
# ─── Identitaet / Adresse dieses Satelliten ────────────────────────
|
||||
# SATELLITE_ID = technisch eindeutig (a-z0-9-_), Default = Hostname-Slug.
|
||||
|
||||
@@ -48,6 +48,11 @@ python satellite.py # liest .env automatisch
|
||||
den Satelliten erreicht). `SATELLITE_LOCATION` ist der Name, über den ARIA das Netz
|
||||
anspricht („Büro").
|
||||
|
||||
**Satellit im selben Netz wie der RVS** (z.B. Rechenzentrum, direkt auf die
|
||||
interne IP statt NAT-Hairpin): `RVS_HOST=<interne-ip>` + **`RVS_SNI=<zert-name>`**
|
||||
(der Name, für den das Caddy-Zertifikat gilt). Ohne das scheitert TLS an
|
||||
`tlsv1 alert internal error`. Zuhause / normal: `RVS_SNI` leer lassen.
|
||||
|
||||
**Kontrolle:** im Log/Diagnostic muss `primary_ip` im Ziel-LAN liegen
|
||||
(`192.168.177.x`) — steht da `192.168.65.x` oder `172.x`, sitzt der Satellit im
|
||||
falschen (Docker-)Netz.
|
||||
|
||||
+15
-3
@@ -107,6 +107,10 @@ RVS_HOST = os.environ.get("RVS_HOST", "")
|
||||
RVS_PORT = int(os.environ.get("RVS_PORT", "443") or "443")
|
||||
RVS_TLS = _env_bool("RVS_TLS", True)
|
||||
RVS_TOKEN = os.environ.get("RVS_TOKEN", "")
|
||||
# TLS-Hostname (SNI + Zertifikatspruefung), falls RVS_HOST eine IP ist — z.B. ein
|
||||
# Satellit im selben Netz wie der RVS, der direkt auf die interne IP verbindet
|
||||
# (das Caddy-Zertifikat gilt aber fuer den Namen). Leer = SNI = RVS_HOST.
|
||||
RVS_SNI = os.environ.get("RVS_SNI", "").strip()
|
||||
|
||||
SATELLITE_ID = (os.environ.get("SATELLITE_ID") or _default_id()).strip()
|
||||
SATELLITE_LOCATION = (os.environ.get("SATELLITE_LOCATION") or SATELLITE_ID).strip()
|
||||
@@ -1316,13 +1320,21 @@ class Satellite:
|
||||
_creds_load()
|
||||
asyncio.create_task(self._periodic_scan())
|
||||
backoff = 1
|
||||
# SNI-/Cert-Override: auf eine IP verbinden, aber den Namen im TLS-
|
||||
# Handshake praesentieren (Caddy-Cert gilt fuer den Namen).
|
||||
connect_kwargs = {"max_size": 8 * 1024 * 1024,
|
||||
"ping_interval": 20, "ping_timeout": 20}
|
||||
if RVS_TLS and RVS_SNI:
|
||||
import ssl
|
||||
connect_kwargs["ssl"] = ssl.create_default_context()
|
||||
connect_kwargs["server_hostname"] = RVS_SNI
|
||||
while True:
|
||||
proto = "wss" if RVS_TLS else "ws"
|
||||
url = f"{proto}://{RVS_HOST}:{RVS_PORT}?token={RVS_TOKEN}"
|
||||
try:
|
||||
logger.info("Verbinde mit RVS %s://%s:%s …", proto, RVS_HOST, RVS_PORT)
|
||||
async with websockets.connect(url, max_size=8 * 1024 * 1024,
|
||||
ping_interval=20, ping_timeout=20) as ws:
|
||||
logger.info("Verbinde mit RVS %s://%s:%s%s …", proto, RVS_HOST, RVS_PORT,
|
||||
f" (SNI {RVS_SNI})" if RVS_SNI else "")
|
||||
async with websockets.connect(url, **connect_kwargs) as ws:
|
||||
self.ws = ws
|
||||
backoff = 1
|
||||
await self._hello(log=True)
|
||||
|
||||
@@ -43,6 +43,13 @@ RVS_PORT=444
|
||||
RVS_TLS=true
|
||||
RVS_TLS_FALLBACK=true
|
||||
RVS_TOKEN=dein_token_hier
|
||||
# RVS_SNI: nur noetig, wenn die Box im SELBEN Netz wie der RVS steht und direkt
|
||||
# auf dessen interne IP verbinden soll (kein NAT-Hairpin ueber den externen
|
||||
# Hostnamen). Dann RVS_HOST=<interne-ip> und hier den Zertifikats-/Hostnamen, fuer
|
||||
# den Caddy sein Cert hat. Zuhause / normal: leer lassen.
|
||||
# RVS_HOST=172.0.2.34
|
||||
# RVS_SNI=mobil.hacker-net.de
|
||||
RVS_SNI=
|
||||
|
||||
# ─── Optional ─────────────────────────────────────
|
||||
# HF_TOKEN= # nur falls ein HF-gated Modell (z.B. Voxtral) geladen wird
|
||||
|
||||
@@ -58,6 +58,10 @@ GPU-Test + Stack-Start.
|
||||
24-GB-Karte: `docker compose stop whisper-bridge && docker compose --profile voxtral up -d --build`.
|
||||
- **Erster Start lädt Modelle** (mehrere GB via HuggingFace nach `xtts/hf-cache`
|
||||
+ `xtts/models`) — genug Platz (1 TB NVMe ✓) und etwas Geduld.
|
||||
- **Box im selben Netz wie der RVS** (z.B. Rechenzentrum, direkt auf die interne
|
||||
IP statt NAT-Hairpin): in `xtts/.env` `RVS_HOST=<interne-ip>` + **`RVS_SNI=<zert-name>`**
|
||||
(Name, für den das Caddy-Zert gilt). Ohne das scheitert TLS an `tlsv1 alert
|
||||
internal error`. Zuhause / normal: `RVS_SNI` leer lassen.
|
||||
|
||||
## Verifizieren
|
||||
|
||||
|
||||
+10
-2
@@ -51,6 +51,9 @@ RVS_PORT = int(os.getenv("RVS_PORT", "443"))
|
||||
RVS_TLS = os.getenv("RVS_TLS", "true").lower() == "true"
|
||||
RVS_TLS_FALLBACK = os.getenv("RVS_TLS_FALLBACK", "true").lower() == "true"
|
||||
RVS_TOKEN = os.getenv("RVS_TOKEN", "").strip()
|
||||
# TLS-Hostname (SNI + Cert), falls RVS_HOST eine IP ist (Box im selben Netz wie
|
||||
# der RVS, direkt auf die interne IP). Leer = SNI = RVS_HOST.
|
||||
RVS_SNI = os.getenv("RVS_SNI", "").strip()
|
||||
|
||||
# F5-TTS Konfiguration
|
||||
# ─────────────────────────────────────────────────────────────────
|
||||
@@ -880,9 +883,14 @@ async def run_loop(runner: F5Runner) -> None:
|
||||
url = f"{scheme}://{RVS_HOST}:{RVS_PORT}?token={RVS_TOKEN}"
|
||||
masked = url.replace(RVS_TOKEN, "***") if RVS_TOKEN else url
|
||||
|
||||
connect_kwargs = {"ping_interval": 20, "ping_timeout": 10, "max_size": 50 * 1024 * 1024}
|
||||
if use_tls and RVS_SNI:
|
||||
import ssl
|
||||
connect_kwargs["ssl"] = ssl.create_default_context()
|
||||
connect_kwargs["server_hostname"] = RVS_SNI
|
||||
try:
|
||||
logger.info("Verbinde zu RVS: %s", masked)
|
||||
async with websockets.connect(url, ping_interval=20, ping_timeout=10, max_size=50 * 1024 * 1024) as ws:
|
||||
logger.info("Verbinde zu RVS: %s%s", masked, f" (SNI {RVS_SNI})" if (use_tls and RVS_SNI) else "")
|
||||
async with websockets.connect(url, **connect_kwargs) as ws:
|
||||
logger.info("RVS verbunden")
|
||||
retry_s = 2
|
||||
tls_fallback_tried = False
|
||||
|
||||
@@ -43,6 +43,9 @@ RVS_PORT = os.getenv("RVS_PORT", "443").strip()
|
||||
RVS_TLS = os.getenv("RVS_TLS", "true").lower() == "true"
|
||||
RVS_TLS_FALLBACK = os.getenv("RVS_TLS_FALLBACK", "true").lower() == "true"
|
||||
RVS_TOKEN = os.getenv("RVS_TOKEN", "").strip()
|
||||
# TLS-Hostname (SNI + Cert), falls RVS_HOST eine IP ist (Box im selben Netz wie
|
||||
# der RVS, direkt auf die interne IP). Leer = SNI = RVS_HOST.
|
||||
RVS_SNI = os.getenv("RVS_SNI", "").strip()
|
||||
|
||||
LLAMA_URL = os.getenv("LLAMA_URL", "http://llama:8081").rstrip("/")
|
||||
LLM_MODEL = os.getenv("LLM_MODEL", "qwen3-8b")
|
||||
@@ -419,11 +422,15 @@ async def _run() -> None:
|
||||
scheme = "wss" if use_tls else "ws"
|
||||
url = f"{scheme}://{RVS_HOST}:{RVS_PORT}?token={RVS_TOKEN}"
|
||||
masked = url.replace(RVS_TOKEN, "***") if RVS_TOKEN else url
|
||||
connect_kwargs = {"ping_interval": 20, "ping_timeout": 10, "max_size": 16 * 1024 * 1024}
|
||||
if use_tls and RVS_SNI:
|
||||
import ssl
|
||||
connect_kwargs["ssl"] = ssl.create_default_context()
|
||||
connect_kwargs["server_hostname"] = RVS_SNI
|
||||
try:
|
||||
logger.info("Verbinde zu RVS: %s (llama=%s)", masked, LLAMA_URL)
|
||||
async with websockets.connect(
|
||||
url, ping_interval=20, ping_timeout=10, max_size=16 * 1024 * 1024
|
||||
) as ws:
|
||||
logger.info("Verbinde zu RVS: %s%s (llama=%s)", masked,
|
||||
f" (SNI {RVS_SNI})" if (use_tls and RVS_SNI) else "", LLAMA_URL)
|
||||
async with websockets.connect(url, **connect_kwargs) as ws:
|
||||
logger.info("RVS verbunden — llm-adapter online")
|
||||
retry_s = 2
|
||||
tls_fallback_tried = False
|
||||
|
||||
+10
-3
@@ -53,6 +53,9 @@ RVS_PORT = int(os.getenv("RVS_PORT", "443"))
|
||||
RVS_TLS = os.getenv("RVS_TLS", "true").lower() == "true"
|
||||
RVS_TLS_FALLBACK = os.getenv("RVS_TLS_FALLBACK", "true").lower() == "true"
|
||||
RVS_TOKEN = os.getenv("RVS_TOKEN", "").strip()
|
||||
# TLS-Hostname (SNI + Cert), falls RVS_HOST eine IP ist (Box im selben Netz wie
|
||||
# der RVS, direkt auf die interne IP). Leer = SNI = RVS_HOST.
|
||||
RVS_SNI = os.getenv("RVS_SNI", "").strip()
|
||||
|
||||
VOXTRAL_MODEL = os.getenv("VOXTRAL_MODEL", "mistralai/Voxtral-Mini-3B-2507")
|
||||
VOXTRAL_LANGUAGE = os.getenv("VOXTRAL_LANGUAGE", "de")
|
||||
@@ -744,10 +747,14 @@ async def run_loop(sessions: SessionManager) -> None:
|
||||
scheme = "wss" if use_tls else "ws"
|
||||
url = f"{scheme}://{RVS_HOST}:{RVS_PORT}?token={RVS_TOKEN}"
|
||||
masked = url.replace(RVS_TOKEN, "***") if RVS_TOKEN else url
|
||||
connect_kwargs = {"ping_interval": 20, "ping_timeout": 10, "max_size": 50 * 1024 * 1024}
|
||||
if use_tls and RVS_SNI:
|
||||
import ssl
|
||||
connect_kwargs["ssl"] = ssl.create_default_context()
|
||||
connect_kwargs["server_hostname"] = RVS_SNI
|
||||
try:
|
||||
logger.info("Verbinde zu RVS: %s", masked)
|
||||
async with websockets.connect(url, ping_interval=20, ping_timeout=10,
|
||||
max_size=50 * 1024 * 1024) as ws:
|
||||
logger.info("Verbinde zu RVS: %s%s", masked, f" (SNI {RVS_SNI})" if (use_tls and RVS_SNI) else "")
|
||||
async with websockets.connect(url, **connect_kwargs) as ws:
|
||||
logger.info("RVS verbunden")
|
||||
retry_s = 2
|
||||
tls_fallback_tried = False
|
||||
|
||||
+10
-2
@@ -53,6 +53,9 @@ RVS_PORT = int(os.getenv("RVS_PORT", "443"))
|
||||
RVS_TLS = os.getenv("RVS_TLS", "true").lower() == "true"
|
||||
RVS_TLS_FALLBACK = os.getenv("RVS_TLS_FALLBACK", "true").lower() == "true"
|
||||
RVS_TOKEN = os.getenv("RVS_TOKEN", "").strip()
|
||||
# TLS-Hostname (SNI + Cert), falls RVS_HOST eine IP ist (Box im selben Netz wie
|
||||
# der RVS, direkt auf die interne IP). Leer = SNI = RVS_HOST.
|
||||
RVS_SNI = os.getenv("RVS_SNI", "").strip()
|
||||
|
||||
WHISPER_MODEL = os.getenv("WHISPER_MODEL", "small")
|
||||
WHISPER_DEVICE = os.getenv("WHISPER_DEVICE", "cuda")
|
||||
@@ -876,9 +879,14 @@ async def run_loop(runner: WhisperRunner, sessions: SessionManager) -> None:
|
||||
scheme = "wss" if use_tls else "ws"
|
||||
url = f"{scheme}://{RVS_HOST}:{RVS_PORT}?token={RVS_TOKEN}"
|
||||
masked = url.replace(RVS_TOKEN, "***") if RVS_TOKEN else url
|
||||
connect_kwargs = {"ping_interval": 20, "ping_timeout": 10, "max_size": 50 * 1024 * 1024}
|
||||
if use_tls and RVS_SNI:
|
||||
import ssl
|
||||
connect_kwargs["ssl"] = ssl.create_default_context()
|
||||
connect_kwargs["server_hostname"] = RVS_SNI
|
||||
try:
|
||||
logger.info("Verbinde zu RVS: %s", masked)
|
||||
async with websockets.connect(url, ping_interval=20, ping_timeout=10, max_size=50 * 1024 * 1024) as ws:
|
||||
logger.info("Verbinde zu RVS: %s%s", masked, f" (SNI {RVS_SNI})" if (use_tls and RVS_SNI) else "")
|
||||
async with websockets.connect(url, **connect_kwargs) as ws:
|
||||
logger.info("RVS verbunden")
|
||||
retry_s = 2
|
||||
tls_fallback_tried = False
|
||||
|
||||
Reference in New Issue
Block a user