I am trying to use Spring 4 Websocket and Angular 7 through @stomp/stompjs and SockJS library, however it keeps returning 404 not found, and connection to websocket keeps closing as a result.
My configuration code at Spring:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class SocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/batch-socket").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/socketio/");
}
}
SocketHandlerService.java to send a message template
@Service
public class SocketHandlerService extends AbsLogger<SocketHandlerService> implements ApplicationListener<BrokerAvailabilityEvent> {
private final MessageSendingOperations<String> messagingTemplate;
@Autowired
public SocketHandlerService(MessageSendingOperations<String> messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
public SocketDetails sendRestMessage() {
...some code...
this.messagingTemplate.convertAndSend("/socketio/batchupdate", data);
...some code...
}
}
Angular socket.service.ts to handle websockets at client side
init() {
let connectionUrl = this.baseUrl + "batch-socket";
return new Promise((resolve, reject) => {
let config = new StompConfig();
config.heartbeatOutgoing = 5000;
config.heartbeatIncoming = 5000;
config.webSocketFactory = function () {
return new SockJS(connectionUrl, null, { transports: ['websocket' , 'xhr-streaming','xhr-polling' ] });
}
config.debug = function (str) {
console.log("@socketDebug: " + str)
}
this.client = new Client();
this.client.configure(config);
enableLogs && console.log(this.client);
console.log("@socketSvc: starting connection...");
const _this = this;
this.client.onConnect = function (frame) {
console.log("@socketSvc: connection established.");
console.log(frame);
_this.state = new BehaviorSubject<any>(SocketClientState.ATTEMPTING);
_this.state.next(SocketClientState.CONNECTED);
resolve(frame.headers['user-name']);
}
this.client.onWebSocketClose = function (msg){
console.log("@socketSvc: connection closed.");
console.log(msg);
}
this.client.activate();
});
}
I have checked that the endpoint urls match and that the domain for both server and client that is using is the same as well. However when deployed the following console output appears:
POST https://exampleWebsite.com/Portal/batch-socket/718/ky4ln33y/xhr_send?t=1576031555275 404 (Not Found)
main.7459b10fe35bab2c58d4.js:179295
@socketDebug: Connection closed to https://exampleWebsite.com/Portal/batch-socket
main.7459b10fe35bab2c58d4.js:179310
@socketSvc: connection closed. main.7459b10fe35bab2c58d4.js:179311
i {type: "close", bubbles: false, cancelable: false, timeStamp: 1576031555344, wasClean: false, …}bubbles: falsecancelable: falsecode: 1006reason: "Sending error: Error: http status 404"timeStamp: 1576031555344type: "close" wasClean: false__proto__: r
main.7459b10fe35bab2c58d4.js:179295
@socketDebug: STOMP: scheduling reconnection in 5000ms
I have also took a look in the developer tools for web browser to check the network: network tab
May I know what is the issue for causing a close connection? Sometimes it takes a few tries before the websocket is successfully established. Other times it takes forever to have a successful connection.
The following code runs for me!!
@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("/batch-socket");
registry.addEndpoint("/batch-socket").withSockJS();
}
}
Message-Handling Controller:
@MessageMapping("/batch-socket")
@SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
String time = new SimpleDateFormat("HH:mm").format(new Date());
return new OutputMessage(message.getFrom(), message.getText(), time);
}
Payload:
public class Message {
private String from;
private String text;
// getters and setters
}