conduit
下面是一些使用、network-conduit
和实现小型接收服务器的代码stm-conduit
。它在套接字上接收数据,然后通过 STM 通道将其流式传输到主线程。
import Control.Concurrent (forkIO)
import Control.Concurrent.STM (atomically)
import Control.Concurrent.STM.TBMChan (newTBMChan, TBMChan())
import Control.Monad (void)
import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad.Trans.Class
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Conduit
import qualified Data.Conduit.Binary as DCB
import Data.Conduit.Extra.Resumable
import Data.Conduit.Network (sourceSocket)
import Data.Conduit.TMChan (sinkTBMChan, sourceTBMChan, mergeSources)
import System.Directory (removeFile)
import System.IO
type BSChan = TBMChan ByteString
listenSocket :: Socket -> Int -> IO BSChan
listenSocket soc bufSize = do
chan <- atomically $ newTBMChan bufSize
forkListener chan
return chan
where
forkListener chan = void . forkIO $ listen soc 2 >> loop where
loop = do
(conn, _) <- accept soc
sourceSocket conn $$ sinkTBMChan chan
close conn
loop
main :: IO ()
main = do
soc <- socket AF_UNIX Stream 0
bind soc (SockAddrUnix "mysock")
socChan <- listenSocket soc 8
sourceTBMChan socChan $$ DCB.sinkHandle stdout
removeFile "mysock"
(在实际应用程序中,来自套接字的数据流与其他一些数据流合并,这就是为什么我不在侦听器中直接处理它的原因)。
问题是,我曾期望它在主线程被杀死之前保持打开状态,而是在套接字上收到第一条消息后退出。我无法弄清楚它为什么这样做,除非它是接收器(在第 2 到最后一行)在看到第一个数据流的结尾时退出。我可以说服它不要这样做吗?有一些Conduit
关于使源可恢复的东西,但不是接收器。