{-# LANGUAGE LambdaCase #-} module Client.Communication where import qualified Data.Aeson as A import qualified Data.ByteString as B import qualified Data.ByteString.Lazy.Char8 as B8 import Network.Socket import System.IO -- internal imports import Library.Types connectSocket :: FilePath -> IO Socket connectSocket path = do sock <- socket AF_UNIX Stream defaultProtocol setSocketOption sock KeepAlive 1 connect sock (SockAddrUnix path) -- handle <- socketToHandle sock ReadWriteMode -- hSetBuffering handle (BlockBuffering Nothing) pure sock -- | Sends a specified message through given socket to the server sendMessage :: ClientMessages -> Socket -> IO () sendMessage msg sock = do handle <- socketToHandle sock WriteMode hSetBuffering handle (BlockBuffering Nothing) let msgJson = A.encode msg B.hPutStr handle $ B.toStrict msgJson hFlush handle -- hClose handle receiveMessage :: Socket -> IO ServerMessage receiveMessage sock = do handle <- socketToHandle sock ReadMode hSetBuffering handle LineBuffering handleOpen <- hIsOpen handle if handleOpen then do message <- hGetContents handle let mJsonMessage = A.decode' $ B8.pack message :: Maybe ServerMessage errMsg = error $ "unexpected message from Server: " <> message -- hClose handle maybe errMsg pure mJsonMessage else error "Handle is closed"