我几乎完成了pub / sub伪造服务器,该服务器请求用户密码和电子邮件(从客户端),将该信息与数据库进行比较并返回数据。它具有“ api_in”和“ api_out”框架,然后是JSON。 发布者可以毫不费力地获取和处理所有信息,但似乎没有将任何信息发送回客户端(订户),我也不知道为什么,因为它已连接到后续端口。
我知道此实现不是经典的PUB / SUB模式,但这是这样做的先决条件。
我尝试了不同的发布/订阅选项,但没有任何改变。
服务器
let zmq = require('zeromq');
const sqlite3 = require('sqlite3').verbose();
const DBSOURCE = "./db.sqlite";
let db = new sqlite3.Database(DBSOURCE, (err) => {
if(err) {
console.error(err.message);
throw err;
} else {
console.log('Connected to SQLite database');
db.run(`CREATE TABLE users (
user_id INTEGER,
email TEXT,
passw TEXT)`,
(err) => {
if (err) {
// Table already created
} else {
// Creating rows
let insert = 'INSERT INTO users (user_id, email, passw) VALUES (?,?,?)';
db.run(insert, [123098, 'phillCollins@gmail.com','5502013']);
db.run(insert, [42424242,'dukenukem3d@mustdie.com','RodriguesShallLiveLong']);
db.run(insert, [5,'yourchick@yandex.ru','semolinaAndPain666']);
}
})
}
});
const args = require('minimist')(process.argv.slice(2));
const pubSocket = zmq.socket('pub', null);
pubSocket.bindSync(`tcp://127.0.0.1:${args['pub']}`);
const subSocket = zmq.socket('sub', null);
subSocket.subscribe('api_in');
subSocket.on('message', function(data) {
let message = data.toString().replace(/api_in/g, '');
let mes = JSON.parse(message);
let api_out = 'api_out';
let errorWrongPWD = 'WRONG_PWD';
let errorWrongFormat = 'WRONG_FORMAT';
if(mes.type = 'login') {
db.get(`SELECT user_id from users WHERE email = ? and passw = ?`, [mes.email, mes.pwd], function(err, row) {
if(err) {
console.log(err);
} else {
if(row) {
let msg = {
msg_id: mes.msg_id,
user_id: row.user_id,
status: 'ok'
}
let outMessage = api_out + JSON.stringify(msg);
console.log(outMessage);
subSocket.send(outMessage);
} else {
let msg = {
msg_id: mes.msg_id,
status: 'error',
error: mes.email == '' || mes.pwd == '' ? errorWrongFormat : errorWrongPWD
}
console.log(msg);
let outMessage = api_out + JSON.stringify(msg);
subSocket.send(outMessage);
}
}
});
}
});
subSocket.bindSync(`tcp://127.0.0.1:${args['sub']}`);
客户端
let zmq = require('zeromq');
let uniqid = require('uniqid');
let readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
const args = require('minimist')(process.argv.slice(2));
const pubSocket = zmq.socket('pub', null);
let pubSocketTCP = `tcp://127.0.0.1:${args['sub']}`;
pubSocket.connect(pubSocketTCP);
const subSocket = zmq.socket('sub', null);
let subSocketTCP = `tcp://127.0.0.1:${args['pub']}`;
subSocket.connect(subSocketTCP);
let api_in = 'api_in';
let secondFrame = {
type: 'login',
email: '',
pwd: '',
msg_id: uniqid()
}
readline.question('What is your email? \n', (email) => {
secondFrame.email = email;
readline.question('What is your password \n', (pwd) => {
secondFrame.pwd = pwd;
let msg = api_in + JSON.stringify(secondFrame);
console.log(msg);
pubSocket.send(msg);
});
});
subSocket.subscribe('api_out');
subSocket.on('message', (response) => {
/* let res = response.toString().replace('api_out');
let responseParsed = JSON.parse(res);
console.log(responseParsed.status);
if(response.status == 'error') console.log(response.error); */
console.log(response);
});
我希望服务器端发回信息。
答案 0 :(得分:0)
您的服务器正在尝试在子套接字上发送
subSocket.send(outMessage);
您不能在子插座上发送。它应该在发布套接字上发送。
答案 1 :(得分:0)
首先,欢迎您访问Zen-of-Zero域。 ZeroMQ是用于智能信令/消息传递的功能强大的工具,因此,如果您注意其所有内部美感,那么您将无法使用它(无法避免这种噩梦)。如果您觉得对这个领域不熟悉,可以先阅读"ZeroMQ Principles in less than Five Seconds",然后再深入探讨该主题的更多细节,或者重用here
张贴的一些技巧。Q :它似乎没有将任何内容发送回客户端(订户),而且我也不知道为什么
有两段代码,似乎同时使用了 PUB
和 SUB
,但是可扩展的形式化通信模式原型却有一些故障有关如何配置它们的信息。
似乎试图实例化 PUB
原型,并使用.bindSync()
方法和cli参数args['pub']
接受该实例,使其具有单个AccessPoint。普通的tcp://
-传输类上的连接。
在为第二个实例定义事件处理程序.on( 'message', ... )
(即 SUB
原型)之后,此事件处理程序将成为.bindSync()
的一个访问点,使用tcp://
-transport-class来接收使用tcp://
-transport-class的连接。
如果确实必须在类似.send()
的原型上进行SUB
,则必须使用 XSUB
替代方法,在该方法中您可以发送数据并在PUB
端或XPUB
端使用实际有效负载执行一些技巧(有关ZMQ_XPUB_MANUAL
模式功能的详细信息,请参考API文档,并在{ {1}}端)
XPUB
与ZMQ_XSUB
相同,除了您通过向套接字发送订阅消息来进行订阅。订阅消息是字节1(用于订阅)或字节0(用于取消订阅),后跟订阅主体。也可以发送不带sub / unsub前缀的邮件,但不会影响订阅状态。
似乎可以实例化ZMQ_SUB
和.connect()
上的客户端本地原型,这些原型是PUB
-transport-class到服务器端访问点(两者都应将ZMQ_LINGER设置为0,以避免无限地挂起孤儿(版本相关的默认值没有其他解决方案,但对此有明确的设置))。
SUB
与tcp://
可以解决通过 XPUB/XSUB
-原型ZMQ_XPUB_MANUAL
与SUB
可以解决通过 XPUB/SUB
-原型进行的发送,而伪装要通过ZMQ_XPUB_MANUAL
发送的消息的舒适度较低-方法SUB
,并严格通过本地.subscribe()
原型实例制作所有PUB/SUB
。.send()
和PUB
参数明确显示ZMQ_SNDHWM
方法后才明确设置ZMQ_RCVHWM
(系统地使用原始.subscribe()
和{ .bind() + .connect() }
函数主动检测和修复潜在的碰撞状态) zmq_errno()
请求仅使用完整的连接(分布式系统对自治分布式(许多)代理执行的操作顺序进行零保证)