James
James

Reputation: 541

Rebus with RabbitMQ accept requests from Python

I am setting up a .NET core service that is reading from RabbitMQ using Rebus. It seems that the request placed in RabbitMQ needs to have the .NET object namespace information. Is there a way to work around this. For example if I had a service written in Python placing items on the queue would it be possible to read and process these requests. It seems every time I test and try to send something besides the .NET object I get an exception.

System.Collections.Generic.KeyNotFoundException: Could not find the key 'rbs2-content-type' - have the following keys only: 'rbs2-msg-id'

Upvotes: 2

Views: 671

Answers (1)

mookid8000
mookid8000

Reputation: 18628

It depends on which serializer, you're using in the receiving end.

By default, Rebus will use its built-in JSON serializer with a fairly "helpful" setting, meaning that all .NET types names are included. This enables serialization of complex objects, including abstract/interface references, etc.

This serializer requires a few special headers to be present, though, e.g. the rbs2-content-type header, which it uses to verify that the incoming message presents itself as JSON (most likely by having application/json; charset=utf-8 as its content type).

If you want to enable deserialization of messages from other platforms, I suggest you provide the necessary headers on the messages (which – at least with Rebus' built-in serializer – also includes a .NET type name of the type to try to deserialize into).

Another option is to install a custom serializer, which is a fairly easy thing to do – you can get started by registering your serializer like this:

Configure.With(...)
    .(...)
    .Serialization(s => s.Register(c => new YourCrazySerializer()))
    .Start();

which you then implement somewhat like this:

public class YourCrazySerializer : ISerializer
{
    public async Task<TransportMessage> Serialize(Message message)
    {
        var headers = message.Headers.Clone();

        // turn into byte[] here
        //
        // possibly add headers

        return new TransportMessage(headers, bytes);
    }

    public async Task<Message> Deserialize(TransportMessage transportMessage)
    {
        var headers = transportMessage.Headers.Clone();

        // turn into object here
        //
        // possibly remove headers

        return new Message(headers);
    }
}

As you can see, it's pretty easy to modify Rebus to accept messages from other systems.

Upvotes: 3

Related Questions