NServiceBus Home

Contents

  • Long-Running Processes
  •     Sagas

NServiceBus Attachments Sample

Large chunks of data, such as images or video files can be transported using NServiceBus v3 data bus.
The only thing you have to do is put an attribute over your large property and NServiceBus will take care of the rest.

This is particularly important when running in cloud environments where limits on message size is usually much lower than on-premise.

In order to see how to send and receive attachments in NServiceBus, open the Databus sample.

First of all run the solution.
You should see two console applications start up.
Find the Sender application by looking for the one with "Sender" in its path and press 'Enter' in the window to send a message.
You have just sent a message that is larger than the allowed 4 Mb by MSMQ.
NServiceBus will send it as an attachment, allowing it to reach to the Receiver application.

Then, press the 'e' and 'Enter'. Larger than the allowed 4 Mb message is sent, but this time, without utilizing NServiceBus attachments mechanism. An exception is thrown at the "Sender" application. You consoles view should like the following:

Databus sample Running

let's go look at the code:

Databus solution explorer view

Code Walk-Through

This sample contains three projects:

  1. Receiver.Messages This is a class library containing the sample messages. As we will later see only one of the message types  utilize the NSERviceBus DataBus.
  2. Sender This is a class library, hosted by NServiceBus host. It is responsible to send the large messages.
  3. Receiver This is a class library, hosted by NServiceBus host. It is responsible to receive the large messages being sent from the server.

Receiver.Messages project

Lets have a look at the Receiver.Messages project, at the two defined messages.

Lets start with the large one, that is not utilizing Databus mechanism:

publicc class AnotherMessageWithLargePayload : IMessage
{
    public byte[]LargeBlob { get; set; }
}

The above message is a simple byte array message.

Lets examine the other message, that is utilizing Databus mechanism:

 

[TimeToBeReceived("00:01:00")]
public class MessageWithLargePayload:IMessage
{
    public string SomeProperty { get; set; }
    public DataBusProperty<byte[]> LargeBlob { get; set; }
}

The thing to pay attention to is the following type

DataBusProperty<byte[]>

This is an NServiceBus data type that instruct NServiceBus to treat the LargeBlob property as an attachment.
It will not be transported in NServiceBus normal flow.

Let's understand the following attribute:

[TimeToBeReceived("00:01:00")] 

When sending a message using the NServiceBus Message attachments mechanism, the message's payload resides in the folder, in addition, a  'signaling' message is sent to the Receiving endpoint.
The above attribute, Instruct NServiceBus framework that it is allowed to clean the MSMQ message after 1 minute, if it was not received by the receiver.
The message payload, will remain Storage folder after the MSMQ message will be cleaned by the NServiceBus framework. 

The following is an example of the 'signaling' message that will be sent to the receiving endpoint:

<?xml version="1.0"?>
<Messages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns="http://tempuri.net/Receiver.Messages">
  <MessageWithLargePayload>
    <SomeProperty>This message contains a large blob that will be sent on the data bus</
    SomeProperty>
    <LargeBlob>
        <Key>2012-01-02_10\f83e3641-4588-4cb2-8c4f-4077342ed32e</Key>
        <HasValue>true</HasValue>
    </LargeBlob>
  </MessageWithLargePayload>
</Messages>

Sender

Lets look at the Sender project, to see how to configure the NServiceBus to use to handle attachments. Lets start with Sender project app.config:

<MessageEndpointMappings>
            <add Messages="Receiver.Messages" Endpoint="Receiver" />
        </MessageEndpointMappings>

The sender instructing NServiceBus to send messages with Namespace equal to Receiver.Messages to the Receiver endpoint

Lets open the EndpointConfig in the Sender project:

public static string BasePath = "..\\..\\..\\storage";

public void Init()
{
    Configure.Instance
        .FileShareDataBus(BasePath)
        .UnicastBus().DoNotAutoSubscribe();//until ICommand is introduced
}

This code, instructs NServiceBus to use FileSharing transport mechanism for the attachment.
The message's payload will be store on the file system in the Storage folder.

The DoNotAutoSubscribe tells NServiceBus not to use a publish/subscribe mechanism. If we were using ICommand for our large message, no automatically subscription was to occur.
Since we are implementing IMessage, we need this instruction.

The following Sender project code, send the MessageWithLargePayload message utilizing NServiceBus attachment mechanism:

bus.Send<MessageWithLargePayload>(m =>
{
    m.SomeProperty = "This message contains a large blob that will be sent on the data bus";
    m.LargeBlob = new DataBusProperty<byte[]>(new byte[1024 * 1024 * 5]);//5MB
});

The following Sender project code, send the AnotherMessageWithLargePayload message without utilizing NServiceBus attachment mechanism:

bus.Send<AnotherMessageWithLargePayload>(m =>
{
    m.LargeBlob = new byte[1024 * 1024 * 5];//5MB
});

In both cases, a 5Mb message is being sent, but in the MessageWithLargePayload will go through while the AnotherMessageWithLargePayload will fail.

Lets see to the Receiver project to see that the receiving application:

Receiver Project

The endpoint configuration code of Receiver is identical to this of the Sender:

Lets open the EndpointConfig in the Sender project:

public static string BasePath = "..\\..\\..\\storage";

public void Init()
{
    Configure.Instance
        .FileShareDataBus(BasePath)
        .UnicastBus().DoNotAutoSubscribe();
}

The following is the receiving message handler:

public class MessageWithLargePayloadHandler : IHandleMessages<MessageWithLargePayload>
{
    public void Handle(MessageWithLargePayload message)
    {
        Console.WriteLine("Message received, size of blob property: " + 
message.LargeBlob.Value.Length + " Bytes");
    }
}

Where to go next?

If you are not familiar with Unobtrusive messaging mode, read the documentation here or see the working sample here.

Legal

“NServiceBus” is among the trademarks of NServiceBus Ltd. All other product and company names and marks mentioned are the property of their respective owners and are mentioned for identification purposes only.

© 2010-2012 NServiceBus Ltd. All rights reserved.