我在ZeroMQ中遇到了一个简单的pub-sub示例的问题。我已阅读了大量文档,但似乎无法找到答案。
我从NuGet获得了libzmq
和clrzmq
。对于套接字地址下面的两个函数是:
let sktAddr = "tcp://127.0.0.1:3456"
这是一个简单的发布者,每秒对邮件进行排队。
// Publisher - this seems to work fine
let publisher () : unit =
let skt = (new ZMQ.Context()).Socket(ZMQ.SocketType.PUB)
skt.SetSockOpt(ZMQ.SocketOpt.LINGER, 0)
skt.Bind sktAddr
skt.SendMore("TEST_TOPIC", Text.Encoding.Unicode) |> ignore
let rec h1 () : unit =
let nv = DateTime.Now.ToUniversalTime().ToString()
printfn "Sending value: %s" nv
skt.Send(Text.Encoding.Unicode.GetBytes nv) |> ignore
Threading.Thread.Sleep 1000
let swt = new Threading.SpinWait()
swt.SpinOnce()
if Console.KeyAvailable then
match Console.ReadKey().Key with
| ConsoleKey.Q -> ()
| _ -> h1()
else
h1()
h1()
以下简单订阅者不会抛出任何错误,但会挂在下面指定的行。
// Subscriber
let subscriber () : unit =
let skt = (new ZMQ.Context()).Socket(ZMQ.SocketType.SUB)
skt.Connect sktAddr
skt.Subscribe("TEST_TOPIC", Text.Encoding.Unicode)
let rec h1 () : unit =
let oDat = skt.Recv() // THE PROGRAMME HANGS HERE!
let strODat = (new Text.UnicodeEncoding()).GetString oDat
if oDat <> null then
printfn "Received: %s" strODat
else
printfn "No data received"
let swt = new System.Threading.SpinWait()
swt.SpinOnce()
if Console.KeyAvailable then
match Console.ReadKey().Key with
| ConsoleKey.Q -> ()
| _ -> h1()
else
h1()
h1()
我已阅读this question,但未提供解决方案。所以我在这里发布一个新问题。
提前感谢您的帮助。
答案 0 :(得分:4)
我认为问题在于发布商:
skt.SendMore("TEST_TOPIC", Text.Encoding.Unicode)
不知道F#,看来上面的语句发生在循环之外。如果订阅者正在监听TEST_TOPIC
,则来自发布者的任何消息都要求主题名称位于每封邮件的内容之前,因此发布者必须在每次发送时执行此操作:
skt.SendMore("TEST_TOPIC", Text.Encoding.Unicode)
skt.Send("some data here", Text.Encoding.Unicode)
..试试这个......
let publisher () : unit =
let skt = (new ZMQ.Context()).Socket(ZMQ.SocketType.PUB)
skt.SetSockOpt(ZMQ.SocketOpt.LINGER, 0)
skt.Bind sktAddr
let rec h1 () : unit =
let nv = DateTime.Now.ToUniversalTime().ToString()
printfn "Sending value: %s" nv
skt.SendMore("TEST_TOPIC", Text.Encoding.Unicode) |> ignore
skt.Send(Text.Encoding.Unicode.GetBytes nv) |> ignore
Threading.Thread.Sleep 1000
let swt = new Threading.SpinWait()
swt.SpinOnce()
if Console.KeyAvailable then
match Console.ReadKey().Key with
| ConsoleKey.Q -> ()
| _ -> h1()
else
h1()
h1()
..并且订阅者必须为每条消息收到两次:
// Subscriber
let subscriber () : unit =
let skt = (new ZMQ.Context()).Socket(ZMQ.SocketType.SUB)
skt.Connect sktAddr
skt.Subscribe("TEST_TOPIC", Text.Encoding.Unicode)
let rec h1 () : unit =
let topicName = skt.Recv()
let oDat = skt.Recv()
let strODat = (new Text.UnicodeEncoding()).GetString oDat
if oDat <> null then
printfn "Received: %s" strODat
else
printfn "No data received"
let swt = new System.Threading.SpinWait()
swt.SpinOnce()
if Console.KeyAvailable then
match Console.ReadKey().Key with
| ConsoleKey.Q -> ()
| _ -> h1()
else
h1()
h1()