guildenstern/websocketserver

Websocket server

see examples/websockettest.nim for a concrete example.

Types

WebsocketServer = ref object of HttpServer
  upgradeCallback*: WsUpgradeCallback ## Return true to accept, false to decline
  afterUpgradeCallback*: WsAfterUpgradeCallback ## Optional, good for initialization purposes
  messageCallback*: WsMessageCallback ## Triggered when a message is received. Streaming reads are not supported: message length must be shorter than buffersize.
  
WsAfterUpgradeCallback = proc () {....gcsafe, nimcall, ...raises: [].}
WsDelivery = tuple[sockets: seq[posix.SocketHandle], message: ptr string,
                   binary: bool, states: seq[State]]
send takes pointer to this as parameter.

sockets: the websockets that should receive this message
message: the message to send (empty message sends a Pong)
binary: whether the message contains bytes or chars

WsMessageCallback = proc () {....gcsafe, nimcall, ...raises: [].}
WsUpgradeCallback = proc (): bool {....gcsafe, nimcall, ...raises: [].}

Procs

proc getMessage(): string {....raises: [], tags: [], forbids: [].}
proc isMessage(message: string): bool {....raises: [], tags: [], forbids: [].}
proc newWebsocketServer(upgradecallback: WsUpgradeCallback;
                        afterupgradecallback: WsAfterUpgradeCallback;
                        onwsmessagecallback: WsMessageCallback;
                        onclosesocketcallback: OnCloseSocketCallback;
                        loglevel = LogLevel.WARN): WebsocketServer {....raises: [],
    tags: [], forbids: [].}
proc send(server: GuildenServer; delivery: ptr WsDelivery; timeoutsecs = 10;
          sleepmillisecs = 10): int {.discardable, ...raises: [],
                                      tags: [TimeEffect, RootEffect],
                                      forbids: [].}
Sends message to multiple websockets at once. Uses non-blocking I/O so that slow receivers do not slow down fast receivers.

Can be called from multiple threads in parallel.
timeoutsecs: a timeout after which sending is given up and all sockets with messages in-flight are closed
sleepmillisecs: if all in-flight receivers are blocking, will suspend for (sleepmillisecs * in-flight receiver count) milliseconds

Returns amount of websockets that had to be closed
proc send(server: GuildenServer; socket: posix.SocketHandle; message: string;
          timeoutsecs = 2; sleepmillisecs = 10): bool {.discardable, ...raises: [],
    tags: [TimeEffect, RootEffect], forbids: [].}
proc send(server: GuildenServer; sockets: seq[posix.SocketHandle];
          message: string; timeoutsecs = 10; sleepmillisecs = 10): bool {.
    discardable, ...raises: [], tags: [TimeEffect, RootEffect], forbids: [].}

Templates

template ws(): untyped
Alias for http socketcontext
template wsserver(): untyped
Casts the socketcontext.socketdata.server into a WebsocketServer