further tinkering with communication

This commit is contained in:
nek0 2024-11-03 15:22:28 +01:00
parent 07189c7e76
commit 4716c8d1d0
5 changed files with 27 additions and 16 deletions

View file

@ -70,7 +70,9 @@ handleMessage
-> Game () -> Game ()
handleMessage ServerQuit = do handleMessage ServerQuit = do
st <- get st <- get
liftIO (gracefulExit st "Quitting due to server shutdown") liftIO $ do
putStrLn "Quitting due to server shutdown"
writeIORef (scStopper st) True
handleMessage (Ping id') = do handleMessage (Ping id') = do
cid <- asks rcClientUUID cid <- asks rcClientUUID

View file

@ -4,22 +4,21 @@ import Control.Concurrent.STM (atomically, writeTQueue, flushTQueue)
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Control.Monad.RWS (asks, gets) import Control.Monad.RWS (asks, get)
import Data.IORef (modifyIORef')
import Graphics.Vty import Graphics.Vty
-- internal imports -- internal imports
import Client.Communication
import Client.Types import Client.Types
handleEvent handleEvent
:: Event :: Event
-> Game () -> Game ()
handleEvent (EvKey KEsc _) = do handleEvent (EvKey KEsc _) = do
stopper <- gets scStopper st <- get
liftIO $ modifyIORef' stopper (const True) liftIO $ gracefulExit st "Quitting due to user input"
handleEvent _ = handleEvent _ =
pure () pure ()

View file

@ -85,10 +85,11 @@ disconnectClients clientSockets queueList = do
(\uuid -> do (\uuid -> do
putStrLn $ "notifying client: " <> show uuid putStrLn $ "notifying client: " <> show uuid
queueMessage ServerQuit uuid queueList queueMessage ServerQuit uuid queueList
threadDelay 1000 -- wait for the message to be actually sent
sock <- do sock <- do
socketList <- STM.atomically $ STM.readTMVar clientSockets socketList <- STM.atomically $ STM.readTMVar clientSockets
pure $ fromJust $ find (\s -> csUUID s == Just uuid) socketList pure $ fromJust $ find (\s -> csUUID s == Just uuid) socketList
dropClient clientSockets (csSocket sock) dropClient clientSockets queueList (csSocket sock)
) )
(cqUUID queue) (cqUUID queue)
) )
@ -116,11 +117,11 @@ processRequests = do
sockContainer <- STM.newTMVarIO clientSock sockContainer <- STM.newTMVarIO clientSock
receiverThreadId <- liftIO $ do receiverThreadId <- liftIO $ do
t <- forkIO $ forever $ receiveMessage sockContainer serverQueue t <- forkIO $ forever $ receiveMessage sockContainer serverQueue
putStrLn "enabled listener thread" -- putStrLn "enabled listener thread"
pure t pure t
senderThreadId <- liftIO $ do senderThreadId <- liftIO $ do
t <- forkIO $ forever $ sendMessageQueue sockContainer clientQueue t <- forkIO $ forever $ sendMessageQueue sockContainer clientQueue
putStrLn "enabled sender thread" -- putStrLn "enabled sender thread"
pure t pure t
print clientSock print clientSock
liftIO $ STM.atomically $ do liftIO $ STM.atomically $ do

View file

@ -1,5 +1,7 @@
module Server.Communication.Handler where module Server.Communication.Handler where
import Control.Concurrent (threadDelay)
import qualified Control.Concurrent.STM as STM import qualified Control.Concurrent.STM as STM
import Control.Monad import Control.Monad
@ -36,6 +38,7 @@ handleMessage stateContainer readerContainer msg = do
case msg of case msg of
IdRequest -> do IdRequest -> do
clientId <- nextRandom clientId <- nextRandom
threadDelay 1000
let clientIdx = findIndex (isNothing . csUUID) socks let clientIdx = findIndex (isNothing . csUUID) socks
sock = socks !! fromJust clientIdx sock = socks !! fromJust clientIdx
queue = queues !! fromJust clientIdx queue = queues !! fromJust clientIdx
@ -55,13 +58,13 @@ handleMessage stateContainer readerContainer msg = do
putStrLn $ "Accepted Client with UUID: " <> show clientId putStrLn $ "Accepted Client with UUID: " <> show clientId
queueMessage (AcceptClient clientId) clientId queueList queueMessage (AcceptClient clientId) clientId queueList
else else
putStrLn $ "Unable to assign ID to Socket and queue: " <> show clientId putStrLn $ "Unable to assign ID to socket and queue: " <> show clientId
ClientMessage clientId payload -> ClientMessage clientId payload ->
case payload of case payload of
ClientQuit -> do ClientQuit -> do
putStrLn $ "client has quit the game: " <> show clientId putStrLn $ "client has quit the game: " <> show clientId
let client = find (\a -> csUUID a == Just clientId) socks let client = find (\a -> csUUID a == Just clientId) socks
dropClient socketList (csSocket $ fromJust client) dropClient socketList queueList (csSocket $ fromJust client)
ClientRequestWizard -> do ClientRequestWizard -> do
putStrLn "initializing new wizard" putStrLn "initializing new wizard"
let arena = rcMap readerContainer let arena = rcMap readerContainer

View file

@ -136,23 +136,29 @@ sendPings = do
-- | Drops the client from internal management and closes its socket, if still present. -- | Drops the client from internal management and closes its socket, if still present.
dropClient dropClient
:: STM.TMVar [ClientSocket] :: STM.TMVar [ClientSocket]
-> STM.TMVar [ClientQueue]
-> Socket -> Socket
-> IO () -> IO ()
dropClient clientList sock = do dropClient socketList queueList sock = do
clients <- STM.atomically $ STM.readTMVar socketList
mClient <- STM.atomically $ do mClient <- STM.atomically $ do
clients <- STM.readTMVar clientList
let mclient = find (\client -> csSocket client == sock) clients let mclient = find (\client -> csSocket client == sock) clients
let reducedClients = filter (\client -> csSocket client /= sock) clients
void $ STM.swapTMVar clientList reducedClients
pure mclient pure mclient
maybe maybe
(putStrLn $ "closing unknown socket: " <> show sock) (putStrLn $ "closing unknown socket: " <> show sock)
(\client -> do (\client -> do
putStrLn $ "dropping client because of closed socket: " <> show (fromJust $ csUUID client) putStrLn $ "killing client sender and listener because of socket closing: " <> show (fromJust $ csUUID client)
killThread (csSender client) killThread (csSender client)
killThread (csReceiver client) killThread (csReceiver client)
) )
mClient mClient
putStrLn $ "dropping client because of socket closing: " <> show (fromJust $ csUUID $ fromJust mClient)
STM.atomically $ do
queues <- STM.readTMVar queueList
let reducedClients = filter (\client -> csSocket client /= sock) clients
reducedQueues = filter (\queue -> cqUUID queue /= csUUID (fromJust mClient)) queues
void $ STM.swapTMVar socketList reducedClients
void $ STM.swapTMVar queueList reducedQueues
close sock close sock
sendUpdate sendUpdate