packages feed

alms-0.6.5: examples/echoServer.alms

(* Echo server written using state-tracked sockets. *)

#load "libsocketcap3"

module EchoServer = struct
  open SocketCap

  (* This is a bit different than the version in the paper, because
   * it uses exceptions. *)
  let rec clientLoop f sock !cap =
    let str = recv sock 1024 cap in
      send sock (f str) $> cap;
      clientLoop f sock cap

  let rec acceptLoop f sock !cap =
    let (clientsock, clientcap) = accept sock cap in
      putStrLn "Opened connection";
      Thread.fork (λ _ →
        catchReady (λ _ → clientLoop f clientsock clientcap)
          (clientsock, λ clientcap →
            close clientsock clientcap;
            putStrLn "Closed connection"));
      acceptLoop f sock cap

  let serve port f =
    let (sock, !cap) = socket () in
    bind sock port $> cap;
    listen sock $> cap;
    acceptLoop f sock cap
end

let serverFun (s: string) = s

let main = function
  | [port] → EchoServer.serve (int_of_string port) serverFun
  | _      → failwith "Usage: echoServer.aff PORT\n"

in main (getArgs ())