Skip to content

A simple microservice with SpringBoot delivering an Angular application that send and receive messages using WebSocket API.

License

Notifications You must be signed in to change notification settings

hypercube-software/websocket-springboot-angular

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WebSocket with SpringBoot and Angular 10

Table of content

1 WebSocket with SpringBoot and Angular 10
    1.1 Project layout
    1.2 Websocket server in SpringBoot
        1.2.1 WebSocket server
        1.2.2 Object serialization
        1.2.3 Endpoint
    1.3 Websocket client in Angular
2 Build the project
3 Development mode

1.1 Project layout

The project is a simple SpringBoot microservice containing an Angular application. The maven project contains two projects in one:

  • src/main/java contains the SpringBoot microservice
  • src/main/angular contains the Angular application (you typically open VSCode here)

In src/main/angular/angular.json we specify an output directory matching the SpringBoot convention (static):

"outputPath": "dist/static",

Then in the maven pom.xml we add this directory as a resource. This will embed the whole directory in the final JAR.

<build>
	<resources>
		<resource>
			<directory>${project.basedir}/src/main/angular/dist</directory>
		</resource>
	</resources>

1.2 Websocket server in SpringBoot

The official tutorial from spring uses STOMP and SockJS on top of the WebSocket API. This can be useful in some cases but that's not what we are going to do here. We will use only the WebSocket API in SpringBoot without STOMP or SockJS. This mean we expect to have a browser with WebSocket client API.

1.2.1 WebSocket server

We just have to inherit from class org.springframework.web.socket.handler.TextWebSocketHandler

@Component
public class WebSocketHandler extends TextWebSocketHandler {

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		
	}

	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		
	}
}

1.2.2 Object serialization

We use the Jackson ObjectMapper provided by SpringBoot runtime.

@Autowired
private ObjectMapper objectMapper;

Our model is very simple, we have a HelloRequest and a HelloResponse.

1.2.3 Endpoint

We declare the WebSocket endpoint inheriting from org.springframework.web.socket.config.annotation.WebSocketConfigurer

@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {

	@Autowired
    protected WebSocketHandler webSocketHandler;
	
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		registry.addHandler(webSocketHandler, "/websocket-server");		
	}
}

The endpoint will be ws://host:port/websocket-server

1.3 Websocket client in Angular

In Angular we use the browser API for Websocket in our Application component:

import { Component } from '@angular/core';
import { HelloRequest } from './model/HelloRequest';
import { HelloResponse } from './model/HelloResponse';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})
export class AppComponent {
  title: string = 'websocket-app';
  ws: any = null;
  messages: Array<HelloResponse> = [];

  onWebSocketOpen() {
    console.log("Websocket connected");
  }

  onWebSocketMessage(evt) {
    let received_msg:HelloResponse = <HelloResponse>JSON.parse(evt.data);
    console.log("Message is received:" + received_msg.message);
    this.messages.push(received_msg);
  }

  onWebSocketclose() {
    console.log("Websocket connection is closed...");
    this.ws = null;
  }

  onConnect() {
    if ("WebSocket" in window) {
      console.log("Connecting...");
      let url = "ws://" + window.location.host + "/websocket-server";
      console.log("Connect to " + url);
      this.ws = new WebSocket(url);
      this.ws.onopen = this.onWebSocketOpen.bind(this);
      this.ws.onmessage = this.onWebSocketMessage.bind(this);
      this.ws.onclose = this.onWebSocketclose.bind(this);
    }
    else {
      alert("WebSocket NOT supported by your Browser!");
    }
  }
  onSend() {
    if (this.ws) {
      console.log("Send message");
      let msg:HelloRequest = new HelloRequest("The message");

      this.ws.send(JSON.stringify(msg));
    }
  }
}

2 Build the project

Build the angular application with npm (in src/main/angular):

npm run build

Then build the JAR with maven:

mvn clean install -Dmaven.test.skip=true

Then run the microservice with:

c:\java\jdk-11.0.2\bin\java -jar target\websocket-server-0.0.1-SNAPSHOT.jar

Then go to http://localhost:8080/

3 Development mode

During development, you have to work differently:

  • You run the SpringBoot service inside Eclipse in Debug, on port 8080
  • You run at the same time the Angular server on 4200

We added a proxy setting in the angular server to redirect the Websocket endpoint ws://localhost:4200/websocket-server to ws:://localhost:8080/websocket-server, So there is no CORS issues.

See src/main/angular/proxy.conf.json

{
    "/websocket-server/*": {
        "target": "ws://localhost:8080/",
        "secure": false,
        "logLevel": "debug",
        "ws": true
    }
}

Note that this configuration file is used because we changed the src/main/angular/angular.json:

       "serve": {
          "options": {
            "proxyConfig": "proxy.conf.json"
          },
  

Note that when you debug the microservice in eclipse (on port 8080), the folder used to deliver the angular application is src/main/angular/dist/static. It may be not up-to-date, so always use the angular server on port 4200.

About

A simple microservice with SpringBoot delivering an Angular application that send and receive messages using WebSocket API.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published