6

Is it possible to use stomp over sockjs without MVC. So I would like to have spring rest interface in tomcat, and angular2 application run by express.

WebSocketConfig.java

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // the endpoint for websocket connections
        registry.addEndpoint("/portfolio").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.setApplicationDestinationPrefixes("/app");
        config.enableSimpleBroker("/topic");
    }
}

SocketController.java

@Controller
public class SocketController {

    @Autowired
    private SimpMessagingTemplate template;

    public SocketController() {
        int a = 5;
    }

    @MessageMapping("/greeting")
    public String handle(String greeting) {
        return "[" + "greeting" + ": " + greeting;
    }
}

and typescript code:

. . .

constructor() {

        var socket = new SockJS('http://localhost:8080/portfolio');
        this.stompClient = Stomp.over(socket);
        this.stompClient.connect("guest", "guest", function(frame) {
            console.log('Connected: ' + frame);
            this.stompClient.subscribe('http://localhost:8080/topic/greeting', function(greeting) {
                console.log("from from", greeting);
            });
        }, function (err) {
            console.log('err', err);
        });
    }

. . .

send() {
    this.stompClient.send("http://localhost:8080/app/greeting", {}, JSON.stringify({ 'name': "kitica" }));
}

. . .

but for some reason this is not working.. in console I get output:

Opening Web Socket...
stomp.js:134 Web Socket Opened...
stomp.js:134 >>> CONNECT
login:guest
passcode:guest
accept-version:1.1,1.0
heart-beat:10000,10000



stomp.js:134 <<< CONNECTED
version:1.1
heart-beat:0,0



stomp.js:134 connected to server undefined
activity-socket.ts:17 Connected: CONNECTED
heart-beat:0,0
version:1.1

and when I send I get

>>> SEND
destination:http://localhost:8080/app/greeting
content-length:17

{"name":"kitica"}

but message never comes back to subscriber.

angular2 is on port 8001 and spring rest is on 8080

4
  • If you can use it in JS you can use it in Angular2. Commented Mar 26, 2016 at 18:01
  • I have updated question with code sample I have tried, this is according to their documentation Commented Mar 26, 2016 at 18:11
  • How did you add sockJS iun your angular2 app please ? Commented Aug 19, 2016 at 15:09
  • If your question was more specific I could give more appropriate answer. But it was very simple npm install, and later in your typescript file you have to declare variables SockJS and Stomp. I hope it was helpful. edit: refer to stackoverflow.com/a/37094682/2662587 Commented Aug 25, 2016 at 18:05

3 Answers 3

7

The part that was confusing is that I am using spring-boot-rest and I am not serving angular2 as static from tomcat container, I have angular2 under webpack so I was constantly trying to subscribe and send to relative URL.

The right way to do is:

import {Component} from '@angular/core';
import {ActivityService} from '../common/services';
import {MaterializeDirective} from 'angular2-materialize';
import {LarsActionButtonComponent} from '../common/components';

var SockJS = require('sockjs-client');
var Stomp = require('stompjs');

@Component({
selector: 'activity',
providers: [ActivityService],
directives: [MaterializeDirective, LarsActionButtonComponent],
templateUrl: 'app/activity/activity.html'
})

export class Activity {
stompClient: any;

activityId: any;
text: any;
messages: Array<String> = new Array<String>();

constructor() {
}

send() {
    this.stompClient.send('/app/hello/' + this.activityId, {},      JSON.stringify({ 'name': this.text }));
}

connect() {
    var that = this;
    var socket = new SockJS('tst-rest.mypageexample/hello?activityId=' + this.activityId);
    this.stompClient = Stomp.over(socket);
    this.stompClient.connect({}, function (frame) {
        console.log('Connected: ' + frame);
        that.stompClient.subscribe('/topic/greetings/' + that.activityId, function (greeting) {
            that.messages.push(JSON.parse(greeting.body).content);
        });
    }, function (err) {
        console.log('err', err);
    });
}

}

and in spring controller:

@Controller
public class SocketController {


@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
    return new Greeting("Hello, " + message.getName() + "!");
}

}

Configuration class:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/hello").setAllowedOrigins("*").withSockJS();
    }

}
Sign up to request clarification or add additional context in comments.

5 Comments

What npm library do you use? Is it sufficient to just "npm install stomp"
please take a look at my answer above, it is just updated
how did you map sockjs-client in webpack?
I have only "sockjs": "0.3.4", "stompjs": "2.3.3" in package.json, everything else is presented up.
@critical how to auto reconnect if I lost connection to a socket?
1

i had myself some issues to work with an angular2 client using stomp over SockJs versus a Java spring-boot back-end. Here what i did to make it working:

On the angular side:

this.stompClient.subscribe cannot be find, so bind "this" to "that".

constructor() {
    var that = this;
    var socket = new SockJS('http://localhost:8080/portfolio');
    this.stompClient = Stomp.over(socket);
    this.stompClient.connect("guest", "guest", function(frame) {
        console.log('Connected: ' + frame);
        that.stompClient.subscribe('http://localhost:8080/topic/greeting', function(greeting) {
            console.log("from from", greeting);
        });
    }, function (err) {
        console.log('err', err);
    });
}

On the Java server side:

Your Controller need an annotation that said where the vallue is returned like this:

@MessageMapping("/greeting")
@SendTo("/topic/greetings")
public String handle(String greeting) {
    return "[" + "greeting" + ": " + greeting;
}

According to your message broker.

Hope that's help a bit.

2 Comments

how to auto reconnect if I lost connection to a socket?
@Lanou Thank you so much, it fixed my issue!
0

You have send the 'handle()' method value to the subscriber either using simpMessagingTemplate.convertAndSend(, ); e.g.- simpMessagingTemplate.convertAndSend("/topic/chats", message.getMessage());

or @SendTo("destination url") above the handler method. e.g.- @SendTo("/topic/message")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.