我有一个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);
});
此外,这仅在服务器先启动然后客户端启动的情况下有效。如何让客户端重试直到连接。
答案 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。
让我介绍一些可以改善该方向免疫力的方法:
始终保持明确设置.setsockopt( zmq.LINGER, 0 )
,以避免在已断开连接的互连上死胡同地“绞尽脑汁”。
更喜欢设置.setsockopt( zmq.IMMEDIATE )
,它可以防止在未准备好传输的互连上缓冲任何消息以便“稍后”传递...
始终始终将所有代码设计为始终使用所有.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锁将实际的代码执行时流程切掉了),并且很安全。