Our basic server has four basic functions:
Listen () => (int socket);
ReadInput(int socket) => (int socket, char* line);
EchoInput(int socket, char* line) => (int socket);
Close(int socket) => ();
Conceptually, a Flux program is separated into two different components.
A source which generates some event and a handler that
processes the event. Each of these are just a single functional
node.
To enable this, we add a single abstract functional node, Echo,
that encapsulates the operation of ReadInput, EchoInput and Close. We
will see how this encapsulation is expressed next.
Next we specify that the Listen node is a source node, and that
the events generated by Listen are handled by Echo
Echo(int socket) => ();
Now the nodes have been specified, but the Flux program for the echo
server is just a disjoint collection of nodes. There are no edges in
the program graph for data to flow along. These edges are added as a
series of flows, each flow encapsulates the operation of some
abstract flow. Programmers should use abstract flows as a mechanism to
structure their programs.
The echo server is a simple program and thus only has a single flow:
source Listen => Echo;
That's all there is to the echo server in Flux.
Echo = ReadInput -> EchoInput -> Close;
The corresponding program graph looks like:
Next use the Flux compiler to compile the flux program:
fluxc
-r <root directory> -t echo_server
The compilation process produces a number of files. Users must implement the stubs in mImpl.cpp to implement the server. The actual implementation of an echo server is an exercise left to the reader.
Once the code is implemented, type make and the server will be built.
./echo_server &; telnet 12345 to try it out!