Я попытался создать простую клиент-серверную программу, следуя этому руководству о библиотеке сетевого канала Haskell.
Это клиент, который одновременно отправляет файл на сервер и получаетответ:
{-# LANGUAGE OverloadedStrings #-}
import Control.Concurrent.Async (concurrently)
import Data.Functor (void)
import Conduit
import Data.Conduit.Network
main = runTCPClient (clientSettings 4000 "localhost") $ \server ->
void $ concurrently
(runConduitRes $ sourceFile "input.txt" .| appSink server)
(runConduit $ appSource server .| stdoutC)
И это сервер, который подсчитывает вхождения каждого слова и отправляет результат обратно клиенту:
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Char8 (pack)
import Data.Foldable (toList)
import Data.HashMap.Lazy (empty, insertWith)
import Data.Word8 (isAlphaNum)
import Conduit
import Data.Conduit.Network
import qualified Data.Conduit.Combinators as CC
main = runTCPServer (serverSettings 4000 "*") $ \appData -> do
hashMap <- runConduit $ appSource appData
.| CC.splitOnUnboundedE (not . isAlphaNum)
.| foldMC insertInHashMap empty
runConduit $ yield (pack $ show $ toList hashMap)
.| iterMC print
.| appSink appData
insertInHashMap x v = do
return (insertWith (+) v 1 x)
Проблема в том, что сервер не 'не доходят до фазы доходности до тех пор, пока я не закрою клиент вручную и поэтому никогда не отвечу на него.Я заметил, что при удалении параллелизма от клиента и сохранении только части, в которой он отправляет данные на сервер, все работает нормально.
Итак, как я могу сохранить принимающую часть клиента, не прерывая поток?