xwh_hub – Mein aktueller Stand zum Projekt 2030
Hallo Freunde,
ich arbeite gerade intensiv an einer neuen Lösung. Es hat eine ganze Weile gedauert, alle möglichen Varianten durchzuspielen und schließlich eine Entscheidung zu treffen, wie wir das Projekt 2030 konkret angehen können.
Mein aktuelles Konzept („xwh_hub“):
FW/Harbour Database Server als Backend – gedacht als neuer Standard für DBF-Datenbanken
FiveWin ManageSoftware läuft direkt am Server, die bestehende Logik bleibt erhalten
FiveWin DBU zur weiteren Pflege der DBF-Tabellen
WebSocket als Transportschicht – läuft direkt auf den Sockets des Betriebssystems, es sind also keine zusätzlichen Bibliotheken notwendig. Das macht die Integration noch einfacher und stabiler.
Für mich steht fest: Dieser Weg ist der richtige, und ich hoffe, dass das vielleicht auch für den einen oder anderen von euch spannend sein könnte.
Ich werde dazu – um die Hauptliste nicht zu stören – alles Weitere hier im GERMAN FORUM posten.
Viele Grüße
Otto
Hallo Freunde,
ich arbeite gerade intensiv an einer neuen Lösung. Es hat eine ganze Weile gedauert, alle möglichen Varianten durchzuspielen und schließlich eine Entscheidung zu treffen, wie wir das Projekt 2030 konkret angehen können.
Mein aktuelles Konzept („xwh_hub“):
FW/Harbour Database Server als Backend – gedacht als neuer Standard für DBF-Datenbanken
FiveWin ManageSoftware läuft direkt am Server, die bestehende Logik bleibt erhalten
FiveWin DBU zur weiteren Pflege der DBF-Tabellen
WebSocket als Transportschicht – läuft direkt auf den Sockets des Betriebssystems, es sind also keine zusätzlichen Bibliotheken notwendig. Das macht die Integration noch einfacher und stabiler.
Für mich steht fest: Dieser Weg ist der richtige, und ich hoffe, dass das vielleicht auch für den einen oder anderen von euch spannend sein könnte.
Ich werde dazu – um die Hauptliste nicht zu stören – alles Weitere hier im GERMAN FORUM posten.
Viele Grüße
Otto
xwh_hub – Technische Referenz (aktueller Stand)
Laufzeit & Server
Lokaler HTTP-Server auf 127.0.0.1:9090 (Winsock2, C89, STARTHTTPSERVER).
Blocking-Accept-Loop mit:
kurzer SO_RCVTIMEO (Zombie-Clients),
/heartbeat-Erkennung via MSG_PEEK,
robustem Header/Body-Parsing inkl. Content-Length & \r\n\r\n/\n\n/\r\r,
Payload-Limit → 413 „Payload too large“,
SO_LINGER für Browser (Chrome/Firefox/Safari),
einheitliches JSON-Antwortgerüst via BuildAndSendJsonResponse/BuildJsonResponse.
Status/Version/Time/Hello (GET): /status, /version, /time, /hello.
WebSocket (serverseitige Basis)
Handshake implementiert (handle_websocket_upgrade): Berechnung Sec-WebSocket-Accept (SHA-1 + Base64 über Crypt32).
Aktuell kein Frame-Loop (d. h. noch kein kontinuierlicher WS-Datenaustausch) – Handshake-Baustein ist da.
Logging & Debug
Dateilog http_log.txt mit Zeitstempel + Zeilennummer (loglineEx, HLOG-Macro).
RAW-Request-Logging (deaktivierbar) nach vollständigem Empfang.
Debugging-Hilfen: DebugHash, DebugArray, ValToChar, logging().
Codepage/UTF-8
DEWIN/Windows-1252 aktiv: hb_cdpSelect("DEWIN"), hb_SetTermCP("DEWIN").
C-Helper:
ISVALIDUTF8, SAFEUTF8 (strippt harte Control-Chars),
CP1252TOUTF8 (1252→UTF-8 mit Mapping 0x80–0x9F).
Harbour-Wrapper: mySafeUtf8, xxxmy_AnsiToUtf8, my_AnsiToUtf8 (vereinfachte Filterung).
INI & Setup
INI-Zugriff via GetPrivateProfileStringA ⇒ GETPVPROFSTRING().
setup() lädt ZPlan.ini (Status 1..22) und baut Farbpalette aFarbe:
TXT/BG/PlanText/PDrucker,
NumToHexColor: numerisch → #RRGGBB.
Endpunkte (Router)
GET
/search?name=... → SearchName()
KUNDEN.DBF (Tag KU_NAME, SET SCOPE TO), liefert bis 200 Treffer: [{name, ort, plz}].
/hello → {status:"ok", message:"Hello works"}
/time → aktuelles Datum/Zeit.
/status | /version → {status:"ok", version:"1.0.0", timestamp:"..."}
POST (JSON)
/heartbeat → HANDLEHEARTBEAT()
{success:.T., type:"heartbeat", heartbeatLastModified:<unix>}
/getindexes → HANDLEGETINDEXES()
Öffnet DBF + zugehöriges CDX, liefert Tags: {"indexes":[[tag, key, for, bag], ...]}.
/readdbf → HANDLEREADDBF()
Paging/Scope/Index optional, felderspezifische oder alle Felder, immer "INDEX": RecNo().
Input:
{"databasePath":"X:\\xwhdaten\\DATAWIN\\KUNDEN.DBF","selectedIndex":"TAGNAME","indexTag":"MEYER","start":1,"end":100,"fields":["NAME","ORT"]}
Output:
{"success":true,"records":[{...}], "Struct":[["name","type","len","dec"], ...]}
/readdbfzplan → HANDLEREADDBF_ZPLAN()
Zeitraumschnitt (ANREISE < dEnd & ABREISE >= dStart), Farben serverseitig (aFarbe, f_Opt_fix()), inkl. BUCHUNGSNR.
Input:
{"databasePath":"...\\BELEGUNG.DBF","dateStart":"YYYY-MM-DD","dateEnd":"YYYY-MM-DD"}
Output:
{"success":true,"count":N,"records":[{"INDEX":123,"ZIMMERNR":"302","ANREISE":"YYYYMMDD","ABREISE":"YYYYMMDD","PLANNAME":"...","FIXBUCHUNG":"...","bgHex":"#RRGGBB","fgHex":"#RRGGBB","BUCHUNGSNR":4711}]}
/addrecord → HANDLEADDRECORD()
Insert mit DBRLOCK(), Typkonvertierung (D/N/L/C/M), Rollback bei Fehler.
Input:
{"databasePath":"...","fields":{"NAME":"...","DATUM":"YYYY-MM-DD",...}}
Output:
{"success":true,"recno":<n>}
/updaterecord → HANDLEEDITRECORD()
Schnelles Setzen eines Feldes (einzelne Spalte) für recordId. (Beispielpfad im Code kommentiert)
/updaterecordfields → HANDLEUPDATERECORD()
Atomare Feld-Updates mit Typkonvertierung (D→CToD, N→VAL).
Input:
{"databasePath":"...","recordId":123,"fields":{"NAME":"...","ANREISE":"YYYY-MM-DD"}}
/deleterecord → HANDLEDELETERECORD()
GOTO recordId + DBRLOCK() + DELETE.
/ziplanupdaterecord → HANDLE_ZIPLAN_EDITRECORD()
Konfliktprüfung Zimmerbelegung (Scopes/Index b_abreise, ordScope pro ZIMMERNR),
Datumskonvertierung (YMD→D.M.Y→CToD), Validierung ADR.DBF (Zimmer existent), HTTP-Status im JSON (200/400/404/409/423/500).
Output bei Konflikt:
{"success":false,"httpstatuscode":"409","status":"occupied","message":"...","zi_nr":"...","from":"dd.mm.yyyy","to":"dd.mm.yyyy"}
Output bei Erfolg:
{"success":true,"httpstatuscode":"200","status":"free", ...}
DB-Zugriff & Sperren
SHARED-Öffnen, DBRLOCK()/FLOCK() wo nötig, sauberes DBUNLOCK()/CLOSE.
Fehlerpfade geben konsistente JSON-Fehlermeldungen zurück (Open/Lock/NotFound/Invalid Input).
Zimmerplan-Farblogik
f_Opt_fix(cFixbuchung) mappt "1".."M", "T", "W", "7", "9" → Index 1..22.
aFarbe[idx] liefert serverseitig bgHex/fgHex (und PlanText/PDrucker).
Initialisierung
PrgInit: Century, Epoch, Deleted ON, Exclusive OFF, Date German, rddSetDefault("DBFCDX"), DESCEND.
Quick Examples (für Tests)
POST /readdbf
POST /readdbf HTTP/1.1
Content-Type: application/json
{
"databasePath": "X:\\xwhdaten\\DATAWIN\\KUNDEN.DBF",
"selectedIndex": "KU_NAME",
"indexTag": "MEYER",
"start": 1,
"end": 50,
"fields": ["NAME","ORT","PLZ"]
}
POST /readdbfzplan
POST /readdbfzplan HTTP/1.1
Content-Type: application/json
{
"databasePath": "X:\\xwhdaten\\DATAWIN\\BELEGUNG.DBF",
"dateStart": "2025-09-01",
"dateEnd": "2025-09-30"
}
POST /addrecord
POST /addrecord HTTP/1.1
Content-Type: application/json
{
"databasePath": "X:\\xwhdaten\\DATAWIN\\KUNDEN.DBF",
"fields": {
"NAME": "Muster GmbH",
"ORT": "Sillian",
"PLZ": "9920",
"ANLAGEDAT": "2025-09-08"
}
}