
I think FRP is well-suited to this problem; it lets you abstract out
the imperative network code from the "reactive core" of the code. The
network code can live in a separate thread that uses select() and
listen(), and updates event streams.
I was thinking about writing a MUD using FRP; in my mind, the
framework looked something like this:
-- A connection is
-- 1) An event that fires once when the connection is closed
-- 2) An event that fires each time a line is received over the connection
-- 3) A routine that outputs a line to that connection
-- 4) A routine that closes the conection
data Connection = Conn
{ connClosed :: Event ()
, connLines :: Event String
, connWrite :: String -> IO ()
, connDisconnect :: IO ()
}
-- Listen on a given port for connections and return them as an FRP
event stream.
-- Since Connection contains an event stream, this is going
-- to be a nested event; we will use join/>>= on Event at some point to get the
-- commands from each connection
listen :: Int -> IO (Event Connection)
-- the server is an FRP program that outputs an event stream of IO actions;
-- the actions will generally just be "write a message to a particular socket"
server :: Event Connection -> Event (IO ())
-- Now main is trivial to implement, given sinkE from Conal's FRP paper
-- http://conal.net/papers/simply-reactive/
-- sinkE :: (a -> IO ()) -> Event a -> IO ()
main = listen 4200 >>= sinkE id . server
-- An example server that writes "hello world" to each client and
disconnects them
server conns = do
connection <- conns
return $ do
connWrite connection "Hello World."
connDisconnect connection
-- ryan
On Sun, Aug 17, 2008 at 2:26 PM, Tim Newsham
I'm interested in FRP, have read several of the papers and am wondering if it could be applied to writing multi-client server programs. What would be the input type events for such a system? What would be the output type events? How would the system handle the fact that it has to multiplex several IO streams (sockets)?
I'm trying to answer these questions myself and having a hard time. Should input events include new connection requests and shutdowns? Individual bytes? Streams of bytes? or higher level PDUs? What kind of output should be generated? Full PDUs? streams of bytes? Pairs of (connection identifier,data)? How would such a system effectively hide the multiplexed IO going on? Is this sort of problem poorly suited for FRP?
Tim Newsham http://www.thenewsh.com/~newsham/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe