簡體   English   中英

如何在Haskell中通過管道使用ZMQ用戶

[英]How to use a ZMQ subscriber in Haskell with pipes

我可以讓ZMQ訂戶在Haskell中工作,但希望能獲得有關如何在Pipes中使用該數據的指導。 我寫生產者的嘗試在“堆棧生成”中失敗,並出現以下錯誤:

無法將類型“代理X()c'0 c0(ZMQ z)”與“ ZMQ z”進行匹配

預期類型:ZMQ z()

實際類型:代理X()c'0 c0(ZMQ z)()

{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad
import Pipes
import qualified Pipes.Prelude as P
import System.ZMQ4.Monadic
import qualified Data.ByteString.Char8 as CS

fromZMQ :: (Receiver r) => Socket z r -> Producer String (ZMQ z) ()
fromZMQ sock = do
    msg <- lift $ receive sock
    yield (CS.unpack msg)
    fromZMQ sock

main :: IO ()
main = --do
  runZMQ $ do
    subSock <- socket Sub  ---subscriptionSocket
    subscribe subSock ""
    connect subSock "tcp://127.0.0.1:4998" 
    forever $ fromZMQ subSock >-> P.take 3 >-> P.print

注意,我想使用通過python腳本在ZMQ上發布的數據。

根據Thomas提出的使用Chan的建議,我改編了MVar示例(下面的鏈接)以累加接收到的字符串,並計算其中的一部分以演示更新和讀取狀態

https://www.oreilly.com/library/view/parallel-and-concurrent/9781449335939/ch07.html

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Concurrent  
import Control.Monad
import System.ZMQ4.Monadic
import qualified Data.ByteString.Char8 as CS

newtype State = State (MVar (Int, [CS.ByteString]) ) --(count, list of strings received over zmq)

newState :: IO State
newState = do
  m <- newMVar (0, [])
  return (State m)

updateState :: State -> CS.ByteString -> IO ()
updateState (State m) newString = do
  (count,strList) <- takeMVar m
  putMVar m ( count + 1 , strList ++ [newString] )

showState :: State -> IO String
showState (State m) = do
  count <- takeMVar m
  putMVar m count  --return the lock; no changes
  return (show count)

main = runZMQ $ do
    sub <- socket Sub
    subscribe sub ""
    connect sub "tcp://127.0.0.1:4998"
    s <- liftIO newState 
    forever $ do
      receive sub >>= liftIO . updateState s 
      liftIO $ updateState s "hello"  --'manually' add an additional string on each iteration
      op <- liftIO $ showState s
      liftIO $ print op 

代碼中唯一的問題是最后一行。

您在那里有一個“管道”:

fromZMQ subSock >-> P.take 3 >-> P.print :: Effect (ZMQ z) ()

當您forever申請時,類型保持不變。 但是,您需要一個簡單的ZMQ z ,換句話說,您需要實際執行pipes計算,並為此使用runEffect函數。 附帶說明一下,您實際上並不需要forever因為流永遠不會結束。

因此,實際上,您要做的就是最后一行中的runEffect forever替換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM