DaveSenn/Stomp.Net

Compatibility with RabbitMQ

Closed this issue · 5 comments

bp74 commented

Hi,

I've tried to use your library with RabbitMQ, but without success. The problem is that the Start method from IConnection never returns, it blocks forever. The Connection itself does not throw any errors.

var connectionFactory = new ConnectionFactory(this.session.BrokerUri, new StompConnectionSettings
{
	UserName = this.session.User,
	Password = this.session.Password,
});

using (var connection = connectionFactory.CreateConnection())
{
	connection.ConnectionInterruptedListener += Connection_ConnectionInterruptedListener;
	connection.ConnectionResumedListener += Connection_ConnectionResumedListener;
	connection.ExceptionListener += Connection_ExceptionListener;
	connection.Start();  // Never Returns !!!
	
	// CUT CUT CUT
}

Do you have any idea what the problem could be? Thanks a lot!

Hi

I did some testing with RabbitMq.
In the RabbitMq Logs I found the following error messages:

2018-02-03 16:51:11.914 [info] <0.1417.0> accepting STOMP connection <0.1417.0> ([::1]:62144 -> [::1]:61613)
2018-02-03 16:51:12.097 [error] <0.1420.0> Error on Direct connection <0.1420.0>
vhost localhost not found
2018-02-03 16:51:12.098 [warning] <0.1417.0> STOMP login failed - not_allowed (vhost access not allowed)~n
2018-02-03 16:51:12.098 [error] <0.1417.0> STOMP error frame sent:
Message: "Bad CONNECT"
Detail: "Virtual host 'localhost' access denied"
Server private detail: none
2018-02-03 16:51:19.431 [info] <0.1417.0> closing STOMP connection <0.1417.0> ([::1]:62144 -> [::1]:61613)

Stomp.Net adds the name of the broker host as “host” header to the Stomp CONNECT frame.
RabbitMq interprets the host header as the name of the virtual host to which the client tries to connect.
Since RabbitMq cannot find a matching virtual host, the broker sends a ERROR frame as response.

RabbitMq documentation:

https://www.rabbitmq.com/vhosts.html
https://www.rabbitmq.com/stomp.html

The CONNECT (or STOMP) frame in STOMP 1.1 has a mandatory host header (to select the virtual host to use for the connection). The RabbitMQ adapter allows this to be optional.
….
When omitted, the default virtual host (/) is presumed. To configure a different default virtual host, add a default_vhost section to the rabbitmq_stomp application configuration, e.g.

…This is why it did not work.
Maybe creating a matching virtual host (e.g localhost or the name/IP you use to connect to the broker host) within RabbitMq would work. But this doesn’t seem to be an optimal solution.

To the question why it silently fails…

After sending the CONENCT frame Stomp.Net expects a response with a matching id, but RabbitMq seems to not set this id. This causes the library to kind of ignore the received message and not perform the correct actions based on the message’s content (in this case close the connection and throw an exception).

I will change the implementation, so that an error gets thrown in case of an ERROR frame with a “wrong” id.

Stomp.Net logs problems like this if a logger is set.
A logger can be any class implementing ITrace.
You can set a logger like this:

Tracer.Trace = new ConsoleLogger();

Here you can find an example logger which just writes all messages the console: https://gist.github.com/DaveSenn/92265c1ba45afe258afb9b13c28c5b93

Since the host header is responsible for the problem and is optional for RabbitMq, I will check if it is possible to create a new option to not set the host header.

bp74 commented

Thanks a lot for the detailed analysis. Unfortunately i have to use the default virtual host "/" and can't change this, since other services are using the existing configuration of RabbitMQ. So hopefully there is a solution which works with the default virtual host.

I’ve implemented the option to not send a host header.
To enable the option, you just have to set StompConnectionSettings.SetHostHeader to false.
If you ever have to work with another virtual host you can manually override the value of the host header by setting StompConnectionSettings.HostHeaderOverride.

The changes are pushed and will be published as a new version (1.2.1.29) of the NuGet package (as soon as nuget.org has it indexed)

bp74 commented

Awesome! Thank you very much for those changes.
I will test it on Monday and let you know how it works.

Hi Bernhard
Did you have the time to test the new version?
Does the change work for you?