【发布时间】:2017-11-05 17:26:56
【问题描述】:
在运行 ZeroMQ 基本 PUB / SUB C# 示例时,如果我先启动发布者,它们对我有用,但如果我先启动订阅者,则不会。当我这样做时,订阅者启动,但从未收到任何数据。根据我的阅读,我认为我应该能够以任一顺序启动进程。
我在 .NET 4.6、x64 应用程序中使用来自 nuget 的 ZeroMQ 4.1.0.26 包。这些在 Windows 上运行。我在同一台机器上运行这两个应用程序。
这是我正在运行的代码(它是 ZeroMQ 教程中示例的简化版本)。
订阅者:
static void Main(string[] args)
{
var endpoint = "tcp://127.0.0.1:5556";
// Socket to talk to server
using (var context = new ZContext())
using (var subscriber = new ZSocket(context, ZSocketType.SUB))
{
Console.WriteLine("I: Connecting to {0}…", endpoint);
subscriber.Connect(endpoint);
// Subscribe to zipcode
string zipCode = "90210 ";
Console.WriteLine("I: Subscribing to zip code {0}…", zipCode);
subscriber.Subscribe(zipCode);
while(true)
{
using (var replyFrame = subscriber.ReceiveFrame())
{
string reply = replyFrame.ReadString();
Console.WriteLine(reply);
}
}
}
}
出版商:
static void Main(string[] args)
{
using (var context = new ZContext())
using (var publisher = new ZSocket(context, ZSocketType.PUB))
{
var address = "tcp://*:5556";
Console.WriteLine("I: Publisher.Bind'ing on {0}", address);
publisher.Bind(address);
// Initialize random number generator
var rnd = new Random();
while (true)
{
// Get values that will fool the boss
int zipcode = 90210;
int temperature = rnd.Next(-55, +45);
// Send message to all subscribers
var update = string.Format("{0:D5} {1}", zipcode, temperature);
using (var updateFrame = new ZFrame(update))
{
publisher.Send(updateFrame);
}
Thread.Sleep(1000);
}
}
}
编辑
我尝试了以下建议答案中的建议:
- 使用明确的 IP 地址:这没有区别
- 删除主题过滤:这没有区别
- 创建新的 AnyCPU(而不是 x64)项目:这没有不同
- 尝试其他语言:这很有趣!
使用 Python 等效的发布者和订阅者:
- 在连接到 Python 发布者或 C# 发布者时,Python 订阅者在发布者之前启动时工作。
- C# 订阅者在发布者之前启动时不起作用,无论它是连接到 Python 还是 C# 发布者。
所以看起来 C# 订阅者代码有问题。
问题:
我的示例代码(以下最新版本)有问题吗?
还是 ZeroMQ .NET 库有问题?
这是正常工作的 Python 订阅者:
import sys
import zmq
# Socket to talk to server
context = zmq.Context()
socket = context.socket( zmq.SUB )
print( "Python: Collecting updates from weather server" )
socket.connect( "tcp://localhost:5556" )
socket.setsockopt_string( zmq.SUBSCRIBE, "" )
while True:
string = socket.recv_string()
zipcode, temperature = string.split()
print( zipcode + " " + temperature )
这是 C# 订阅者的最新等效 ( non-working ) 版本:
static void Main(string[] args)
{
// Socket to talk to server
using (var context = new ZContext())
using (var socket = new ZSocket(context, ZSocketType.SUB))
{
Console.WriteLine("C#: Collecting updates from weather server");
socket.Connect("tcp://localhost:5556");
socket.Subscribe("");
while (true)
{
using (var replyFrame = socket.ReceiveFrame())
{
string reply = replyFrame.ReadString();
Console.WriteLine(reply);
}
}
}
}
【问题讨论】:
-
netmq(zeromq 到 .net 的另一个端口)顺便说一句正确地做到了这一点。我会在这里打开一个问题:github.com/zeromq/clrzmq4 看看他们会说什么,你的代码看起来对我完全有效。
-
订阅空字符串是否有效?
-
@somdoron 嗨,somdoron,“订阅任何东西”模式已经过 OP 测试,报告说它在 C# 中不起作用,而 python 客户端运行良好(参考根目录上的 cmets-下面的原因隔离测试 + 希望理查德很清楚,删除主题过滤器实际上意味着需要显式订阅一个空的 ""-string )。到目前为止,该问题似乎已被区分为 Richard 正在使用的 ZeroMQ C# 绑定的实际版本,如 SUB 端对比 { !working |在 C# 之间工作,分别。 python SUB 实现。
-
好吧,ZeroMQ/clrzmq4 只是围绕 ZeroMQ/libzmq 的绑定;您应该尝试将 amd64/libzmq.dll/.so 替换为您的库版本。我怀疑你正在运行 Windows,其中最新的更新是对 libzmq 4.2.x 进行的,这实际上是一个测试版。请务必制作 ZeroMQ/zeromq4-1(或从您的 Python 绑定中复制一个),然后重试...