1

I am trying to put together a simple example WebSocket app that uses AngularJS and Spring Boot. I am using this angularjs websocket library

The issue is that i am unable to send anything from client to server. There are no errors on the front end and nothing logged no errors on the back end.

Websocket config:

package org.example.project;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements 
WebSocketMessageBrokerConfigurer {

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

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

}

Websocket endpoint implementation:

package org.example.project;

import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

@Controller
public class WebSocketController {

    private final SimpMessagingTemplate template;

    @Autowired
    WebSocketController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @MessageMapping("/uc/status/request")
    public void onReceivedMessage(String message) {

        System.out.println(" THIS CAME FROM WS CLIENT ");
        this.template.convertAndSend("/uc/status/report", 
            "received " + message);
    }

}

Angular client implementation:

'use strict'

var app = angular.module('app', [
    'ngWebSocket'
])
app.controller("MyController", function($scope, $http, $websocket) {

    // path to the end point is actually /app/uc/status/request
    // unable to add end point path when connecting
    // and don't know how to subscribe
    var ws = $websocket('ws://localhost:8080/socket/websocket/');

    ws.onMessage(function(event) { 
        console.log('message: ', event);
    });

    ws.onError(function(event) {
        console.log("error");
    });

    ws.onClose(function(event) { 

    });

    ws.onOpen(function(event) { 
        console.log('connection open');
    });

    // nothing happens when this call is made
    ws.send("message content", "/app/uc/status/request");

});

1 Answer 1

1
this.template.convertAndSend("/uc/status/report", 
    "received " + message);

Your destination (first param) is wrong. You registered your broker channel with destination prefix /report, so you must publish/subscribe to such destination prefix. So change it to

this.template.convertAndSend("/report", 
    "received " + message);

And for front end client to subscribe and send to a particular destination

// sorry I dont work with angular below is mostly copied.
connect() {
  const socket = new SockJS('/socket');
  this.stompClient = Stomp.over(socket);

  const _this = this;
  this.stompClient.connect({}, function (frame) {
    _this.stompClient.subscribe('/report', function (data) {
      // do something with received data
    });
  });
}
// send message to destination
send() {
  this.stompClient.send(
    '/app/uc/status/request', // roughly put, ur applicationDestinationPrefix + @MessageMapping
    {},
    "my message"
  );
}

Depending on your application needs, You can add whatever path you want after /report, such as /report/myreport1, /report/myreport2, for multiple topics or queues. Note that the prefix you defined in enableSimpleBroker("/report") doesn't really matter in the naming sense as it works fine for Spring's in-memory message broker. For other dedicated brokers, such as ActiveMQ or RabbitMQ, you should be using /topic for one to many (many subscribers) and /queue for one to one (one receiver). read more on https://docs.spring.io/spring-framework/docs/5.0.0.M1/spring-framework-reference/html/websocket.html

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

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.