ZeroMq:保持python和节点之间的连接对

时间:2018-12-14 12:44:20

标签: python node.js zeromq

我有一个python服务器和一个nodejs客户端。问题是,有时当我重新启动nodejs脚本时,它不会重新连接。

此外,我不明白的是为什么python上存在无限循环。不能使用事件来监听连接。

下面是服务器和客户端。

context = zmq.Context()
socket = context.socket(zmq.PAIR)
print("Binding socket to port: " + str(port))
socket.bind("tcp://*:%s" % port)
print("Connection has been established")
while True: // cant we listen for events here i.e on connection etc
    msg = socket.recv()
    print(msg)
    socket.send("Server response")

//

'use strict';
var globevt = require('../lib/emitter');
var sprintf = require("sprintf-js").sprintf;
var logger = require('../lib/logat');
var zmq = require('zeromq')
    , socket = zmq.socket('pair');
const fs = require('fs');
socket.connect('tcp://127.0.0.1:3000');
socket.on('message', function (msg) {
    console.log(msg);
});

此外,这仅在服务器先启动然后客户端启动的情况下有效。如何让客户端重试直到连接。

2 个答案:

答案 0 :(得分:0)

根据zmq指南,成对套接字用于在同一过程中进行线程间通信。预期用途是绑定父线程,然后将套接字上下文传递给子线程,并以对/对组合的形式将其连接到父线程套接字

排他的对,排他地连接两个插座。这是一个 在一个进程中连接两个线程的模式,不要混淆 带有“普通”插座对。

对于进程间通信,您应该使用req / rep,pub / sub或其他某种模式。如果您需要简单可靠的进程间(可靠性级别非常高),客户端可以处理服务器的故障,请查看lazy pirate模式

答案 1 :(得分:0)

Q “ ...有时,当我重新启动node.js脚本时,它不会重新连接。”

嗯,有一些技巧可以解决这个问题,但要特别注意的是,ZeroMQ版本和实际的第三方语言包装器/绑定版本(以及对当时有效的语言的严格程度) API记录的属性)很重要...

如v4.3.2 API所述,

socket( zmq.PAIR ) -实例在生产中的行为方式有两个主要区别:

a)一个PAIR套接字原型,在进入.bind()到RTO状态并接受成功.connect(...)的传入对等方之后,将永远不会接受“另一个“ .connect()来临

b)PAIR-套接字原型在其他常见的低级传输级连接管理服务原型上不起作用,因此不要指望任何静默的自动化“自动重新连接”或智能接收新的原型,成为 ...几乎... 再次“空闲”,.connect()-连接在内部未完成对“旧”对等互连套接字的处理,而该套接字仍处于关闭状态tcp-transport-class。

仍然,我们可以在内置原型原语之上创建自己的智能元层,以处理任何此类行为。如有疑问,请记住零零点零零零零零零零碎的精心设计的零零零零原则。可能会发现更多here的灵感,并且为了获得更广泛的(如果不是完整的)上下文,可以尝试this

让我介绍一些可以改善该方向免疫力的方法:

  1. 始终保持明确设置.setsockopt( zmq.LINGER, 0 ),以避免在已断开连接的互连上死胡同地“绞尽脑汁”。

  2. 更喜欢设置.setsockopt( zmq.IMMEDIATE ),它可以防止在未准备好传输的互连上缓冲任何消息以便“稍后”传递...

  3. 始终始终将所有代码设计为始终使用所有.recv()方法的非阻塞形式-您的代码将永远在行msg = socket.recv()上不可挽救地阻塞,其中如果远程对等端尚未发送任何消息,或者无论出于何种原因永远不会发送任何下一条消息,它将保留其余时间。始终使用.recv( zmq.NOBLOCK )

    进行---预先轮询POSACK是否已准备就绪
    以下一步执行.recv( zmq.NOBLOCK )
    使用.poll( someContextSpecificFeasibleWaitingTime )
    或在所有情况下进行---后.recv( zmq.NOBLOCK )处理的情况下,实际上.recv( zmq.NOBLOCK )并没有什么期望值,因此您确实会留空调用.recv( zmq.NOBLOCK )方法

    一无所获

Q “此外,我不明白的是为什么python上存在无限循环。我不能使用事件来监听连接。”

好吧,循环更简单,并且主要是避免了多个事件循环框架之间的“冲突”(在Tkinter的情况下很常见,其中mainloop()通常撤回所有其他事件处理程序,而“合作”事件处理框架几乎是矛盾的东西。

循环是简单的纯[SERIAL]代码执行结构(还记得GIL锁将实际的代码执行时流程切掉了),并且很安全。