Search code examples
springtomcatangularstompsockjs

spring boot rest and angular2 with websocket (stomp over sockjs)


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


Solution

  • 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();
        }
    
    }