guildenstern/guildenserver

Search:
Group by:

GuildenServer is the abstract base class for creating server components. The three concrete server implementations that currently ship with GuildenStern are guildenstern/httpserver, guildenstern/websocketserver and guildenstern/multipartserver. One server is associated with one TCP port, use your internet-facing reverse proxy to route traffic to different servers.

GuildenServer itself mainly acts as the glue between everything else, offering set of callback hooks for others to fill in.

In addition to GuildenServer, this module also defines SocketContext, which is a container for data of one request in flight, available as the global socketcontext threadvar. SocketContext is inheritable, so concrete servers may add properties to it.

To see how to use GuildenStern in practice, consult the various practical examples in the examples folder.

Types

CloseSocketCallback = proc (server: GuildenServer; socket: SocketHandle;
                            cause: SocketCloseCause; msg: string) {....gcsafe,
    nimcall, ...raises: [].}
DeprecatedOnCloseSocketCallback {....deprecated: "use OnCloseSocketCallback".} = proc (
    socketdata: ptr SocketData; cause: SocketCloseCause; msg: string) {....gcsafe,
    nimcall, ...raises: [].}
Deprecated: use OnCloseSocketCallback
GetFlagsCallback = proc (server: GuildenServer; socket: SocketHandle): int {.
    nimcall, ...gcsafe, raises: [].}
GuildenServerObj {.inheritable.} = object
  port*: uint16
  thread*: Thread[GuildenServer]
  id*: int
  name*: string
  logCallback*: LogCallback
  loglevel*: LogLevel
  started*: bool
  internalThreadInitializationCallback*: ThreadInitializerCallback
  threadInitializerCallback*: ThreadInitializerCallback
  threadFinalizerCallback*: ThreadFinalizerCallback
  handlerCallback*: HandlerCallback
  suspendCallback*: SuspendCallback
  closeSocketCallback*: CloseSocketCallback
  onCloseSocketCallback*: OnCloseSocketCallback
  deprecatedOnCloseSocketCallback*: DeprecatedOnCloseSocketCallback
  getFlagsCallback*: GetFlagsCallback
  setFlagsCallback*: SetFlagsCallback
HandlerCallback = proc () {.nimcall, ...gcsafe, raises: [].}
LogCallback = proc (loglevel: LogLevel; source: string; message: string) {.
    ...gcsafe, nimcall, ...raises: [].}
LogLevel = enum
  TRACE, DEBUG, INFO, NOTICE, WARN, ERROR, FATAL, NONE
OnCloseSocketCallback = proc (server: GuildenServer; socket: SocketHandle;
                              cause: SocketCloseCause; msg: string) {....gcsafe,
    nimcall, ...raises: [].}
The msg parameter may contain furher info about the cause. For example, in case of websocket ClosedByClient, msg contains the status code.]#
SetFlagsCallback = proc (server: GuildenServer; socket: SocketHandle;
                         newflags: int): bool {.nimcall, ...gcsafe, raises: [].}
SocketCloseCause = enum
  EFault = -10000,          ## Memory corruption bug
  Excepted = -1000,         ## A Nim exception happened
  CloseCalled,              ## Use this, when the server (your code) closes a socket
  AlreadyClosed,            ## Another thread has closed the socket
  ClosedbyClient,           ## Client closed the connection
  ConnectionLost,           ## TCP/IP connection was dropped
  TimedOut,                 ## Client did not send/receive all expected data
  ProtocolViolated,         ## Client was sending garbage
  NetErrored,               ## Some operating system level error happened
  SecurityThreatened,       ## Use this, when you decide to close socket for security reasons 
  DontClose                  ## Internal flag
Parameter in close callbacks.
SocketContext {.inheritable.} = ref object
  server*: GuildenServer
  socket*: SocketHandle
  customdata*: pointer
SocketData {....deprecated.} = object
  server*: GuildenServer
  socket*: SocketHandle
Deprecated
SuspendCallback = proc (server: GuildenServer; sleepmillisecs: int) {.nimcall,
    ...gcsafe, raises: [].}
ThreadFinalizerCallback = proc () {.nimcall, ...gcsafe, raises: [].}
ThreadInitializerCallback = proc (theserver: GuildenServer) {.nimcall, ...gcsafe,
    raises: [].}

Vars

shutdownCallbacks: seq[proc () {.nimcall, ...gcsafe, raises: [].}]
shuttingdown = false
Global variable that all code is expected to observe and abide to (check this inside your loops every now and then...).
socketcontext {.threadvar.}: SocketContext

Procs

proc `$`(x: SocketHandle): string {.inline, ...raises: [], tags: [], forbids: [].}
proc closeOtherSocket(server: GuildenServer; socket: posix.SocketHandle;
                      cause: SocketCloseCause = CloseCalled; msg: string = "") {.
    ...deprecated: "just use closeSocket", gcsafe, nimcall, ...raises: [],
    tags: [RootEffect], forbids: [].}
Deprecated: just use closeSocket
proc closeSocket(cause = CloseCalled; msg = "") {....raises: [],
    tags: [RootEffect], forbids: [].}
Call this to close the current socket connection.
proc closeSocket(server: GuildenServer; socket: SocketHandle;
                 cause = CloseCalled; msg = "") {....gcsafe, nimcall, ...raises: [],
    tags: [RootEffect], forbids: [].}
Call this to close any socket connection.
func epollSupported(): bool {....raises: [], tags: [], forbids: [].}
proc getFlags(server: GuildenServer; socket: posix.SocketHandle): int {.
    ...raises: [], tags: [RootEffect], forbids: [].}
proc handleRead(theserver: GuildenServer; socket: SocketHandle;
                customdata: pointer) {....raises: [], tags: [RootEffect],
                                       forbids: [].}
proc initialize(server: GuildenServer; loglevel: LogLevel) {....raises: [],
    tags: [], forbids: [].}
proc initializeThread(server: GuildenServer) {....raises: [], tags: [RootEffect],
    forbids: [].}
proc setFlags(server: GuildenServer; socket: posix.SocketHandle; flags: int): bool {.
    ...raises: [], tags: [RootEffect], forbids: [].}
proc shutdown() {....raises: [], tags: [RootEffect], forbids: [].}
Sets shuttingdown to true and signals dispatcher loops to cease operation.
proc socketdata(sc: SocketContext): SocketContext {.
    ...deprecated: "Use socketcontext directly", raises: [], tags: [], forbids: [].}
Deprecated: Use socketcontext directly
proc suspend(server: GuildenServer; sleepmillisecs: int) {.inline, ...raises: [],
    tags: [RootEffect], forbids: [].}
proc suspend(sleepmillisecs: int) {....deprecated: "use suspend that takes server as parameter",
                                    raises: [], tags: [TimeEffect], forbids: [].}
Deprecated: use suspend that takes server as parameter

Templates

template log(theserver: GuildenServer; level: LogLevel; message: string)
Calls logCallback, if it set. By default, the callback is set to echo the message, if level is same or higher than server's loglevel.
template log(theserver: GuildenServer; level: LogLevel; source: string;
             message: string)
Calls logCallback, if it set. By default, the callback is set to echo the message, if level is same or higher than server's loglevel.
template thesocket(): untyped
Global shortcut for accessing socketcontext.socket