Starting WebSocket

This commit is contained in:
PEDSF 2020-11-01 09:23:29 +01:00
parent 8755ca9cf1
commit ad9d5f513c
9 changed files with 280 additions and 24 deletions

102
pom.xml
View file

@ -14,6 +14,9 @@
<version>2.3.3.RELEASE</version> <version>2.3.3.RELEASE</version>
</parent> </parent>
<!-- ===================================================================== -->
<!-- PROPERTIES -->
<!-- ===================================================================== -->
<properties> <properties>
<!-- Generic properties --> <!-- Generic properties -->
<java.version>1.8</java.version> <java.version>1.8</java.version>
@ -26,13 +29,22 @@
<webjars-jquery.version>2.2.4</webjars-jquery.version> <webjars-jquery.version>2.2.4</webjars-jquery.version>
<wro4j.version>1.8.0</wro4j.version> <wro4j.version>1.8.0</wro4j.version>
<checkstyle.version>8.32</checkstyle.version>
<jacoco.version>0.8.5</jacoco.version> <jacoco.version>0.8.5</jacoco.version>
<junit.version>4.13</junit.version>
<lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
<lombok.version>1.18.12</lombok.version>
<maven-checkstyle-plugin.version>3.1.1</maven-checkstyle-plugin.version>
<modelmapper.version>2.3.8</modelmapper.version>
<nohttp-checkstyle.version>0.0.4.RELEASE</nohttp-checkstyle.version> <nohttp-checkstyle.version>0.0.4.RELEASE</nohttp-checkstyle.version>
<spring-format.version>0.0.25</spring-format.version> <spring-format.version>0.0.25</spring-format.version>
</properties> </properties>
<!-- ===================================================================== -->
<!-- DEPENDENCIES -->
<!-- ===================================================================== -->
<dependencies> <dependencies>
<!-- Spring and Spring Boot dependencies --> <!-- ============================================================ SPRING -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
@ -57,6 +69,10 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId> <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
@ -69,15 +85,7 @@
</exclusions> </exclusions>
</dependency> </dependency>
<!-- ================================================== MODELMAPPER --> <!-- ========================================================= DATABASES -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.8</version>
<scope>compile</scope>
</dependency>
<!-- Databases - Uses H2 by default -->
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
@ -89,6 +97,15 @@
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- ======================================================= MODELMAPPER -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${modelmapper.version}</version>
<scope>compile</scope>
</dependency>
<!-- caching --> <!-- caching -->
<dependency> <dependency>
<groupId>javax.cache</groupId> <groupId>javax.cache</groupId>
@ -100,6 +117,12 @@
</dependency> </dependency>
<!-- webjars --> <!-- webjars -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.40</version>
</dependency>
<dependency> <dependency>
<groupId>org.webjars</groupId> <groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId> <artifactId>webjars-locator-core</artifactId>
@ -119,9 +142,35 @@
<artifactId>bootstrap</artifactId> <artifactId>bootstrap</artifactId>
<version>${webjars-bootstrap.version}</version> <version>${webjars-bootstrap.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.1.2</version>
</dependency>
<!-- end of webjars --> <!-- end of webjars -->
<!-- Testing --> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
<!-- =========================================================== TESTING -->
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId> <artifactId>junit-jupiter-engine</artifactId>
@ -141,17 +190,20 @@
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.13</version> <version>${junit.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.12</version> <version>${lombok.version}</version>
<scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<!-- ===================================================================== -->
<!-- BUILD -->
<!-- ===================================================================== -->
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -170,12 +222,12 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId> <artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version> <version>${maven-checkstyle-plugin.version}</version>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.puppycrawl.tools</groupId> <groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId> <artifactId>checkstyle</artifactId>
<version>8.32</version> <version>${checkstyle.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.spring.nohttp</groupId> <groupId>io.spring.nohttp</groupId>
@ -297,7 +349,7 @@
</dependencies> </dependencies>
</plugin> </plugin>
<!-- ===================================================== SUREFIRE --> <!-- ======================================================== SUREFIRE -->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
@ -349,6 +401,9 @@
</plugins> </plugins>
</build> </build>
<!-- ===================================================================== -->
<!-- LICENCIES -->
<!-- ===================================================================== -->
<licenses> <licenses>
<license> <license>
<name>Apache License, Version 2.0</name> <name>Apache License, Version 2.0</name>
@ -356,6 +411,9 @@
</license> </license>
</licenses> </licenses>
<!-- ===================================================================== -->
<!-- REPOSITORIES -->
<!-- ===================================================================== -->
<repositories> <repositories>
<repository> <repository>
<id>spring-snapshots</id> <id>spring-snapshots</id>
@ -375,6 +433,9 @@
</repository> </repository>
</repositories> </repositories>
<!-- ===================================================================== -->
<!-- PLUGIN REPOSITORIES -->
<!-- ===================================================================== -->
<pluginRepositories> <pluginRepositories>
<pluginRepository> <pluginRepository>
<id>spring-snapshots</id> <id>spring-snapshots</id>
@ -394,7 +455,11 @@
</pluginRepository> </pluginRepository>
</pluginRepositories> </pluginRepositories>
<!-- ===================================================================== -->
<!-- PROFILES -->
<!-- ===================================================================== -->
<profiles> <profiles>
<!-- =============================================================== M2E -->
<profile> <profile>
<id>m2e</id> <id>m2e</id>
<activation> <activation>
@ -410,7 +475,7 @@
<plugin> <plugin>
<groupId>org.eclipse.m2e</groupId> <groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId> <artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version> <version>${lifecycle-mapping.version}</version>
<configuration> <configuration>
<lifecycleMappingMetadata> <lifecycleMappingMetadata>
<pluginExecutions> <pluginExecutions>
@ -450,5 +515,4 @@
</profile> </profile>
</profiles> </profiles>
</project> </project>

View file

@ -0,0 +1,32 @@
package org.springframework.samples.petclinic.configuration;
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 class to enable WebSocket and STOMP messaging.
*
* @author Paul-Emmanuel DOS SANTOS FACAO
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/topic/");
}
}

View file

@ -0,0 +1,22 @@
package org.springframework.samples.petclinic.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@Configuration
@EnableScheduling
public class WebSocketSchedulerConfiguration {
@Autowired
SimpMessagingTemplate simpMessagingTemplate;
@Scheduled(fixedDelay = 3000)
public void sendMessages() {
simpMessagingTemplate.convertAndSend("/topic/user", new WebSocketMessage("Fixed Delay Scheduler"));
}
}

View file

@ -0,0 +1,19 @@
package org.springframework.samples.petclinic.controller.common;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.samples.petclinic.model.common.User;
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
@MessageMapping("/user")
@SendTo("/topic/user")
public WebSocketMessage getUser(User user) {
return new WebSocketMessage("Hi " + user.getFirstName() + user.getLastName());
}
}

