(net server) - Simple server framework

Library (net server)

This library provides simple server framework.

Following example describes how to write a simple echo server with the APIs this library provides.

(import (net server) (sagittarius socket))

(define (handler server socket)
  ;; echo message is limited to 255 bytes in this example
  (let ((r (socket-recv socket 255)))
    ;; socket will be closed by the framework
    (socket-send socket r)))

(define server (make-simple-server "5000" handler))

(server-start! server)

Above example creates only one thread and if there are more than one connection, then the latter one needs to wait until first one is done. The library also provides mult threading server. Following example describes how to make multi threading server.

(import (net server) (sagittarius socket))

;; specifies maximum thread number
(define server-config (make-server-config :max-thread 5))

(define (handler server socket)
  (let ((r (socket-recv socket 255)))
    ;; socket will be closed by the framework
    (socket-send socket r)))

(define server (make-simple-server "5000" handler :config server-config))

(server-start! server)

If the server gets more than 5 connection simultaneously, then it tries to wait until one of the connection's task finishes. If it doesn't finish in time, then connection will be refused.

If clients keep the connection but server wants to handle requests more than configured thread number, then specify non-blocking? keyword argument with #t.

(import (net server) (sagittarius socket))

;; specifies maximum thread number
(define server-config (make-server-config :max-thread 5 :non-blocking? #t))

(define (handler server socket)
  (let ((r (socket-recv socket 255)))
    (if (eof-object? r)
        ;; close the socket after the process
        (socket-close socket)
        (socket-send socket r))))

(define server (make-simple-server "5000" handler :config server-config))

(server-start! server)

Above server example creates 5 threads and accept all requests. The requests are dispatched to the least busy thread. There are couple of restrictions to use this server. See the descirption of non-blocking? keyword argument.

Server

Simple server class.

Function server? obj

Returns #t if the obj is an instance of <simple-server>, otherwise #f.

Creates a server object.

service must be a string and indicates the service name or port number.

handler must be a procedure accepts 2 arguments, server object server created with this procedure and socket object socket.

Keyword argument server-class is specified, it must be a class inherits <simple-server>, then the procedure uses the class to instantiate. And during instantiation, given other keys are passed.

Keyword argument config is specified, it must be an instance of <server-config> or subclass of it, then the server is created according to the configuration.

Returns configuration object used to create given server object server.

Returns #t if given server is stopped.

NOTE: this also returns #t if the server is not started.

Starts the given server.

Keyword argument background is true value then the server is started background. By default it's #f.

The rest of keywords are passed to on-server-start!.

NOTE: Server object is not reusable thus once server is started, it is impossible to restart the server.

Stops the given server.

The rest of keywords are passed to on-server-stop!.

Waits until the server stops.

The server must be stopping by accessing shutdown port otherwise this procedure waits forever/for timeout period.

Optional argument timeout must be #f, time object or real number. If the value is #f then this procedure waits forever until the _server_stops. By default #f.

Hook methods for subclasses.

The first method is called when server is starting.

The second method is called after server is stopped.

Configuration

Server configuration class.

Returns #t if the obj is an instance of <server-config>, otherwise #f.

_ max-retry use-ipv6? secure? certificates

Creates a server config object.

Following is the description of keyword arguments.

shutdown-port

Specifying shutdown port. The value must be a string. If this is not specified, then the server doesn't have shutdown port.

shutdown-handler

This is only used then shutdown-port is specified. The value must be a procedure takes 2 arguments, server and socket. When the procedure returns true value then server will be stopped. By default, it's a procedure always returns #t.

exception-handler

Specifying exception handler. The value must be a procedure accepts 3 arguments, server, socket and condition. This is called when the server handler raises an error. NOTE: The passing socket is not closed so that the handler can send messages to client socket.

max-thread

Specifying max thread count. Default value is 1.

max-retry

Specifying max retry count. When connection reached max-thread, then the server waits if the one of the connections finishes. The waiting period is half second (500 ms) and this value specifies how many times server waits. Default value is 10.

non-blocking?

Creating non blocking server. If the server is non blocking server, then the server handler must follow the following rules:

  • the handler process must not block/stop even if the given socket is active.

  • the handler process must close the socket when it's not needed. When handler raises an error and exception-handler is specified, then the given socket won't be closed. So exception-handler needs to decide whether the exception is continuable or not. Otherwise, server closes the socket. Specifying this keyword argument makes server ignore max-retry.

use-ipv6?

Specifying whether or not the server uses IPv6. Default value is #f. (only IPv4)

secure?
certificates

If secure? is true value and certificates is a list of X509 certificates, then the server uses TLS.

private-key

If the server uses TLS, then this keyword argument is passed to make-server-tls-socket. It is strongly recommended to specify this keyword argument, otherwise key exchange is done anonymously, means no signature is sent.

Socket detaching

Non blocking server manages sockets per threads. This feature is useful if the server handler is reused per socket. However this prevents users to write asynchronous call. The following procedure allow users to detach sockets from the server.

Detaches the given socket.

If the socket is detached, then all resource managements, including closing socket, become users' responsibility.

This procedure is only available on non blocking server and can be called inside of server handler. If the condition is not met, then &assertionis signaled.