【问题标题】:Compatibility of ZeroMQ sockets written on different languages用不同语言编写的 ZeroMQ 套接字的兼容性
【发布时间】:2017-01-01 18:28:31
【问题描述】:

我基于 ZeroMQ 构建了一个用 python 编写的应用程序,但现在我遇到了性能问题。所以我决定使用 Golang 重写我的应用程序的一些模块。但是,当我尝试在由不同语言实现的套接字之间建立消息传递时,任何事情都不起作用。

到目前为止,我已经搜索过了,但我没有找到任何关于 ZeroMQ 使用不同的兼容性问题的信息语言。

所以问题是:我可以使用 golang 进行基于 ZeroMQ 的服务器实现和用 python 编写的客户端来连接它吗?
或者我只能使用一种语言?

编辑:这是我正在尝试正常工作的典型服务器和客户端

服务器:

import zmqctx = zmq.Context()
sock = ctx.socket(zmq.REP)
sock.bind("tcp://*:57000")
msg = sock.recv()

客户:

package main

import (
    zmq "github.com/pebbe/zmq4"
)

func main() {

    ctx, _ := zmq.NewContext()
    sock, _ := ctx.NewSocket(zmq.REQ)

    sock.Connect("tcp://localhost:57000")
    sock.Send("simple message", 0)
}

服务器卡在sock.recv()

【问题讨论】:

  • 我最近将我的一个慢速 python (celery) 模块重写为 Go。它通过 RabbitMQ 与系统的其他部分进行通信。我不知道 ZeroMQ,但我猜它对所有连接客户端都有一个通用协议,所以它应该可以工作。也许你做错了什么?您遇到了什么样的问题?
  • 当你说“重写,比方说,Golang”时,你的意思是这是假设的,还是你真的做了重写?如果您尚未完成重写,我建议您为 python 编写 C 扩展以提高性能。
  • @Tadhg McDonald-Jensen,说实话,我使用 Golang 作为第二语言
  • 通过 FFI 编写 C 比仅仅在 Go 中进行破解要困难得多——@pupizoid 使用 ZeroMQ 的事实意味着无需专注于解释器本地对象。跨度>
  • 参考您的示例代码,zmq.REP 在收到请求之前阻止 recv。您确定有可供客户端使用的消息吗?

标签: python go zeromq


【解决方案1】:

编程语言能够相互通信——是的,你可以用 Go 编写一个服务器,用 Python 编写一个客户端,让它们相互通信。

如果您尝试使用原始套接字进行通信,请查看所需语言的文档并确保序列化数据在结构上匹配。

例如您可以决定一个结构并在Python 或代码中实现您的有效负载,然后在Go 中匹配该结构(Go 中可能有更好的/stdlib 方式;我对这种语言不是很有经验)。担心这些细节的潜在维护和实现难题是人们使用更高级别协议的原因——这正是 ZeroMQ 的一个很好的用例。

如果您将消息队列用作操作的主干,只需将其用作共享协议即可。如果您的 Python 代码可以与 ZeroMQ 对话,那么它就可以正确地完成工作——您的 Go 代码无需知道它正在与 Python 对话。

在这种情况下,您的新 Go server would bind to ZeroMQ、您的 Python client would bind to ZeroMQ 和您的两种异构语言无需相互了解。

【讨论】:

  • 我是这么认为的,但在实践中,即使是简单的例子也行不通,我已将其添加到我的问题中。
  • 好吧,我试着反过来运行一切,令我高兴的是,当 python 客户端连接到 go 服务器并传递一条消息时,它终于成功了。事实证明,我从一开始就做错了什么,所以感谢你的回答,这让我对显而易见的事情更有信心:)
  • @pupizoid 哦,很高兴听到这个消息——这也意味着我可以停止在这台机器上设置 Go 环境了 :)
【解决方案2】:

这有点晚了,但我在尝试查找 golang-to-python 0mq 实现时发现了这篇文章。

在我的 golang 代码中,我刚刚将 zmq 更改为 zmq4,一切都对我有用:

import (
    zmq4 "github.com/pebbe/zmq4"
)

func main() {

    ctx, _ := zmq4.NewContext()
    sock, _ := ctx.NewSocket(zmq4.REQ)

    sock.Connect("tcp://localhost:57000")
    sock.Send("simple message", 0)
}

【讨论】:

  • 嗨,据我所知,导入模块的“快捷方式”并不重要。正如我之前发现的那样,我的系统设置有问题,最后一切都解决了。但无论如何感谢您的回复!
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多