spring-guides / gs-messaging-stomp-websocket

Using WebSocket to build an interactive web application :: Learn how to the send and receive messages between a browser and the server over a WebSocket

Home Page:http://spring.io/guides/gs/messaging-stomp-websocket/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Stomp client fails to connect to a dynamic controller destination that has a @DestinationVariable when I switch to use a StompBrokerRelay but it works with SimpleBroker

givenm opened this issue · comments

commented

Hi

When I switch the default config example in the project gs-messaging-stomp-websocket to use config.enableStompBrokerRelay("/topic"); the example works as when I had config.enableSimpleBroker("/topic");.

When I change the controller to use dynamic destinations with a SimpleBroker as below, it also works:

@MessageMapping("/hello/{id}")
@SendTo("/topic/greetings/{id}")
 public Greeting greeting(HelloMessage message, @DestinationVariable String id) throws Exception {
      Thread.sleep(1000); // simulated delay
      return new Greeting("Hello, " + message.getName() + " and id passed is " + id);
 }

But if I change the configuration to use Stomp broker with the above controller, my server app logs say:

2017-04-19 00:26:08.354 ERROR 14958 --- [eactor-tcp-io-3] o.s.m.s.s.StompBrokerRelayMessageHandler : Received ERROR {message=[Invalid destination], content-type=[text/plain], version=[1.0,1.1,1.2], content-length=[48]} session=uxmho5lj text/plain payload='/greetings/1' is not a valid topic destination

and the stomp client say:

Opening Web Socket...
stomp.min.js:8 Web Socket Opened...
stomp.min.js:8 >>> CONNECT
cool:something
accept-version:1.1,1.0
heart-beat:10000,10000


stomp.min.js:8 <<< PONG
stomp.min.js:8 <<< CONNECTED
session:session-kN6B9Jl7qyqx-lNHslTsPA
heart-beat:10000,10000
server:RabbitMQ/3.5.7
version:1.1


stomp.min.js:8 connected to server RabbitMQ/3.5.7
stomp.min.js:8 send PING every 10000ms
stomp.min.js:8 check PONG every 10000ms
app.js:20 Connected: CONNECTED
version:1.1
server:RabbitMQ/3.5.7
heart-beat:10000,10000
session:session-kN6B9Jl7qyqx-lNHslTsPA


stomp.min.js:8 >>> SUBSCRIBE
id:sub-0
destination:/topic/greetings/1


stomp.min.js:8 <<< ERROR
message:Invalid destination
content-type:text/plain
version:1.0,1.1,1.2
content-length:48

'/greetings/1' is not a valid topic destination

stomp.min.js:8 <<< PONG
stomp.min.js:8 Whoops! Lost connection to http://localhost:8080/gs-guide-websocket

The same code works with Simple broker but does not work with a StompBrokerRelay. Is there some further settings required for this to work with the same code or could this be an issue in BrokerRelay? I came across this post on stackoverflow and it doesn't see to work for me.

I added these dependencies when I turned on Broker relay:

        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-net</artifactId>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.9.Final</version>
        </dependency>

Thanks.

@rstoyanchev Can you take a look?

commented

@gregturn Is there a chance that this will be answered?

@givenm I don't need both a comment AND a frowny face asking for feedback. I've ask Rossen to take a peek, given this is his specialty, but being open source, I can't promise anything. If you had a support contract, we could certainly escalate. But your alternative would be soliciting Stackoverflow for more community response.

commented

@gregturn I apologise.

Sorry but I could not reproduce the issue. Worked fine for me:

Opening Web Socket...
stomp.min.js:8 Web Socket Opened...
stomp.min.js:8 >>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000

�
stomp.min.js:8 <<< PONG
stomp.min.js:8 <<< CONNECTED
session:session-0S9-_nqm2PS0zycrh9yrSw
heart-beat:10000,10000
server:RabbitMQ/3.5.7
version:1.1

�
stomp.min.js:8 connected to server RabbitMQ/3.5.7
stomp.min.js:8 send PING every 10000ms
stomp.min.js:8 check PONG every 10000ms
app.js:20 Connected: CONNECTED
version:1.1
server:RabbitMQ/3.5.7
heart-beat:10000,10000
session:session-0S9-_nqm2PS0zycrh9yrSw


stomp.min.js:8 >>> SUBSCRIBE
id:sub-0
destination:/topic/greetings

�
stomp.min.js:8 <<< PONG
stomp.min.js:8 >>> PING
stomp.min.js:8 <<< PONG
stomp.min.js:8 >>> PING
stomp.min.js:8 >>> SEND
destination:/app/hello
content-length:13

{"name":"rr"}�
stomp.min.js:8 <<< MESSAGE
subscription:sub-0
destination:/topic/greetings
message-id:T_sub-0@@session-0S9-_nqm2PS0zycrh9yrSw@@1
redelivered:false
content-type:application/json;charset=UTF-8
content-length:24

{"content":"Hello, rr!"}

That said I did not add a destination variable...

I see the issue now. RabbitMQ does not support "/" as a separator. You can do something like this:

stompClient.subscribe('/topic/greetings.*', function (greeting) {
            // ...
        });
@MessageMapping("/hello/{id}")
@SendTo("/topic/greetings.{id}")
public Greeting greeting(HelloMessage message, @DestinationVariable String id) {
   // ...
}

The above works but if you want spring-messaging to also use "." as separator for mapping destinations you can customize it.

commented

Thanks, that works :)

@givenm It's not necessary to use wildcards. For your case, you can subscribe to /topic/greetings.1

@rstoyanchev

Thanks, that works :)

@givenm It's not necessary to use wildcards. For your case, you can subscribe to /topic/greetings.1

Thanks, it solves my problem :)

Thanks. The / in the topic names is the issue when using rabbit mq as external queue.
Below was working for me when using messaging template with dynamic topics.

// Configuration
registry.enableStompBrokerRelay("/topic", "/queue")
...
// Usage
messagingTemplate.convertAndSend("/topic/status.job." + jobId, status);