If you want, for some reason, to interleave rapid-fire RPC with file transfer while hopping between the networks (or just dislike websockets), and/but can’t be bothered with setting up a proper TLS PKI…
Here’s a quic-and-dirty example:
data ClientMessage
= Hello
| Bye
deriving (Eq, Show, Ord, Generic)
instance QUIC.Serialise ClientMessage
data ServerMessage
= Ok Int
deriving (Eq, Show, Ord, Generic)
instance QUIC.Serialise ServerMessage
serverSimple :: IO ()
serverSimple = do
counter <- newIORef 0
QUIC.runServerSimple "127.0.0.1" 14443 \case
Hello -> do
putStrLn "Server got Hello"
n <- atomicModifyIORef' counter \old -> (old + 1, old)
pure $ Ok n
Bye -> do
putStrLn "Server got Bye"
error "Whelp, the serverSimple must reply, but the protocol must stop. Needs a redesign."
clientSimple :: IO ()
clientSimple = do
(stop, call) <- QUIC.startClientSimple "127.0.0.1" "14443"
replicateM_ 5 do
Ok n <- call Hello
putStrLn $ "Client got reply " <> show n
timeout 1000000 (call Bye) >>= mapM_ \reply ->
putStrLn $ "Shouldn't happen, the server errors out on this: " <> show reply
putStrLn "Stopping"
stop
The code is separated into layers and is intended to be used as a template. Replace the wrappers with code and adjust it as you move from a prototype to a working system with requirements.