0
我在寫一個套接字服務器runTCPServer
從conduit-extra(以前叫做network-conduit)。我的目標是使用此服務器與我的編輯器進行交互 - 從編輯器激活服務器(很可能只是通過調用外部命令),使用它並在工作完成時終止服務器。如何關閉`runTCPServer`?
爲簡單起見,我從一個簡單的echo服務器開始,假設我想在連接關閉時關閉整個過程。
所以,我想:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Conduit
import Data.Conduit.Network
import Data.ByteString (ByteString)
import Control.Monad.IO.Class (liftIO)
import System.Exit (exitSuccess)
import Control.Exception
defaultPort :: Int
defaultPort = 4567
main :: IO()
main = runTCPServer (serverSettings defaultPort "*") $ \ appData ->
appSource appData $$ conduit =$= appSink appData
conduit :: ConduitM ByteString ByteString IO()
conduit = do
msg <- await
case msg of
Nothing -> liftIO $ do
putStrLn "Nothing left"
exitSuccess
-- I'd like the server to shut down here
(Just s) -> do
yield s
conduit
但是,這並不工作 - 程序繼續接受新的連接。如果我沒有弄錯,這是因爲偵聽我們正在處理的連接的線程以exitSuccess
退出,但整個過程不會。所以這是完全可以理解的,但我一直無法找到一種方法來退出整個過程。
如何終止由runTCPServer
運行的服務器?是runTCPServer
應該永遠服務的東西?
'exit'必須從主線程調用(我不知道爲什麼,但是這是要求)。你總是可以在一個單獨的'forkIO'd線程中運行'runTCPServer',讓主線程等待一些工作線程在終止消息到達時設置的'MVar'。 –
是的,'runTCPServer'旨在永遠運行,請參見[source](https://hackage.haskell.org/package/streaming-commons-0.1.15.5/docs/src/Data-Streaming-Network.html# runTCPServerWithHandle)。 –
@ n.m。這似乎是我正在尋找的確切答案(尤其是'forkIO'和'MVar'部分)。你會添加一個簡單的例子(如果你不介意),並將其作爲答案發布? – Yosh