user467526
user467526

Reputation: 527

Why does await always return Nothing when using network conduits?

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

Answers (1)

user467526
user467526

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

Related Questions