websocket_actor/src/websocket_actor.nim

56 lines
1.7 KiB
Nim

# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, json]
import preserves, preserves/jsonhooks
import syndicate
import ws
type
Args* {.preservesDictionary.} = object
dataspace: Cap
url: string
SendJson* {.preservesRecord: "send".} = object
data: JsonNode
RecvJson* {.preservesRecord: "recv".} = object
data: JsonNode
runActor("websocket-json-actor") do (root: Cap; turn: var Turn):
connectStdio(root, turn)
during(turn, root, ?Args) do (ds: Cap, url: string):
let facet = turn.facet
var
ws: WebSocket
connectedHandle: Handle
newWebSocket(url).addCallback(turn) do (turn: var Turn; sock: WebSocket):
ws = sock
let connectedHandle = publish(turn, ds, initRecord("connected", url.toPreserve))
var fut: Future[(Opcode, string)]
proc recvMessage() {.gcsafe.} =
fut = receivePacket ws
addCallback(fut, facet) do (turn: var Turn):
let (opcode, data) = read fut
case opcode
of Text:
message(turn, ds,
RecvJson(data: data.parseJson))
of Binary:
message(turn, ds,
initRecord("recv", cast[seq[byte]](data).toPreserve))
of Ping:
asyncCheck(turn, ws.send(data, Pong))
of Pong, Cont:
discard
of Close:
retract(turn, connectedHandle)
stderr.writeLine "closed connection with ", url
stop(turn)
return
recvMessage()
recvMessage()
onMessage(turn, ds, ?SendJson) do (data: JsonNode):
asyncCheck(turn, ws.send($data, Text))
do:
close(ws)