View file

@ -0,0 +1,26 @@
package org.springframework.samples.petclinic.controller.common;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
import org.springframework.stereotype.Controller;
@Controller
public class WebSocketController {
@MessageMapping("/websocket.send")
@SendTo("/topic/public")
public WebSocketMessage sendMessage(@Payload final WebSocketMessage message) {
return message;
}
@MessageMapping("/websocket.newUser")
@SendTo("/topic/public")
public WebSocketMessage newUser(@Payload final WebSocketMessage message, SimpMessageHeaderAccessor headerAccessor) {
headerAccessor.getSessionAttributes().put("usqername", message.getSender());
return message;
}
}

View file

@ -0,0 +1,33 @@
package org.springframework.samples.petclinic.controller.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.samples.petclinic.model.common.WebSocketMessage;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectedEvent;
@Slf4j
@Component
public class WebSocketEventListener {
@Autowired
private SimpMessageSendingOperations sendingOperations;
@EventListener
public void handlewebSocketConnectListener(final SessionConnectedEvent event) {
log.info("Ding dong. We have a new connection!");
}
@EventListener
public void handlewebSocketDisconnectListener(final SessionConnectedEvent event) {
final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
final String username = (String) headerAccessor.getSessionAttributes().get("username");
sendingOperations.convertAndSend("/topic/public", new WebSocketMessage("Hello" + username));
}
}

View file

@ -0,0 +1,10 @@
package org.springframework.samples.petclinic.model.common;
import org.springframework.samples.petclinic.model.Person;
public class User extends Person {
public User() {
super();
}
}

View file

@ -0,0 +1,43 @@
package org.springframework.samples.petclinic.model.common;
import java.time.LocalDate;
public class WebSocketMessage {
private String sender;
private String time;
private String content;
public WebSocketMessage(String content) {
this.time = LocalDate.now().toString();
this.content = content;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

View file

@ -0,0 +1,7 @@
package org.springframework.samples.petclinic.model.common;
public enum WebSocketMessageType {
MESSAGE,
CONNECT,
DISCONNECT
}