engine-io 1.1.0 → 1.1.1
raw patch · 3 files changed
+49/−6 lines, 3 filesdep ~aesonPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson
API changes (from Hackage documentation)
+ Network.EngineIO: dupRawReader :: Socket -> IO (STM Packet)
Files
- Changelog.md +8/−0
- engine-io.cabal +2/−2
- src/Network/EngineIO.hs +39/−4
Changelog.md view
@@ -1,3 +1,11 @@+## 1.1.1++* Long-polling connections now emit a `ping` message after 45 seconds, if no+ data is written to them.++* There is a new `dupRawReader` function, which lets you create a read-only+ stream of raw communication with a socket.+ ## 1.1.0 * The `ServerAPI` functions `srvWriteBuilder`, `srvSetContentType` and
engine-io.cabal view
@@ -1,5 +1,5 @@ name: engine-io-version: 1.1.0+version: 1.1.1 synopsis: A Haskell implementation of Engine.IO homepage: http://github.com/ocharles/engine.io license: BSD3@@ -27,7 +27,7 @@ RankNTypes, OverloadedStrings, RecordWildCards build-depends:- aeson >=0.7 && <0.8,+ aeson >=0.7 && <0.9, async >=2.0 && <2.1, attoparsec >=0.11 && <0.13, base >=4.6 && <4.8,
src/Network/EngineIO.hs view
@@ -22,6 +22,7 @@ , SocketId , socketId , getOpenSockets+ , dupRawReader -- * The Engine.IO Protocol -- This section of the API is somewhat low-level, and exposes the raw@@ -293,6 +294,7 @@ , socketTransport :: STM.TVar Transport , socketIncomingMessages :: STM.TChan PacketContent , socketOutgoingMessages :: STM.TChan PacketContent+ , socketRawIncomingBroadcast :: STM.TChan Packet } instance Eq Socket where@@ -457,6 +459,7 @@ STM.newTVarIO transport) <*> STM.newTChanIO <*> STM.newTChanIO+ <*> STM.newBroadcastTChanIO liftIO $ STM.atomically (STM.modifyTVar' (eioOpenSessions eio) (HashMap.insert sId socket)) @@ -478,6 +481,7 @@ _ -> return () + STM.writeTChan (socketRawIncomingBroadcast socket) req return (Just req) , do STM.readTChan (socketOutgoingMessages socket)@@ -496,7 +500,7 @@ saOnDisconnect app let openMessage = OpenMessage { omSocketId = sId- , omUpgrades = [ Websocket ]+ , omUpgrades = [ ] , omPingTimeout = 60000 , omPingInterval = 25000 }@@ -588,11 +592,27 @@ where poll = do+ readTimeout <- liftIO $ STM.registerDelay (45 * 1000000)+ let out = transOut transport- packets <- liftIO $- (:) <$> STM.atomically (STM.readTChan out)- <*> unfoldM (STM.atomically (STM.tryReadTChan (transOut transport))) + -- Here we attempt to read as much from the transport output as we can.+ -- We also consider the timeout above, such that if we haven't even read+ -- one message by the timeout is reached, we instead emit a `ping`.+ packets <- liftIO $ do+ p <- STM.atomically $ do+ let dequeueHead = Just <$> STM.readTChan out+ timeout = Nothing <$ (STM.readTVar readTimeout >>= STM.check)++ dequeueHead <|> timeout++ case p of+ Just p' ->+ (p' :) <$> unfoldM (STM.atomically (STM.tryReadTChan (transOut transport)))++ Nothing ->+ return [ Packet Ping (BinaryPacket mempty) ]+ writeBytes api (encodePayload supportsBinary (Payload (V.fromList packets))) post = do@@ -650,6 +670,21 @@ TransportUnknown -> "Transport unknown" SessionIdUnknown -> "Session ID unknown" BadRequest -> "Bad request"+++--------------------------------------------------------------------------------+-- | Create a new 'IO' action to read the socket's raw incoming communications.+-- The result of this call is iteslf an STM action, which will called will return+-- the next unread incoming packet (or block). This provides you with a separate+-- channel to monitor incoming communications. This may useful to monitor to+-- determine if the socket has activity.+--+-- This is a fairly low level operation, so you will receive *all* packets -+-- including pings and other control codes.+dupRawReader :: Socket -> IO (STM.STM Packet)+dupRawReader s = do+ c <- STM.atomically (STM.dupTChan (socketRawIncomingBroadcast s))+ return (STM.readTChan c) {- $intro