다음을 통해 공유


Send Messages from TopicClient to WCF Subscription Service

How to send Message to ServiceBus topic using TopicClient and receive it with WCF as Subscription Service that acts as a Subscription client, without the use of SubscriptionClient classes of Service Bus?

Relevant Facts and Documentaion:

Solution:

Since the sender and receiver are based on two different technologies we have to make sure the encoding on both sides match and a WCF data contract is defined. Please follow the steps below. Also, here's a good blog where Abhishek (from Service Bus product group) talks about different ways of formatting the content for Service Bus Messages - https://abhishekrlal.com/2012/03/30/formatting-the-content-for-service-bus-messages/

  • Define the data contract

   static class Constants

    {

        public const string ContractNamespace = "urn:wcsubscriptionservice";

    }

 

    [DataContract(Namespace = Constants.ContractNamespace)]

    public class TestMessage

    {

        [DataMember]

        public string MsgNumber { get; set; }

        [DataMember]

        public string MsgContent { get; set; }

 

    }

  •  Format the brokered message when sending from client.

    BrokeredMessage message = new BrokeredMessage(new TestMessage() { MsgNumber = 1, MsgContent = "Test Message" }, new DataContractSerializer(typeof(TestMessage)));

                     // Send message to the topic

                     topicClient.Send(message);

  • Set the ListenURI in WCF Service:

……………………       

private static Uri serviceBusEndpointAddress = new Uri("sb://<namespace>.servicebus.windows.net/<topic>");

        private static Uri subscriptionUri = new

Uri("sb://<namespace>.servicebus.windows.net/<topic>/subscriptions/<subscription>");

 

……………………….

           var endpoint = new ServiceEndpoint(contract, binding, new

EndpointAddress(serviceBusEndpointAddress.AbsoluteUri));

            endpoint.ListenUri = subscriptionUri;

            endpoint.Behaviors.Add(transportBehavior);

            endpoint.Name = "ReceiveMessage";

 

  • Manually Control the Receive Context, if you would like the user code to control the incoming message for any further processing purposes.

 [ServiceContract(Namespace="urn:wcsubscriptionservice")]

    public interface IServiceBusReader

    {

        [OperationContract(IsOneWay = true, Action = "*"), ReceiveContextEnabled(ManualControl = true)]

        void ReceiveMessage(TestMessageContract someMsg);

    }

     

    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

    public class ServiceBusReader : IServiceBusReader

    {

        public void ReceiveMessage(TestMessageContract someMsg)

        {

            TestMessage msg = someMsg.TestMessage;

            var incomingProperties = OperationContext.Current.IncomingMessageProperties;

            var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;

            ReceiveContext receiveContext;

            if (ReceiveContext.TryGet(incomingProperties, out receiveContext))

            {

                receiveContext.Complete(TimeSpan.FromSeconds(10.0d));

            }

            else

            {

                throw new InvalidOperationException("...");

            }        

        }

    }

 

I've attached the sample code, please feel free to use it. Just make sure, you input the values for service bus namespace, key, topic name and subscription name.

Files: TopicSender.cs, WCFSubscriptionService.cs

TopicSenderAndWCFReceive.zip

Comments

  • Anonymous
    March 31, 2014
    Thanks for this great article!  I'm actually trying to do the opposite...  I want to use a MessageReciever to get dead-letter messages from a topic subscription that were originally sent to the topic via WCF using the NetMessageBinding.I'm receiving the messages just fine, but am unable to deserialize the body.  I think what I'm missing is they type of serializer that is used by the NetMessageBinding.  Any idea how to do this?Thanks!
  • Anonymous
    April 02, 2014
    Thanks for your feedback.Application using WCF and NetMessagingBinding wraps the message in soap envelope and encodes it.msdn.microsoft.com/.../hh532034.aspxHave you tried something like?receiveMessage.GetBody<T>(new DataContractSerializer(typeof(T)))Please refer to Abhishek's blog for more information on formatting of brokered messages.abhishekrlal.com/.../formatting-the-content-for-service-bus-messages
  • Anonymous
    January 10, 2016
    Hey I am tried using your code and service starts running but no messages on subscriber side. I am using this code on Windows Service Bus. Can you please help if I need to do some more configurations