Zum Inhalt springen

WebSocket-Client

WebSocket-Client für bidirektionale Echtzeit-Kommunikation mit Servern.

local websocket = require("websocket")
local client, err = websocket.connect("wss://api.example.com/ws")
if err then
return nil, err
end
local client, err = websocket.connect("wss://api.example.com/ws", {
headers = {
["Authorization"] = "Bearer " .. token
},
protocols = {"graphql-ws"},
dial_timeout = "10s",
read_timeout = "30s",
compression = websocket.COMPRESSION.CONTEXT_TAKEOVER
})
ParameterTypBeschreibung
urlstringWebSocket-URL (ws:// oder wss://)
optionstableVerbindungsoptionen (optional)

Gibt zurück: Client, error

OptionTypBeschreibung
headerstableHTTP-Header für Handshake
protocolstableWebSocket-Subprotokolle
dial_timeoutnumber/stringVerbindungs-Timeout (ms oder “5s”)
read_timeoutnumber/stringLese-Timeout
write_timeoutnumber/stringSchreib-Timeout
compressionnumberKomprimierungsmodus (siehe Konstanten)
compression_thresholdnumberMin. Größe zum Komprimieren (0-100MB)
read_limitnumberMax. Nachrichtengröße (0-128MB)
channel_capacitynumberEmpfangs-Channel-Puffer (1-10000)

Timeout-Format: Zahlen sind Millisekunden, Strings verwenden Go-Dauerformat (“5s”, “1m”).

local ok, err = client:send("Hello, Server!")
if err then
return nil, err
end
-- JSON senden
client:send(json.encode({
type = "subscribe",
channel = "orders"
}))
client:send(binary_data, websocket.BINARY)
ParameterTypBeschreibung
datastringNachrichteninhalt
typenumberwebsocket.TEXT (1) oder websocket.BINARY (2)

Gibt zurück: boolean, error

client:ping()

Gibt zurück: boolean, error

Die channel()-Methode gibt einen Channel zum Empfangen von Nachrichten zurück. receive() ist ein Alias für channel(). Funktioniert mit channel.select für Multiplexing.

local ch = client:channel()
local msg, ok = ch:receive()
if ok then
print("Type:", msg.type) -- "text" oder "binary"
print("Data:", msg.data)
end
local ch = client:channel()
while true do
local msg, ok = ch:receive()
if not ok then
break -- Verbindung geschlossen
end
if msg.type == "text" then
local data = json.decode(msg.data)
handle_message(data)
end
end
local ch = client:channel()
local timeout = time.after("30s")
while true do
local r = channel.select {
ch:case_receive(),
timeout:case_receive()
}
if r.channel == timeout then
client:ping() -- Keep-Alive
timeout = time.after("30s")
else
local data = json.decode(r.value.data)
process(data)
end
end
FeldTypBeschreibung
typestring"text" oder "binary"
datastring?Nachrichteninhalt (nil bei unbekannten Payload-Typen)
-- Normales Schließen (Code 1000)
client:close()
-- Mit Code und Grund
client:close(websocket.CLOSE_CODES.NORMAL, "Session ended")
-- Fehler-Schließen
client:close(websocket.CLOSE_CODES.INTERNAL_ERROR, "Processing failed")
ParameterTypBeschreibung
codenumberSchließ-Code (1000-4999), Standard 1000
reasonstringSchließgrund (optional)

Gibt zurück: boolean, error

-- Numerisch (für send)
websocket.TEXT -- 1
websocket.BINARY -- 2
-- String (empfangener Nachrichtentyp-Feld)
websocket.TYPE_TEXT -- "text"
websocket.TYPE_BINARY -- "binary"
websocket.TYPE_PING -- "ping"
websocket.TYPE_PONG -- "pong"
websocket.TYPE_CLOSE -- "close"
websocket.COMPRESSION.DISABLED -- 0 (keine Komprimierung)
websocket.COMPRESSION.CONTEXT_TAKEOVER -- 1 (gleitendes Fenster)
websocket.COMPRESSION.NO_CONTEXT -- 2 (pro Nachricht)
KonstanteCodeBeschreibung
NORMAL1000Normales Schließen
GOING_AWAY1001Server fährt herunter
PROTOCOL_ERROR1002Protokollfehler
UNSUPPORTED_DATA1003Nicht unterstützter Datentyp
RESERVED1004Reserviert
NO_STATUS1005Kein Status empfangen
ABNORMAL_CLOSURE1006Verbindung verloren
INVALID_PAYLOAD1007Ungültiger Frame-Payload
POLICY_VIOLATION1008Richtlinienverletzung
MESSAGE_TOO_BIG1009Nachricht zu groß
MANDATORY_EXTENSION1010Erforderliche Erweiterung nicht ausgehandelt
INTERNAL_ERROR1011Serverfehler
SERVICE_RESTART1012Server startet neu
TRY_AGAIN_LATER1013Server überlastet
BAD_GATEWAY1014Gateway-Fehler
TLS_HANDSHAKE1015TLS-Handshake fehlgeschlagen
client:close(websocket.CLOSE_CODES.NORMAL, "Done")
local function connect_chat(room_id, on_message)
local client, err = websocket.connect("wss://chat.example.com/ws", {
headers = {["Authorization"] = "Bearer " .. token}
})
if err then
return nil, err
end
-- Raum beitreten
client:send(json.encode({
type = "join",
room = room_id
}))
-- Nachrichtenschleife
local ch = client:channel()
while true do
local msg, ok = ch:receive()
if not ok then break end
local data = json.decode(msg.data)
on_message(data)
end
client:close()
end
local client = websocket.connect("wss://stream.example.com/prices")
client:send(json.encode({
action = "subscribe",
symbols = {"BTC-USD", "ETH-USD"}
}))
local ch = client:channel()
local heartbeat = time.after("30s")
while true do
local r = channel.select {
ch:case_receive(),
heartbeat:case_receive()
}
if r.channel == heartbeat then
client:ping()
heartbeat = time.after("30s")
elseif not r.ok then
break -- Verbindung geschlossen
else
local price = json.decode(r.value.data)
update_price(price.symbol, price.value)
end
end
client:close()

WebSocket-Verbindungen unterliegen der Sicherheitsrichtlinienauswertung.

AktionRessourceBeschreibung
websocket.connect-WebSocket-Verbindungen erlauben/verweigern
websocket.connect.urlURLVerbindungen zu bestimmten URLs erlauben/verweigern

Siehe Sicherheitsmodell für Richtlinienkonfiguration.

BedingungArtWiederholbar
Verbindungen deaktivierterrors.PERMISSION_DENIEDnein
URL nicht erlaubterrors.PERMISSION_DENIEDnein
Kein Kontexterrors.INTERNALnein
Verbindung fehlgeschlagenerrors.INTERNALja
Ungültige Verbindungs-IDerrors.INTERNALnein
local client, err = websocket.connect(url)
if err then
if errors.is(err, errors.PERMISSION_DENIED) then
print("Access denied:", err:message())
elseif err:retryable() then
print("Temporary error:", err:message())
end
return nil, err
end

Siehe Fehlerbehandlung für die Arbeit mit Fehlern.