Node.js 在nodeJS中使用amqplib复制EasyNetQ请求/响应

Node.js 在nodeJS中使用amqplib复制EasyNetQ请求/响应,node.js,amqp,Node.js,Amqp,我正在NodeJS中复制EasyNetQ功能(这样节点应用程序就可以通过启用EasyNetQ的.NET应用程序通过Rabbit进行通信)。我复制了EasyNetQ的发布/订阅和EasyNetQ的发送/接收,但是EasyNetQ的请求/响应有些困难 以下是我当前的节点代码: var rqrxID = uuid.v4(); //a GUID var responseQueue = 'easynetq.response.' + rqrxID; Q(Play.AMQ.ConfirmChannel.as

我正在NodeJS中复制EasyNetQ功能(这样节点应用程序就可以通过启用EasyNetQ的.NET应用程序通过Rabbit进行通信)。我复制了EasyNetQ的发布/订阅和EasyNetQ的发送/接收,但是EasyNetQ的请求/响应有些困难

以下是我当前的节点代码:

var rqrxID = uuid.v4(); //a GUID
var responseQueue = 'easynetq.response.' + rqrxID;

Q(Play.AMQ.ConfirmChannel.assertQueue(responseQueue, { durable: false, exclusive: true, autoDelete: true }))
.then((okQueueReply) =>
    Play.AMQ.ConfirmChannel.consume(responseQueue, (msg) => {
        //do something here...
        Play.AMQ.ConfirmChannel.ack(msg);
    })
)
.then((okSubscribeReply) => {
    Q(Play.AMQ.ConfirmChannel.assertExchange('easy_net_q_rpc', 'direct', { durable: true, autoDelete: false }))
    .then((okExchangeReply) =>
        Play.AMQ.ConfirmChannel.publish(
            global.AppConfig.amq.rpc.exchange,
            dto.AsyncProcessorCommand.Type,
            Play.ToBuffer(command),
            { type: command.GetType() },
            (err, ok): void => {
                if (err !== null) {
                    console.warn('Message nacked!');
                    responseDeferred.reject(err);
                }
            }
        )
    )
})
.catch((failReason) => {
    console.error(util.format('Error creating response queue: %s', failReason));
    return null;
});
请注意,发布工作并由.NET代码接收。然后,该代码发送一个响应,问题是没有收到响应。以下是.NET代码:

Bus.Respond<AsyncProcessorCommand, AsyncProcessorCommandResponse>(
    request =>
    {
        Console.WriteLine("Got request: '{0}'", request);
        return new AsyncProcessorCommandResponse()
        {
            ID = Guid.NewGuid(),
            ResponseType = "ENQResp"
        };
    });
Bus.response(
请求=>
{
WriteLine(“获取请求:'{0}',请求);
返回新的AsyncProcessorCommandResponse()
{
ID=Guid.NewGuid(),
ResponseType=“ENQResp”
};
});
我肯定我遗漏了什么,但不确定是什么。谁能帮忙

更新 我至少解决了部分问题。获取responseQueue的值并将其设置为publish的选项为“replyTo”,这将钩住响应—很好。现在我只需要弄清楚如何不每次创建一个新队列,或者让响应队列消失

更新最终版本
因此,使用我拥有的频道设置并保存cinsumerTag(实际上,指定它)允许我取消消费者和自动删除队列。

从上面的评论中回答这个问题

这有两个部分。首先,根据上面的代码,创建响应队列,使其自动删除(当消费者计数降至0时):

然后创建/发布到“服务器”正在侦听的队列-确保为刚刚创建的响应队列设置“replyTo”(类型部分是ENQ所需的另一段代码):

因此,用于执行此模式的整个(当前混乱的“播放”代码)方法如下所示:

private static Request(command: dto.AsyncProcessorCommand): Q.Promise<dto.interfaces.IAsyncProcessorCommandResponse> {
    var responseDeferred = Q.defer<dto.interfaces.IAsyncProcessorCommandResponse>();

    var consumerTag = uuid.v4();
    var rqrxID = uuid.v4();
    var responseQueue = 'easynetq.response.' + rqrxID;

    var handleResponse = (msg: any): void => {
        var respType = null;
        switch(command.Action) {
            default:
                respType = 'testResp';
        }

        //just sending *something* back, should come from 'msg'
        responseDeferred.resolve(new dto.AsyncProcessorCommandResponse(respType, { xxx: 'yyy', abc: '123' }));
    }

    Q(Play.AMQ.ConfirmChannel.assertQueue(responseQueue, { durable: false, exclusive: true, autoDelete: true }))
        .then((okQueueReply) =>
            Play.AMQ.ConfirmChannel.consume(responseQueue, (msg) => {
                handleResponse(msg);
                Play.AMQ.ConfirmChannel.ack(msg);
                Play.AMQ.ConfirmChannel.cancel(consumerTag);
            },
            { consumerTag: consumerTag })
        )
        .then((okSubscribeReply) => {
            Q(Play.AMQ.ConfirmChannel.assertExchange('easy_net_q_rpc', 'direct', { durable: true, autoDelete: false }))
            .then((okExchangeReply) =>
                Play.AMQ.ConfirmChannel.publish(
                    'easy_net_q_rpc',
                    dto.AsyncProcessorCommand.Type,
                    Play.ToBuffer(command),
                    { type: command.GetType(), replyTo: responseQueue },
                    (err, ok): void => {
                        if (err !== null) {
                            console.warn('Message nacked!');
                            responseDeferred.reject(err);
                        }
                    }
                )
            )
        })
        .catch((failReason) => {
            console.error(util.format('Error creating response queue: %s', failReason));
            return null;
        });

    return responseDeferred.promise
}
私有静态请求(命令:dto.AsyncProcessorCommand):Q.Promise{
var responseDeferred=Q.defer();
var consumerTag=uuid.v4();
var rqrxID=uuid.v4();
var responseQueue='easynetq.response.'+rqrxID;
var handleResponse=(消息:any):void=>{
var respType=null;
开关(命令动作){
违约:
respType='testResp';
}
//只是发送一些东西回来,应该来自“msg”
responseDeferred.resolve(新的dto.AsyncProcessorCommandResponse(respType,{xxx:'yyy',abc:'123'}));
}
Q(Play.AMQ.ConfirmChannel.assertQueue(responseQueue,{持久:false,独占:true,自动删除:true}))
。然后((okQueueReply)=>
Play.AMQ.ConfirmChannel.consume(responseQueue,(msg)=>{
HandlerResponse(msg);
Play.AMQ.ConfirmChannel.ack(msg);
Play.AMQ.ConfirmChannel.cancel(消费者代号);
},
{consumerTag:consumerTag})
)
.然后((okSubscribeReply)=>{
Q(Play.AMQ.ConfirmChannel.assertExchange('easy_net_Q_rpc','direct',{dustable:true,autoDelete:false}))
。然后((okExchangeReply)=>
Play.AMQ.ConfirmChannel.publish(
“简易网络”和“简易网络”,
dto.AsyncProcessorCommand.Type,
玩托布弗(指挥),
{type:command.GetType(),replyTo:responseQueue},
(错误,确定):无效=>{
如果(错误!==null){
console.warn('Message nacked!');
响应请求。拒绝(err);
}
}
)
)
})
.catch((失败原因)=>{
console.error(util.format('error creating response queue:%s',failReason');
返回null;
});
回信,回信,承诺
}
{ type: command.GetType(), replyTo: responseQueue }
private static Request(command: dto.AsyncProcessorCommand): Q.Promise<dto.interfaces.IAsyncProcessorCommandResponse> {
    var responseDeferred = Q.defer<dto.interfaces.IAsyncProcessorCommandResponse>();

    var consumerTag = uuid.v4();
    var rqrxID = uuid.v4();
    var responseQueue = 'easynetq.response.' + rqrxID;

    var handleResponse = (msg: any): void => {
        var respType = null;
        switch(command.Action) {
            default:
                respType = 'testResp';
        }

        //just sending *something* back, should come from 'msg'
        responseDeferred.resolve(new dto.AsyncProcessorCommandResponse(respType, { xxx: 'yyy', abc: '123' }));
    }

    Q(Play.AMQ.ConfirmChannel.assertQueue(responseQueue, { durable: false, exclusive: true, autoDelete: true }))
        .then((okQueueReply) =>
            Play.AMQ.ConfirmChannel.consume(responseQueue, (msg) => {
                handleResponse(msg);
                Play.AMQ.ConfirmChannel.ack(msg);
                Play.AMQ.ConfirmChannel.cancel(consumerTag);
            },
            { consumerTag: consumerTag })
        )
        .then((okSubscribeReply) => {
            Q(Play.AMQ.ConfirmChannel.assertExchange('easy_net_q_rpc', 'direct', { durable: true, autoDelete: false }))
            .then((okExchangeReply) =>
                Play.AMQ.ConfirmChannel.publish(
                    'easy_net_q_rpc',
                    dto.AsyncProcessorCommand.Type,
                    Play.ToBuffer(command),
                    { type: command.GetType(), replyTo: responseQueue },
                    (err, ok): void => {
                        if (err !== null) {
                            console.warn('Message nacked!');
                            responseDeferred.reject(err);
                        }
                    }
                )
            )
        })
        .catch((failReason) => {
            console.error(util.format('Error creating response queue: %s', failReason));
            return null;
        });

    return responseDeferred.promise
}