1

スタックオーバーフローに質問を投稿するのはこれが初めてです。質問やアプローチに何か問題がある場合は、ご容赦ください。私は自分の問題の答えを見つけるために多くの検索を行いましたが、それを理解することができませんでした。これが私がやろうとしていることです。RabbitMQ ローカルホストに接続してメッセージを取得する WCF サービスを作成しました。WCF サービスを使用するコンソール プログラムを作成しました。ここで、WCF が RabbitMQ から取得したメッセージがコンソール プログラムに返されるようにしたいのですが、WCF は今後のメッセージを取得するのを待っています。私が見た例では、デリゲートとイベントを使用して、メッセージを Windows フォーム アプリケーションに戻していました。これをコンソール プログラムに実装するのが困難です。以下は私のWCFコードです。

public class MessageQueueSvc : IService1
{
    public string HOST_NAME = "localhost";
    public string EXCHANGE_NAME = "MyExchange";
    public string QUEUE_NAME = "MyMessageQ1";
    public string ROUTING_KEY = "";

    protected bool isConsuming;
    public delegate void onReceiveMessage(byte[] message);
    public event onReceiveMessage onMessageReceived;

    public IModel Model { get; set; }
    public IConnection Connection { get; set; }
    public Subscription mSubscription { get; set; }

    public string Hello(string name)
    {
        return "Hello";
    }

    public void StartConsuming()
    {
        isConsuming = true;

        var connectionFactory = new ConnectionFactory();
        connectionFactory.HostName = "localhost";
        Connection = connectionFactory.CreateConnection();

        //connect the model, exchange, queue and bind them together
        bool durable = true;

        //after connection create a channel so that you can communicate with the broker thru this channel. 
        IModel channel = Connection.CreateModel();

        //after this declare an exchange and a queue and bind them together to this channel 
        if (!String.IsNullOrEmpty(EXCHANGE_NAME))
            channel.ExchangeDeclare(EXCHANGE_NAME, ExchangeType.Direct, durable);

        if (!String.IsNullOrEmpty(QUEUE_NAME))
        {
            channel.QueueDeclare(QUEUE_NAME, false, false, false, null);
            channel.QueueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY, null);
        }

        //once model,exchange, queue is created then start cosuming it. 
        bool autoAck = false;

        //create a subscription
        mSubscription = new Subscription(Model, QUEUE_NAME, autoAck);

        while (isConsuming)
        {
            BasicDeliverEventArgs e = mSubscription.Next();
            byte[] body = e.Body;
            String tempStr = System.Text.Encoding.UTF8.GetString(body);
            tempStr = "Processed message = " + tempStr;
            body = System.Text.Encoding.UTF8.GetBytes(tempStr);
            if (onMessageReceived != null)
            {
                //this is not working. I have to write an event handler or some sort of delegate to pass the message back to the calling program
                //and still waiting here for further messages from the server. 
                onMessageReceived(body);
            }
            mSubscription.Ack(e);
        }

    }
}
4

1 に答える 1

0

あなたのアプローチは少し間違っていると思います。

メソッドで現在行っているように、MessageQueueSvc クラスをインスタンス化するときに、接続、チャネル、およびコンシューマーを作成する必要がありますStartConsuming。ただし、メッセージの消費を行うための無限ループは作成しません。

代わりに、コンソール アプリが WCF クライアントを呼び出すときに、キューから消費する必要があります。

public string GetMessage()
{
  BasicDeliverEventArgs e = mSubscription.Next();
  byte[] body = e.Body;
  String tempStr = System.Text.Encoding.UTF8.GetString(body);
  tempStr = "Processed message = " + tempStr;
  body = System.Text.Encoding.UTF8.GetBytes(tempStr);
  mSubscription.Ack(e);

  if (onMessageReceived != null)
  {
    return tempStr;
  } 
  else
  {
    return null; //or throw some kind of exception...
  }
}
于 2013-03-27T22:51:35.110 に答える