stomp-js / stompjs

Javascript and Typescript Stomp client for Web browsers and node.js apps
Apache License 2.0
763 stars 81 forks source link

HowTo: broker failover support #225

Open genadis opened 4 years ago

genadis commented 4 years ago

Hi,

It would be great if the project supported the ActiveMQ failover. As mentioned here: https://activemq.apache.org/components/cms/stomp-support With Stomp protocol there are limitation to the supported failover that can be accomplished. But adding support for basic multiple uri destinations for reconnects in form of: failover:(uri1,...,uriN) Can be achieved relatively easily.

Currently the Client supports only single uri for the brokerUrl. It could support the failover format and select different uri on connection failure/disconnection.

The user of the library could manage the logic outside the library by listening to onWebSocketClose and changing the client.brokerUrl. Or using the beforeConnect hook.

native support would be great feature.

Below is what I'm using in my wrapper for the stomp client:

        this.brokerUrls = [];
        this.activeBrokerIndex = 0;

        const config: StompConfig = {
            // ...
            beforeConnect: () => {
                this.client.brokerURL = this.brokerUrls[this.activeBrokerIndex];
                this.activeBrokerIndex += 1;
                if (!this.brokerUrls[this.activeBrokerIndex]) {
                    this.activeBrokerIndex = 0;
                }
            }
        };

        const brokerURL = config.brokerURL.replace(/\s/g, '');
        const match = brokerURL.match(/failover:\((.*?)\)/i);
        this.brokerUrls = match && match[1] ? match[1].split(',') : [brokerURL];
        config.brokerURL = this.brokerUrls[0];

        this.client = new Client(config);
kum-deepak commented 4 years ago

I will suggest to use beforeConnect. While implementing within the library as well we should use this callback.

Will you be able to do a PR, please :smile:

I think we will need to extend our testing framework in order to test this feature. Current test setup uses a RabbitMQ server locally using docker. We can possibly run two RabbitMQ servers on different ports.

genadis commented 4 years ago

@kum-deepak I've updated the description with reference code I'm using :)

genadis commented 4 years ago

@kum-deepak The more I think about it, maybe it's better to keep such support to the user of the library, it's flexible enough.

For couple of reasons:

  1. There can be different failover url formats, which will require defining parse callback etc..
  2. The user might want to use different selection algorithm (random/based on priority etc), again another callback..
  3. Will introduce additional complexity and less control for the user of the library. It's actually would be more complicated to implement as part of the library than for the user of the library, edge cases to think about..
  4. probably others that I don't think of...

so maybe just add example code similar to what I've posted to FAQ/User guide.

It's not because I'm lazy.. ;)

kum-deepak commented 4 years ago

That makes sense. It will be good to add to FAQs. I will suggest following changes:

The documentation uses GutHub pages (internally Jekyll). All FAQ entries are inside https://github.com/stomp-js/stomp-js.github.io/tree/master/_faqs. Name the file based on the question. The header metadata has question, group, and order. Let me know if you need more details.