这是一个conduit
组合器的示例,当从上游接收到完整的消息时,它应该在yield
下游:
import qualified Data.ByteString as BS
import Data.Conduit
import Data.Conduit.Combinators
import Data.Conduit.Network
message :: Monad m => ConduitT BS.ByteString BS.ByteString m ()
message = loop
where
loop = await >>= maybe (return ()) go
go x = if (BS.isSuffixOf "|" x)
then yield (BS.init x) >> loop
else leftover x
服务器代码本身如下所示:
main :: IO ()
main = do
runTCPServer (serverSettings 5000 "!4") $ \ appData -> runConduit $
(appSource appData)
.| message
.| (appSink appData)
telnet 127.0.0.1 5000
发送任何消息后由于某种原因断开连接:
telnet 127.0.0.1 5000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
123|
Connection closed by foreign host.
请指教,我在这里做错了什么?
更新
更重要的是,我在这里尝试做的是等待完成信号|
,然后yield
是下游的完整消息。下面是message
组合器的演变:
message :: Monad m => ConduitT BS.ByteString BS.ByteString m ()
message = do
minput <- await
case minput of
Nothing -> return ()
Just input -> do
case BS.breakSubstring "|" input of
("", "") -> return ()
("", "|") -> return ()
("", xs) -> leftover $ BS.tail xs
(x, "") -> leftover x -- problem is in this leftover
(x, xs) -> do
yield x
leftover $ BS.tail xs
message
我的想法是,如果上游组合器没有任何内容,则必须等到有东西出现,这样它才能向下游发送完整的消息。但是在上述组合器中的调用中,它conduit
开始在 CPU 上旋转很多。leftover
message