Skip to content
This repository

Aleph models bidirectional communication using channels. Make sure you’re familiar with their usage before reading this entry. Also familiarize yourself with using Lamina to model connections.

TCP servers

Consider this simple echo server:

(use 'lamina.core 'aleph.tcp 'gloss.core)

(defn handler [ch client-info]
  (receive-all ch
    #(enqueue ch (str "You said " %))))

(start-tcp-server handler {:port 10000, :frame (string :utf-8 :delimiters ["\r\n"])})

When a client connects, the handler is called with a channel and a hash containing information about the client. At this point, the client may or may not have actually sent anything to the server.

To read the messages sent by the client, the server uses receive-all. Without a frame specified, the messages would be sequences of ByteBuffers. In this case, we’ve specified that the frame is a newline-delimited string. We can specify the :frame, the :delimiters, or both in the options of start-tcp-server. If necessary, we can also specify separate frames for the :decoder when receiving data from a client and the :encoder when sending data to a client.

Upon receiving a message, we prepend “You said …” and enqueue it back into the channel.

When the client closes the connection, both sides of the channel will be immediately sealed. The final message from the channel will be nil, which in the above example will cause some strange but harmless behavior: the callback will attempt to respond with "You said ", but since the channel is already sealed, this response is ignored.

TCP clients

Creating a client and talking to the echo server described above is simple:

(def ch
  (wait-for-result
    (tcp-client {:host "localhost",
                 :port 10000,
                 :frame (string :utf-8 :delimiters ["\r\n"])})))
(enqueue ch "Hello, server!")
(wait-for-message ch)

The tcp-client call will return an async-promise. If the client successfully connects, wait-for-result yields a channel that can be used to communicate with the server. :frame and :delimiters work the same for clients as they do for servers.

Something went wrong with that request. Please try again.