further tinkering with communication
This commit is contained in:
parent
07189c7e76
commit
4716c8d1d0
5 changed files with 27 additions and 16 deletions
|
@ -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
|
||||||
|
|
|
@ -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 ()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue