app.websocket - WebSocket API
WebSocket client for real-time bidirectional communication.
Requires: macOS 10.15+ (returns an error on older systems) Permission: Requires
websocketdeclared in the manifest (L1 standard)
Methods
app.websocket.connect(url, config?)
Connects to a WebSocket server.
Parameters:
url(string) - WebSocket URL (ws:// or wss://)config(table, optional):headers(table, optional) - Custom request headersonMessage(function, optional) - Message callbackfunction(id, data, type)id(string) - Connection IDdata(string) - Message content (base64-encoded for binary type)type(string) -"text"or"binary"
onClose(function, optional) - Close callbackfunction(id, code, reason)onError(function, optional) - Error callbackfunction(id, message)
Returns: string, error - Connection ID
local id, err = app.websocket.connect("wss://echo.websocket.org", {
headers = {
["Authorization"] = "Bearer token123"
},
onMessage = function(id, data, type)
app.log.info("Received message: " .. data)
end,
onClose = function(id, code, reason)
app.log.info("Connection closed: " .. code)
end,
onError = function(id, msg)
app.log.error("WebSocket error: " .. msg)
end
})
app.websocket.send(id, data, options?)
Sends a message.
Parameters:
id(string) - Connection IDdata(string) - Data to send (must be base64-encoded for binary type)options(table, optional):type(string, optional) -"text"(default) or"binary"
Returns: boolean, error
-- Send text
local ok, err = app.websocket.send(id, "Hello, Server!")
-- Send JSON
local ok, err = app.websocket.send(id, app.json.stringify({
action = "subscribe",
channel = "updates"
}))
-- Send binary data (base64-encoded)
local ok, err = app.websocket.send(id, base64Data, {type = "binary"})
app.websocket.close(id, options?)
Closes a connection.
Parameters:
id(string) - Connection IDoptions(table, optional):code(number, optional) - Close status code (default 1000)reason(string, optional) - Close reason
Returns: boolean, error
local ok, err = app.websocket.close(id)
-- Specify close code and reason
local ok, err = app.websocket.close(id, {code = 1001, reason = "Going away"})
app.websocket.closeAll()
Closes all connections.
Returns: boolean
app.websocket.closeAll()
app.websocket.list()
Lists all active connections.
Returns: array - Array of connection info
local connections = app.websocket.list()
for _, conn in ipairs(connections) do
app.log.info(string.format("ID: %s, URL: %s, State: %s",
conn.id, conn.url, conn.state))
end
Connection states (state): "connecting" | "open" | "closing" | "closed"
Examples
Real-time chat
function MyPlugin:handleChat(context)
local ws, err = app.websocket.connect("wss://chat.example.com/ws", {
onMessage = function(id, data, type)
local msg = app.json.parse(data)
if msg and msg.text then
app.notification.show("New Message", msg.text)
end
end,
onError = function(id, msg)
app.notification.show("Connection Error", msg)
end
})
if not ws then
app.dialog.alert({title = "Error", message = err})
return
end
-- Send a message
app.websocket.send(ws, app.json.stringify({
type = "message",
text = "Hello from iRightMenu!"
}))
end
File change monitoring
function MyPlugin:init()
self.wsId = nil
end
function MyPlugin:handleStartWatch(context)
if self.wsId then
app.websocket.close(self.wsId)
end
self.wsId = app.websocket.connect("ws://localhost:8080/watch", {
onMessage = function(id, data)
local event = app.json.parse(data)
if event and event.type == "change" then
app.notification.show("File Changed", event.path)
end
end,
onClose = function(id, code, reason)
self.wsId = nil
app.log.info("Monitoring stopped")
end
})
end
function MyPlugin:cleanup()
if self.wsId then
app.websocket.close(self.wsId)
end
end
Notes
- macOS version: Requires macOS 10.15+; all methods return an error on older versions
- Connection limit: Each plugin can have up to 10 concurrent connections
- Binary data: Binary data is sent and received using base64 encoding
- Resource cleanup: All connections are automatically closed when the plugin is unloaded; you can also manually call
closeAll()