简体   繁体   English

PUB / SUB Api没有发送回消息,这可能是什么问题?

[英]PUB/SUB Api doesn't send messages back, what might be the problem?

I have almost completed pub/sub fake-server, that requests user password and email (from the client), compares this info with database and returns data back. 我几乎完成了pub / sub伪造服务器,该服务器请求用户密码和电子邮件(来自客户端),将该信息与数据库进行比较并返回数据。 It has 'api_in' and 'api_out' frames and then the JSON. 它具有“ api_in”和“ api_out”框架,然后是JSON。 The publisher takes and processes all the info without a hitch, but it doesn't seem to send anything back to the client (subscriber) and I don't know why, cause it is connected to the subsequent port. 发布者可以毫不费力地获取和处理所有信息,但似乎没有将任何信息发送回客户端(订户),我也不知道为什么,因为它已连接到后续端口。

And I know that this implementation is not a classic PUB/SUB pattern, but that was prerequisite, to do it like that. 而且我知道此实现不是经典的PUB / SUB模式,但这是做到这一点的前提。

I tried different pub/sub options, but nothing has changed. 我尝试了不同的pub / sub选项,但没有任何改变。

Server 服务器

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']}`);

client 客户

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);
}); 

I want the server side to send info back. 我希望服务器端发回信息。

Your server is trying to send on the sub socket 您的服务器正在尝试在子套接字上发送

subSocket.send(outMessage);

You can't send on the sub socket. 您无法发送子插座。 It should be sending on a pub socket. 它应该在pub套接字上发送。

Well, first of all, welcome to the Zen-of-Zero domain. 好吧,首先,欢迎来到零禅的领域。 ZeroMQ is a powerful tool for smart signaling / messaging, so if you pay attention to all its internal beauties, there will be no such thing you will not be able to do with it ( nightmares still not avoided on this way forward ). ZeroMQ是用于智能信令/消息传递的功能强大的工具,因此,如果您注意其所有内部美感,那么您将无法使用它(无法避免这种噩梦)。 If feeling to be new to this domain, one may enjoy a short read into "ZeroMQ Principles in less than Five Seconds " before diving into further details on subject, or re-use some of tricks posted here 如果您感觉不熟悉该领域,可以在阅读有关该主题的更多详细信息之前,先阅读一下不到五秒钟的 ZeroMQ 原理 ,或者重新使用此处发布的一些技巧

Q : it doesn't seem to send anything back to the client (subscriber) and I don't know why 它似乎没有将任何内容发送回客户端(订户),我也不知道为什么

There are two pieces of code, that seem to use both PUB and SUB Scalable Formal Communication Pattern Archetypes, yet have some glitches on how these get configured. 有两段代码似乎同时使用PUBSUB可伸缩形式通信模式原型,但是在如何配置它们方面存在一些故障。


The server-code : 服务器代码:

seems to try to instantiate PUB -archetype and equips that instance with a single AccessPoint, using .bindSync() -method and cli-parameter args['pub'] for accepting connections over a plain and common tcp:// -transport-class. 似乎尝试使用.bindSync() - .bindSync()和cli-parameter args['pub']来实例化PUB原型并为该实例配备单个.bindSync() ,以通过普通且通用的tcp:// -transport-class接受连接。

After defining the event-handler .on( 'message', ... ) for the second instance, being the SUB -archetype, this one becomes .bindSync() -equipped with a single AccessPoint, using tcp:// -transport-class, for receiving connections using tcp:// -transport-class. 定义事件处理程序之后.on( 'message', ... )的第二个实例,作为SUB -archetype,这一个变成.bindSync() -equipped与单个存取点,使用tcp:// -transport-类,用于使用tcp:// -transport-class接收连接。

If you indeed have to make a .send() over a SUB -alike archetype, you have to use XSUB alternative, where you can send data and perform some tricks with the actual payload on the PUB -side or XPUB -side ( ref. API documentation for details about ZMQ_XPUB_MANUAL mode capabilities and limits for some wilder data-mangling on the XPUB -side ) 如果确实必须通过类似SUB原型进行.send()操作,则必须使用XSUB替代方法,在该方法中,您可以发送数据并使用PUB端或XPUB端的实际有效负载执行一些技巧(请XPUB 。 API文档,以获取有关ZMQ_XPUB_MANUAL模式功能的详细信息,以及XPUB端一些荒谬的数据处理限制)

ZMQ_XSUB

Same as ZMQ_SUB except that you subscribe by sending subscription messages to the socket. ZMQ_SUB相同,除了您通过向套接字发送订阅消息来进行订阅。 Subscription message is a byte 1 (for subscriptions) or byte 0 (for unsubscriptions) followed by the subscription body. 订阅消息是字节1(用于订阅)或字节0(用于取消订阅),后跟订阅主体。 Messages without a sub/unsub prefix may also be sent, but have no effect on subscription status. 也可以发送不带sub / unsub前缀的消息,但对订阅状态没有影响。


The client-code : 客户端代码:

Seems to instantiate and .connect() both the client-local PUB and SUB Archetypes over tcp:// -transport-class to the server-side AccessPoints ( which both ought to set ZMQ_LINGER to 0, so as to avoid infinitely hanging orphans ( version dependent defaults do not have other solution but an explicit setting on this ) ). 似乎要通过tcp:// -transport-class实例化和本地.connect()客户端PUBSUB原型到服务器端访问点(两者都应将ZMQ_LINGER设置为0,以避免无限地挂起孤儿(版本相关的默认值没有其他解决方案,而是对此)的显式设置。


Possible improvements : 可能的改进:

  • XPUB/XSUB with ZMQ_XPUB_MANUAL may solve the sending via SUB -archetype 具有ZMQ_XPUB_MANUAL XPUB/XSUB可以解决通过SUB -archetype发送
  • XPUB/SUB with ZMQ_XPUB_MANUAL may solve the sending via SUB -archetype with less comfort of masquerading the messages to be sent via the .subscribe() -method 具有ZMQ_XPUB_MANUAL XPUB/SUB可以解决通过SUB原型发送的问题,而伪装要通过.subscribe()方法发送的消息的舒适性较低。
  • PUB/SUB with making all .send() -s strictly via a local PUB -archetype instance. 通过本地PUB原型实例严格执行所有.send() s的PUB/SUB
  • be explicit with ZMQ_SNDHWM and ZMQ_RCVHWM parameters if still loosing messages 如果仍然丢失消息,则使用ZMQ_SNDHWMZMQ_RCVHWM参数明确
  • be explicit on setting .subscribe() only after a successfully completed { .bind() + .connect() } -methods ( systematically using original zmq_errno() and zmq_strerror() functions for actively detecting and repairing the potential colliding states ) 仅在成功完成{ .bind() + .connect() }方法(系统地使用原始zmq_errno()zmq_strerror()函数主动检测并修复潜在的碰撞状态)之后才明确设置.subscribe() )。
  • may request to work with only completed connections ( distributed systems have zero-warranty of an order of operations autonomous distributed (many) agents perform ) using .setsockopt( ZMQ_IMMEDIATE, 1 ) 可以使用.setsockopt( ZMQ_IMMEDIATE, 1 )请求仅使用完整的连接(分布式系统对自治分布式(许多)代理执行的操作顺序进行零保证.setsockopt( ZMQ_IMMEDIATE, 1 )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM