【问题标题】:How to consume RabbitMQ in WCF?如何在 WCF 中使用 RabbitMQ?
【发布时间】:2017-09-06 09:19:15
【问题描述】:

我有一个场景,其中可执行文件是生产者,WCF 服务是消费者。

WCF服务工作流程如下:

1)Service调用可执行文件(生产者),这个可执行文件是另一个进程,它产生消息到RabbitMQ队列中。

2)Service 必须消费来自 RabbitMQ Queue 的消息

3)将数据返回给客户端。

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ConnectionServices
{

    public class Connection : IConnection
    {
        public string ConnectSite(string provider, string server, string siteName)
        {
            InvokeProducer(provider, server, siteName);
            string activeInstance = RunRabbitMQ();
            return activeInstance;

        }
        public void InvokeProducer(string provider, string server, string siteName)
        {
            string siteManagerExePath = @"C:\Users\mbmercha\Documents\Visual Studio 2015\Projects\Producer\Producer\bin\Debug\Producer.exe";
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                Process siteManagerProcess = new Process();
                startInfo.FileName = siteManagerExePath;
                startInfo.Arguments = string.Format("{0} {1} {2} {3}", "-b ", provider, server, siteName);
                siteManagerProcess.StartInfo = startInfo;
                siteManagerProcess.Start();
                siteManagerProcess.WaitForExit();

            }
            catch (Exception e)
            {

            }
        }
        public string RunRabbitMQ()
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            string activeInstance = null;
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare("DurableQueue", true, false, false, null);
                channel.ExchangeDeclare("DurableExchange", ExchangeType.Topic, true);
                channel.QueueBind("DurableQueue", "DurableExchange", "durable");
                var consumer = new EventingBasicConsumer(channel);

                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    activeInstance = message;
                };
                channel.BasicConsume(queue: "DurableQueue",
                                     autoAck: false,
                                     consumer: consumer);


            }
            return activeInstance;
        }
    }
}

到目前为止,服务能够调用可执行文件并在队列中生成消息。

但服务从第 2 步开始失败,它返回 null 而不是实际消息。 有人可以建议我在这里缺少什么吗?

提前致谢。

【问题讨论】:

  • 这两行使用了activeInstancestring activeInstance = null; return activeInstance; 你从来没有设置这个变量。
  • 这是我的拼写错误。在实际代码中它是正确的,但我仍然得到 null @Reniuz
  • 所以请添加实际代码。现在消息必须为空,但不能因为 GetString() 返回字符串。
  • 我已经编辑了代码@Reniuz
  • 你的问题与 WCF 完全无关。

标签: c# wcf rabbitmq wcf-binding


【解决方案1】:

您永远不会将activeInstance 设置为除null 之外的任何内容。

您似乎正在使用异步 API,这意味着您在 RunRabbitMQ 方法调用完成很久之后才从 RabbitMQ 检索消息......或者如果您没有立即处理所有退货时的消费机械。

如果您想同步检索消息 - 在这种情况下,在同步方法调用中 - 您需要等待消息可用。为此,您需要使用“pull API”,即channel.BasicGet(...)

【讨论】:

  • 这是我的拼写错误。在实际代码中它是正确的,但我仍然得到 null @yaakov
  • 您仍然存在同步性问题 - 您正在从事件中设置变量,但在方法完成之前事件不会被触发。
  • 我发现从 WCF 服务中,事件没有被触发。虽然我用控制台应用程序测试了相同的代码并且事件被触发并且我能够返回值。你能帮忙吗,为什么它不能在 WCF 中触发? @yaakov
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
  • 2016-01-21
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
相关资源
最近更新 更多