guildenstern/websocketserver

Search:
Group by:

Websocket server

see examples/websockettest.nim for a concrete example.

Types

WebsocketServerObj = object of HttpServerObj
  isclient* = false          ## If a `clientmaskkey` is given in initWebsocketServer, this is set to true
  upgradeCallback*: WsUpgradeCallback ## Optional, return true to accept, false to decline a websocket upgrade request
  afterUpgradeCallback*: WsAfterUpgradeCallback ## Optional, good for sending the very first websocket message to client
  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: [].}
Returns the body as a string copy. See also: getMessageView
proc getMessageview(ws: HttpContext): openArray[char] {....raises: [], tags: [],
    forbids: [].}
Returns the message without making an expensive string copy. Requires --experimental:views compiler switch.
proc handleWsRequest() {....gcsafe, nimcall, ...raises: [], tags: [RootEffect],
                         forbids: [].}
proc handleWsThreadInitialization(theserver: GuildenServer) {....raises: [],
    tags: [RootEffect], forbids: [].}
proc initWebsocketServer(theserver: WebsocketServer;
                         upgradecallback: WsUpgradeCallback;
                         afterupgradecallback: WsAfterUpgradeCallback;
                         onwsmessagecallback: WsMessageCallback;
                         loglevel = LogLevel.WARN;
                         clientmaskkey = "\x00\x00\x00\x00") {....raises: [],
    tags: [], forbids: [].}
proc isMessage(message: string): bool {....raises: [], tags: [], forbids: [].}
proc newWebsocketServer(upgrade: WsUpgradeCallback = nil;
                        afterupgrade: WsAfterUpgradeCallback = nil;
                        receive: WsMessageCallback;
                        close: OnCloseSocketCallback = nil;
                        loglevel = LogLevel.WARN): WebsocketServer {....raises: [],
    tags: [], forbids: [].}
proc newWebsocketServer(upgradecallback: WsUpgradeCallback;
                        afterupgradecallback: WsAfterUpgradeCallback;
                        onwsmessagecallback: WsMessageCallback;
    deprecatedOnclosesocketcallback: DeprecatedOnCloseSocketCallback;
                        loglevel = LogLevel.WARN): WebsocketServer {....raises: [],
    tags: [], forbids: [].}
This constructor is going to get deprecated. Please switch to the one that uses the new OnCloseSocketCallback.
proc send(theserver: WebsocketServer; delivery: ptr WsDelivery;
          failedsockets: var seq[SocketHandle]; timeoutsecs = 10;
          sleepmillisecs = 10) {....raises: [], tags: [RootEffect, TimeEffect],
                                 forbids: [].}
Sends a 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 sockets that failed and had to be closed in the failedsockets parameter.
proc send(theserver: WebsocketServer; delivery: ptr WsDelivery;
          timeoutsecs = 10; sleepmillisecs = 10): int {.discardable, ...raises: [],
    tags: [RootEffect, TimeEffect], forbids: [].}
proc send(theserver: WebsocketServer; socket: posix.SocketHandle;
          message: string; binary = false; timeoutsecs = 2; sleepmillisecs = 10): bool {.
    ...gcsafe, discardable, ...raises: [], tags: [RootEffect, TimeEffect], forbids: [].}
proc send(theserver: WebsocketServer; sockets: seq[posix.SocketHandle];
          message: string; binary = false; timeoutsecs = 10; sleepmillisecs = 10): bool {.
    discardable, ...raises: [], tags: [RootEffect, TimeEffect], forbids: [].}
proc send(theserver: WebsocketServer; sockets: seq[posix.SocketHandle];
          message: string; failedsockets: var seq[SocketHandle]; binary = false;
          timeoutsecs = 10; sleepmillisecs = 10) {....raises: [],
    tags: [RootEffect, TimeEffect], forbids: [].}
proc sendClose(theserver: WebsocketServer; socket: posix.SocketHandle;
               statuscode: int16 = 1000.int16; timeoutsecs = 1;
               sleepmillisecs = 10): bool {.discardable, ...raises: [],
    tags: [RootEffect, TimeEffect], forbids: [].}
Sends a close frame to the client, in sync with other possible deliveries going to the same socket from other threads. | statuscode: Available for the client. For semantics, see https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1 Returns whether the sending was succesful (and if not, you may want to just call closeSocket)

Templates

template ws(): untyped
shortcut for HttpContext(socketcontext)
template wsserver(): untyped
Casts the socketcontext.server into a WebsocketServer