Types
ProtocolError = object of Exception
Opcode = enum Cont = 0x00000000, ## Continued Frame (when the previous was fin = 0) Text = 0x00000001, ## Text frames need to be valid UTF-8 Binary = 0x00000002, ## Binary frames can be anything. Close = 0x00000008, ## Socket is being closed by the remote, or we intend to close it. Ping = 0x00000009, ## Ping Pong = 0x0000000A ## Pong. Needs to echo back the app data in ping.
Frame = tuple[fin: bool, ## Last frame in current packet. rsv1: bool, ## Extension data: negotiated in http prequel, or 0. rsv2: bool, ## Extension data: negotiated in http prequel, or 0. rsv3: bool, ## Extension data: negotiated in http prequel, or 0. masked: bool, ## If the frame was received masked/is supposed to be masked. ## Do not mask data yourself. opcode: Opcode, ## The opcode of this frame. data: string]
- A frame read off the netlayer.
SocketKind = enum Client, Server
AsyncWebSocket = ref AsyncWebSocketObj
Procs
proc makeFrame(f: Frame): string {.
raises: [Exception], tags: [WriteIOEffect, TimeEffect, ReadIOEffect].}- Generate valid websocket frame data, ready to be sent over the wire. This is useful for rolling your own impl, for example with AsyncHttpServer
proc makeFrame(opcode: Opcode; data: string; masked: bool): string {.
raises: [Exception], tags: [WriteIOEffect, TimeEffect, ReadIOEffect].}- A convenience shorthand.
proc recvFrame(ws: AsyncSocket): Future[Frame] {.
raises: [FutureError], tags: [RootEffect].}-
Read a full frame off the given socket.
You probably want to use the higher-level variant, readData.
proc readData(ws: AsyncSocket; isClientSocket: bool): Future[ tuple[opcode: Opcode, data: string]] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}-
Reads reassembled data off the websocket and give you joined frame data.
Note: You will still see control frames, but they are all handled for you (Ping/Pong, Cont, Close, and so on).
The only ones you need to care about are Opcode.Text and Opcode.Binary, the so-called application frames.
As per the websocket specifications, all clients need to mask their responses. It is up to you to to set isClientSocket with a proper value, depending on if you are reading from a server or client socket.
Will raise IOError when the socket disconnects and ProtocolError on any websocket-related issues.
proc sendText(ws: AsyncSocket; p: string; masked: bool): Future[void] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}- Sends text data. Will only return after all data has been sent out.
proc sendBinary(ws: AsyncSocket; p: string; masked: bool): Future[void] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}- Sends binary data. Will only return after all data has been sent out.
proc sendPing(ws: AsyncSocket; masked: bool; token: string = ""): Future[void] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}- Sends a WS ping message. Will generate a suitable token if you do not provide one.
proc readData(ws: AsyncWebSocket): Future[tuple[opcode: Opcode, data: string]] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}-
Reads reassembled data off the websocket and give you joined frame data.
Note: You will still see control frames, but they are all handled for you (Ping/Pong, Cont, Close, and so on).
The only ones you need to care about are Opcode.Text and Opcode.Binary, the so-called application frames.
Will raise IOError when the socket disconnects and ProtocolError on any websocket-related issues.
proc sendText(ws: AsyncWebSocket; p: string; masked: bool): Future[void] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}- Sends text data. Will only return after all data has been sent out.
proc sendBinary(ws: AsyncWebSocket; p: string; masked: bool): Future[void] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}- Sends binary data. Will only return after all data has been sent out.
proc sendPing(ws: AsyncWebSocket; masked: bool; token: string = ""): Future[void] {.
raises: [FutureError], tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect].}- Sends a WS ping message. Will generate a suitable token if you do not provide one.
proc closeWebsocket(ws: AsyncSocket; code = 0; reason = ""): Future[void] {.
raises: [FutureError], tags: [WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect].}- Closes the socket.
proc close(ws: AsyncWebSocket; code = 0; reason = ""): Future[void] {.
raises: [FutureError], tags: [WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect].}- Closes the socket.