2013-03-13 108 views
2

我有一個Azure服務總線隊列。我想使用REST API將消息發佈到隊列中,但使用IIS託管的WCF服務使用netMessagingBinding來接收消息。通過REST發送消息到服務總線隊列並通過TCP接收消息?

有沒有人有資源的鏈接來演示這個?或者是否有人能夠提供如何使用REST POST將消息推送到隊列,然後使用netMessagingBinding接收代碼示例?

我相信這是看完這個可能:

您可以發送和接收郵件使用REST或.NET託管API,混合,在給定的情況下使用不同的協議匹配客戶端或服務。例如,您可以使用一種協議將消息發送到隊列,並使用不同的協議使用它。

http://msdn.microsoft.com/en-us/library/windowsazure/hh780717.aspx

我能夠使用netMessagingBinding推送消息到隊列中,並使用netMessagingBinding接收。我也可以使用REST POST將消息推送到隊列,然後使用REST DELETE從隊列中接收和刪除消息。我只是不能REST張貼消息並通過netMessagingBinding接收

回答

3

NetMessagingBinding始終使用BinaryMessageEncodingBindingElement + NetMessagingTransportBindingElement構建通道堆棧。如果ServiceBus隊列/訂閱中的BrokeredMessages是普通的[text] xml,那麼BinaryMessageEncoding將不起作用,使用WCF您將使用帶有TextMessageEncoder和NetMessagingTransportBindingElement的CustomBinding。

總之,您需要使用帶有TextMessageEncodingBindingElement(具有MessageVersion = None)的CustomBinding和NetMessagingTransportBindingElement,確保Action =「*」,並在您的ServiceBehavior上設置AddressFilterMode = Any。

下面是使用NetMessagingTransportBindingElement讀一個普通的舊XML消息兩種方式:

解決方案#1 使用System.ServiceModel.Channels.Message中的ServiceContract和調用Message.GetBody()

namespace MessagingConsole 
{ 
    static class Constants { 
     public const string ContractNamespace = "http://contoso"; 
    } 

    [DataContract(Namespace = Constants.ContractNamespace)] 
    class Record 
    { 
     [DataMember] 
     public string Id { get; set; } 
    } 

    [ServiceContract] 
    interface ITestContract 
    { 
     [OperationContract(IsOneWay = true, Action="*")] 
     void UpdateRecord(Message message); 
    } 

    [ServiceBehavior(
     AddressFilterMode = AddressFilterMode.Any)] // This is another way to avoid 「The message with To 」 cannot be processed at the receiver…」 
    class TestService : ITestContract 
    { 
     [OperationBehavior] 
     public void UpdateRecord(Message message) 
     { 
      Record r = message.GetBody<Record>(); 
      Console.WriteLine("UpdateRecord called! " + r.Id); 
     } 
    } 

    class ServiceProgram 
    { 
     static void Main(string[] args) 
     { 
      string solution = "sb://SOMENS"; 
      string owner = "owner"; 
      string key = "XXXXXX="; 
      string topicPath = "Topic2"; 
      string subscriptionName = "Sub0"; 
      TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(owner, key); 

      MessagingFactory factory = MessagingFactory.Create(solution, tokenProvider); 
      TopicClient sender = factory.CreateTopicClient(topicPath); 
      SubscriptionClient receiver = factory.CreateSubscriptionClient(topicPath, subscriptionName, ReceiveMode.ReceiveAndDelete); 

      string interopPayload = "<Record xmlns='" + Constants.ContractNamespace + "'><Id>4</Id></Record>"; 
      BrokeredMessage interopMessage = new BrokeredMessage(new MemoryStream(Encoding.UTF8.GetBytes(interopPayload)), true); 
      sender.Send(interopMessage); 

      CustomBinding binding = new CustomBinding(
       new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.None }, 
       new NetMessagingTransportBindingElement()); 
      ServiceHost serviceHost = new ServiceHost(typeof(TestService), new Uri(solution)); 
      ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(ITestContract), binding, topicPath + "/Subscriptions/" + subscriptionName); 
      endpoint.Behaviors.Add(new TransportClientEndpointBehavior(tokenProvider)); 
      serviceHost.Open(); 
      Console.WriteLine("Service is running"); 
      Console.ReadLine();    
     } 
    } 
} 

解決方案#2 定義MessageContract數據類型,來使預期肥皂合同匹配什麼互操作的客戶端發送:

namespace MessagingConsole 
{ 
    static class Constants 
    { 
     public const string ContractNamespace = "http://contoso"; 
    } 

    [DataContract(Namespace = Constants.ContractNamespace)] 
    class Record 
    { 
     [DataMember] 
     public string Id { get; set; } 
    } 

    [MessageContract(IsWrapped=false)] 
    class RecordMessageContract 
    { 
     [MessageBodyMember(Namespace = Constants.ContractNamespace)] 
     public Record Record { get; set; } 
    } 

    [ServiceContract] 
    interface ITestContract 
    { 
     [OperationContract(IsOneWay = true, Action="*")] 
     void UpdateRecord(RecordMessageContract recordMessageContract); 
    } 

    class ServiceProgram 
    { 
     static void Main(string[] args) 
     { 
      string solution = "sb://SOMENS"; 
      string owner = "owner"; 
      string key = "XXXXXXXXXXXXXX="; 
      string topicPath = "Topic2"; 
      string subscriptionName = "Sub0"; 
      TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(owner, key); 

      MessagingFactory factory = MessagingFactory.Create(solution, tokenProvider); 
      TopicClient sender = factory.CreateTopicClient(topicPath); 
      SubscriptionClient receiver = factory.CreateSubscriptionClient(topicPath, subscriptionName, ReceiveMode.ReceiveAndDelete); 

      string interopPayload = "<Record xmlns='" + Constants.ContractNamespace + "'><Id>5</Id></Record>"; 
      BrokeredMessage interopMessage = new BrokeredMessage(new MemoryStream(Encoding.UTF8.GetBytes(interopPayload)), true); 
      sender.Send(interopMessage); 

      CustomBinding binding = new CustomBinding(
       new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.None }, 
       new NetMessagingTransportBindingElement()); 
      ServiceHost serviceHost = new ServiceHost(typeof(TestService), new Uri(solution)); 
      ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(ITestContract), binding, topicPath + "/Subscriptions/" + subscriptionName); 
      endpoint.Behaviors.Add(new TransportClientEndpointBehavior(tokenProvider)); 
      serviceHost.Open(); 
      Console.WriteLine("Service is running"); 
      Console.ReadLine(); 
     } 
    } 

    [ServiceBehavior(
     AddressFilterMode = AddressFilterMode.Any 
     )] 
    class TestService : ITestContract 
    { 
     [OperationBehavior] 
     public void UpdateRecord(RecordMessageContract recordMessageContract) 
     { 
      Record r = recordMessageContract.Record; 
      Console.WriteLine("UpdateRecord called! " + r.Id); 
     } 
    } 
}