为什么 ZeroMQ REQ / ROUTER 示例没有收到任何消息?
Why a ZeroMQ REQ / ROUTER Example Does Not Receive Any Message?
ZeroMQ: Messaging for Many Applications 评论 REQ -> ROUTER
通讯:
If we rewrote our “Hello World” server using ROUTER
, we’d be able to process any number of “Hello” requests in parallel.
所以我从 ZeroMQ 指南中输入 hwclient.hs
and have slightly modified the hwserver.hs
:
你好世界客户端
{-# LANGUAGE OverloadedStrings #-}
-- Hello World client
module Main where
import Control.Monad
import System.ZMQ4.Monadic
main :: IO ()
main = runZMQ $ do
liftIO $ putStrLn "Connecting to hello world server…"
requester <- socket Req
connect requester "tcp://localhost:5555"
forM_ [1..10] $ \i -> do
liftIO . putStrLn $ "Sending Hello " ++ show i ++ "…"
send requester [] "Hello"
_ <- receive requester
liftIO . putStrLn $ "Received World " ++ show i
路由器:
你好世界路由器
{-# LANGUAGE OverloadedStrings #-}
-- Hello World server
module Main where
import Control.Concurrent
import Control.Monad
import System.ZMQ4.Monadic
main :: IO ()
main = runZMQ $ do
-- Socket to talk to clients
responder <- socket Router
bind responder "tcp://*:5555"
forever $ do
buffer <- receive responder
liftIO $ do
putStrLn "Received Hello"
threadDelay 1000000 -- Do some 'work'
send responder [] "World"
但是,当我 运行 它时,我看到客户端发送消息,但从未收到响应。
$stack exec -- client-exe
Connecting to hello world server…
Sending Hello 1…
在我的另一个 window 中,我看到服务器收到了 3 条消息,仅此而已:
$stack exec -- server-exe
Received Hello
Received Hello
Received Hello
Q1:
为什么客户端一直收不到回复?
Q2:
为什么服务器 (ROUTER
) 收到 3 条消息而不是 1 条?
编辑
我更新了 hwserver.hs
以打印出它收到的消息,而不是简单地 "Hello"。
发布差异:
printf "received request: %s\n" . unpack $ buffer
已替换
putStrLn "Received Hello"
并且服务器(路由器)显示:
$stack exec -- server-exe
received request: A§
received request:
received request: Hello
最后,这里是 send
的函数签名:
λ: :t send
send
:: Sender t =>
Socket z t
-> [Flag] -> Data.ByteString.Internal.ByteString -> ZMQ z ()
反序回答...
你的3'messages'是收到消息的3帧。第一帧由 Router
套接字添加,用于标识消息的来源。第二个是 Requester
套接字添加的空分隔符帧,最后一个帧包含您发送的数据。
这就是为什么您没有收到响应的原因,当经销商套接字发送消息时,它会剥离第一个消息帧并将其用作地址来标识需要回复的客户端。由于您没有保存收到的第一帧并将其附加到传出消息,因此它会被丢弃。
遗憾的是,我对 haskell 或其 zeromq 绑定了解不够,无法为您提供代码解决方案,但如果您接收到地址缓冲区,直到读取空数据包,然后读取数据包入数据缓冲区。回复时发送地址缓冲区,空缓冲区然后回复。
根据 David's and user3666197's 的响应,我放弃了 identity
框架,我想出了:
{-# LANGUAGE OverloadedStrings #-}
-- Hello World server
module Main where
import Control.Concurrent
import Control.Monad
import System.ZMQ4.Monadic
import Text.Printf
import Data.ByteString.Char8 (unpack, pack)
import Data.List.NonEmpty
main :: IO ()
main = runZMQ $ do
-- Socket to talk to clients
responder <- socket Router
bind responder "tcp://*:5555"
forever $ do
response @ (identity : _ : body : []) <- receiveMulti responder
_ <- liftIO $ putStrLn . show . Prelude.length $ response
_ <- liftIO $ forM_ response (printf "received request: %s\n" . unpack)
liftIO $ putStrLn "sending world"
sendMulti responder $ identity `cons` (pack "" `cons` (pack "world" :| []))
运行这
-- terminal 1
$stack exec -- client-exe
Connecting to hello world server…
Sending Hello 1…
received request: world
...
--terminal 2
$stack exec -- router-exe
3
received request: A§
received request:
received request: Hello
sending world
...
ZeroMQ: Messaging for Many Applications 评论 REQ -> ROUTER
通讯:
If we rewrote our “Hello World” server using
ROUTER
, we’d be able to process any number of “Hello” requests in parallel.
所以我从 ZeroMQ 指南中输入 hwclient.hs
and have slightly modified the hwserver.hs
:
你好世界客户端
{-# LANGUAGE OverloadedStrings #-}
-- Hello World client
module Main where
import Control.Monad
import System.ZMQ4.Monadic
main :: IO ()
main = runZMQ $ do
liftIO $ putStrLn "Connecting to hello world server…"
requester <- socket Req
connect requester "tcp://localhost:5555"
forM_ [1..10] $ \i -> do
liftIO . putStrLn $ "Sending Hello " ++ show i ++ "…"
send requester [] "Hello"
_ <- receive requester
liftIO . putStrLn $ "Received World " ++ show i
路由器:
你好世界路由器
{-# LANGUAGE OverloadedStrings #-}
-- Hello World server
module Main where
import Control.Concurrent
import Control.Monad
import System.ZMQ4.Monadic
main :: IO ()
main = runZMQ $ do
-- Socket to talk to clients
responder <- socket Router
bind responder "tcp://*:5555"
forever $ do
buffer <- receive responder
liftIO $ do
putStrLn "Received Hello"
threadDelay 1000000 -- Do some 'work'
send responder [] "World"
但是,当我 运行 它时,我看到客户端发送消息,但从未收到响应。
$stack exec -- client-exe
Connecting to hello world server…
Sending Hello 1…
在我的另一个 window 中,我看到服务器收到了 3 条消息,仅此而已:
$stack exec -- server-exe
Received Hello
Received Hello
Received Hello
Q1:
为什么客户端一直收不到回复?
Q2:
为什么服务器 (ROUTER
) 收到 3 条消息而不是 1 条?
编辑
我更新了 hwserver.hs
以打印出它收到的消息,而不是简单地 "Hello"。
发布差异:
printf "received request: %s\n" . unpack $ buffer
已替换
putStrLn "Received Hello"
并且服务器(路由器)显示:
$stack exec -- server-exe
received request: A§
received request:
received request: Hello
最后,这里是 send
的函数签名:
λ: :t send
send
:: Sender t =>
Socket z t
-> [Flag] -> Data.ByteString.Internal.ByteString -> ZMQ z ()
反序回答...
你的3'messages'是收到消息的3帧。第一帧由 Router
套接字添加,用于标识消息的来源。第二个是 Requester
套接字添加的空分隔符帧,最后一个帧包含您发送的数据。
这就是为什么您没有收到响应的原因,当经销商套接字发送消息时,它会剥离第一个消息帧并将其用作地址来标识需要回复的客户端。由于您没有保存收到的第一帧并将其附加到传出消息,因此它会被丢弃。
遗憾的是,我对 haskell 或其 zeromq 绑定了解不够,无法为您提供代码解决方案,但如果您接收到地址缓冲区,直到读取空数据包,然后读取数据包入数据缓冲区。回复时发送地址缓冲区,空缓冲区然后回复。
根据 David's and user3666197's 的响应,我放弃了 identity
框架,我想出了:
{-# LANGUAGE OverloadedStrings #-}
-- Hello World server
module Main where
import Control.Concurrent
import Control.Monad
import System.ZMQ4.Monadic
import Text.Printf
import Data.ByteString.Char8 (unpack, pack)
import Data.List.NonEmpty
main :: IO ()
main = runZMQ $ do
-- Socket to talk to clients
responder <- socket Router
bind responder "tcp://*:5555"
forever $ do
response @ (identity : _ : body : []) <- receiveMulti responder
_ <- liftIO $ putStrLn . show . Prelude.length $ response
_ <- liftIO $ forM_ response (printf "received request: %s\n" . unpack)
liftIO $ putStrLn "sending world"
sendMulti responder $ identity `cons` (pack "" `cons` (pack "world" :| []))
运行这
-- terminal 1
$stack exec -- client-exe
Connecting to hello world server…
Sending Hello 1…
received request: world
...
--terminal 2
$stack exec -- router-exe
3
received request: A§
received request:
received request: Hello
sending world
...