module Web.SocketIO.Channel
( newGlobalChannel
, newLogChannel
, streamToHandle
, streamBothChannelTo
, makeChannelHub
, stderr
) where
import Web.SocketIO.Types
import Control.Applicative ((<$>))
import Control.Concurrent.Chan.Lifted
import Control.Concurrent.Lifted (fork)
import Control.Monad (forever, void)
import Control.Monad.Base (MonadBase)
import Control.Monad.Trans.Control (MonadBaseControl)
import qualified Data.ByteString.Char8 as BC
import System.IO (Handle, stderr)
newGlobalChannel :: MonadBase IO m => m (Chan Package)
newGlobalChannel = newChan
newLogChannel :: MonadBase IO m => m (Chan ByteString)
newLogChannel = newChan
streamToHandle :: Handle -> Chan ByteString -> IO ()
streamToHandle handle channel = void . fork . forever $ do
readChan channel >>= BC.hPutStrLn handle
makeChannelHub :: SessionID -> ConnectionM ChannelHub
makeChannelHub sessionID = do
globalChannel <- envGlobalChannel <$> getEnv
logChannel <- envLogChannel <$> getEnv
globalChannelClone <- dupChan globalChannel
localChannel <- newChan
outputChannel <- newChan
streamBothChannelTo sessionID localChannel globalChannelClone outputChannel
return $ ChannelHub localChannel globalChannelClone outputChannel logChannel
streamBothChannelTo :: (MonadBaseControl IO m, MonadBase IO m) => SessionID -> Chan Package -> Chan Package -> Chan Package -> m ()
streamBothChannelTo sessionID local global output = do
void . fork . forever $ readChan local >>= writeChan output
void . fork . forever $ do
package <- readChan global
case package of
(Private, _) -> writeChan output package
(Broadcast sessionID', _) -> do
if sessionID /= sessionID'
then writeChan output package
else return ()