Reputation: 527
I'm trying to learn how to use conduits. I have a conduit that takes bytestrings and groups them into packets that represent actions being sent to a server. I then have a conduit that takes these packets, acts on them and yields a response packet. Finally I have a conduit that takes the response packets and turns them into a stream of bytestrings. The problem is that yield in the packet handling conduit always returns Nothing. My code looks like this
processingConduit :: ServerState -> Conduit BS.ByteString IO BS.ByteString
processingConduit state = getPacketConduit
=$= processPacketConduit state
=$= putPacketConduit
processPacketConduit :: ServerState -> Conduit ClientPacket IO ServerPacket
processPacketConduit state = awaitForever $ \packet -> do
liftIO $ putStrLn "got something :)"
let function = case packet of
(LoginPacket _ _) -> login
_ -> ugh
result <- liftIO $ function state packet
yield result
getPacketConduit :: Conduit BS.ByteString IO ClientPacket
getPacketConduit = conduitGet (get :: Get ClientPacket)
putPacketConduit :: Conduit ServerPacket IO BS.ByteString
putPacketConduit = conduitPut (put :: ServerPacket -> Put)
I run the conduit using runTCPServer and it's able to accept connections and the getPacketConduit is able to convert the bytestring into valid packets, but awaitForever never calls its function. If I modify processPacketConduit to use await instead, I can see that it always returns Nothing.
Upvotes: 0
Views: 101
Reputation: 527
I figured out my error, I forgot that cereal serializes bytestring by sending length :: Int followed by the actual data. I was only sending a single byte for the length.
Upvotes: 0