Betrieb
Das Protokoll allein genügt nicht. Ein Steuerprogramm muss die Anzeige zuerst finden, die Verbindung gehört abgesichert, und was auf einem öffentlich stehenden Bildschirm erscheinen darf, bestimmt nicht der Gestaltungswille, sondern der Datenschutz.
Die Kenndatei#
Eine Anzeige legt neben ihrer ausführbaren Datei eine Kenndatei
<programmname>.dat ab: UTF-8, je Zeile SCHLÜSSEL=Wert, Zeilen mit # sind
Kommentar. Sie wird beim Start geschrieben und atomar ersetzt (schreiben,
umbenennen).
APP_NAME=anzeigeprogramm
APP_VERSION=0.2.0
PROTOCOL=SBC-AP
PROTOCOL_VERSION=1
CAPS=session,idle,message,venue,monitor,config,lifecycle
HOST=127.0.0.1
PORT=7207
PID=4711
MUTEX=Anzeige eines Herstellers
EXE_PATH=c:\programme\anzeige\anzeige.exe
CONFIG_PATH=c:\programme\anzeige\anzeige.ini
STARTED_UNIX_UTC=1786819200
Pflicht sind APP_NAME, PROTOCOL, PROTOCOL_VERSION, HOST, PORT und
PID. CAPS erspart das Verbinden, wenn nur zu klären ist, ob ein Bereich
überhaupt vorhanden ist.
Läuft die Anzeige?#
Das beantwortet nicht das Vorhandensein der Kenndatei, sondern diese Prüfung, in dieser Reihenfolge:
- Unter Windows: der benannte Mutex aus
MUTEX. Das eigene Handle ist sofort wieder zu schließen – solange es offen ist, hält es den Namen künstlich am Leben, und eine längst beendete Anzeige gälte weiterhin als laufend. - Sonst: die Prozesskennung aus
PID. - Ersatzweise:
ping.
Schlägt die Prüfung fehl, sind HOST und PORT trotzdem gültig – sie sagen,
wo die Anzeige nach ihrem Start zu erreichen sein wird. PID und
STARTED_UNIX_UTC beziehen sich dagegen immer auf den letzten Lauf und sind
danach bedeutungslos.
Absicherung der Verbindung#
Vorgabe ist die Bindung an 127.0.0.1: Dann erreicht die Anzeige nur, wer
ohnehin schon an diesem Rechner arbeitet. Für den Regelfall – Anzeige und
Steuerprogramm auf demselben Rechner – ist damit alles gesagt.
Steht die Anzeige an einem anderen Rechner im örtlichen Netz der Bücherei, etwa als Kleinrechner hinter dem Bildschirm, muss sie die Anmeldung verlangen:
{"v":1,"cmd":"hello","auth":{"token":"…"}}
Fehlt der Wert oder stimmt er nicht, beantwortet die Anzeige jeden Auftrag außer
hello und ping mit 401 unauthorized. Das Geheimnis wird außerhalb des
Protokolls vereinbart und in beiden Programmen eingetragen.
Nicht ins Internet#
Die Schnittstelle gehört nicht ins Internet – auch nicht mit Token. Sie überträgt im Klartext und ist für kurze Wege innerhalb der Bücherei gedacht, nicht für einen öffentlich erreichbaren Dienst.
Wer eine Anzeige an einem entfernten Standort bedienen will, verbindet die beiden Netze (VPN) und behandelt die Anzeige danach wie eine im örtlichen Netz. Eine Portweiterleitung im Router ist kein Ersatz dafür.
Datenschutz#
Eine Kundenanzeige steht öffentlich, und wer daneben steht, liest mit. Daher:
- Kein Klarname, keine Anschrift, keine vollständige E-Mail-Adresse.
customer.maskedträgt Initialen oder Ähnliches; E-Mail-Adressen werden gekürzt (b***[at]example.org). - Die Lesernummer ist ausdrücklich zulässig (
customer.number). Sie wird an der Theke ohnehin laut genannt, benennt für sich genommen niemanden und hilft beim Abgleich mit dem Ausweis. - Medientitel benennen, was jemand liest, und sind damit besonders
schutzwürdig. Eine Anzeige, die
itemsauswertet, soll Titel nur zeigen, solange die Person davorsteht, und sie beim Ende der Sitzung verwerfen. Eine Anzeige, die auf Titel verzichtet und nur zählt, ist ausdrücklich konform. - Verlässt der Arbeitsplatz die Aufsicht – Sperrbildschirm, Pause –, sendet das
Steuerprogramm
idle.show, damit nichts stehen bleibt. - Die Anzeige speichert Sitzungsangaben nicht dauerhaft.
Mitschnitt#
Beide Seiten sollen einen abschaltbaren Mitschnitt anbieten, der jede eingehende Zeile und jede Antwort mit Zeitstempel festhält. Er ist das einzige Werkzeug, mit dem sich ein Zusammenspiel zweier Hersteller nachvollziehen lässt.
Weil im Mitschnitt personenbezogene Angaben stehen, ist er standardmäßig ausgeschaltet, wird auf dem Gerät selbst abgelegt und in seinem Umfang begrenzt.
Pflichten beider Seiten#
Eine Anzeige
- übergeht unbekannte Felder,
- beantwortet jeden Auftrag genau einmal und schließt nie ohne Antwort,
- beantwortet
pingauch dann, wenn sie beschäftigt ist, - gibt in
capswahrheitsgemäß an, was sie versteht.
Ein Steuerprogramm
- wertet
capsaus und verschmerzt fehlende Bereiche, - behandelt
404und501als Auskunft, nicht als Störung, - arbeitet mit kurzem Zeitlimit und wenigen Wiederholungen,
- hält den Betrieb an der Theke nie an, weil eine Anzeige nicht antwortet,
- meldet dem Personal höchstens beiläufig, dass die Anzeige fehlt.
Die eigene Umsetzung prüfen#
Der folgende Client genügt, um eine Anzeige vollständig durchzuspielen – er braucht nichts außer Python.
#!/usr/bin/env python3
"""Kleinster vollständiger SBC-AP-Client. Aufruf: sbcap.py [port]"""
import json, socket, sys
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 7207
def call(cmd, **felder):
auftrag = {"v": 1, "cmd": cmd, **felder}
with socket.create_connection(("127.0.0.1", PORT), timeout=5) as s:
s.sendall((json.dumps(auftrag, ensure_ascii=False) + "\n").encode("utf-8"))
s.shutdown(socket.SHUT_WR)
antwort = b""
while b"\n" not in antwort:
teil = s.recv(4096)
if not teil:
break
antwort += teil
return json.loads(antwort.decode("utf-8").strip())
print(call("hello", client={"name": "sbcap.py", "version": "1.0"}))
print(call("session.open", lang="de",
customer={"masked": "B. L.", "number": "10245"},
counters={"loans": 5, "holds": 1, "holds_ready": 1}))
print(call("session.update",
items=[{"kind": "loan", "title": "Der Schwarm", "due": "2026-08-29"}],
counters={"loans": 6, "borrowed": 1}))
print(call("session.close", delay=1, seconds=10,
dates={"due_next": "2026-08-29", "next_open": "2026-08-18"}))