2013-03-13 125 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); 
     } 
    } 
}