diff --git a/crypto-messenger-desktop/pom.xml b/crypto-messenger-desktop/pom.xml
index 5e8d8c7..e2fe450 100644
--- a/crypto-messenger-desktop/pom.xml
+++ b/crypto-messenger-desktop/pom.xml
@@ -28,6 +28,11 @@
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
org.springframework.cloud
spring-cloud-starter-openfeign
diff --git a/crypto-messenger-desktop/src/main/java/cryptomessenger/Ws.java b/crypto-messenger-desktop/src/main/java/cryptomessenger/Ws.java
new file mode 100644
index 0000000..0663579
--- /dev/null
+++ b/crypto-messenger-desktop/src/main/java/cryptomessenger/Ws.java
@@ -0,0 +1,92 @@
+package cryptomessenger;
+
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.context.event.EventListener;
+import org.springframework.messaging.converter.StringMessageConverter;
+import org.springframework.messaging.simp.stomp.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.WebSocketHttpHeaders;
+import org.springframework.web.socket.client.standard.StandardWebSocketClient;
+import org.springframework.web.socket.messaging.WebSocketStompClient;
+
+import java.lang.reflect.Type;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class Ws {
+
+ private final SessionWsHandler sessionWsHandler;
+ private final NewMessageWsHandler newMessageWsHandler;
+ private final CallWsHandler callWsHandler;
+
+ @EventListener(ApplicationReadyEvent.class)
+ public void run() {
+ var client = new WebSocketStompClient(new StandardWebSocketClient());
+ client.setMessageConverter(new StringMessageConverter());
+
+ var headers = new WebSocketHttpHeaders();
+ headers.add("X-Auth", "It's me!");
+
+ client.connectAsync("ws://localhost:8080/ws", headers, sessionWsHandler).thenAccept(session -> {
+ log.info("Session: {}", session.getSessionId());
+ session.subscribe("/user/alex/calls/new", newMessageWsHandler);
+ session.subscribe("/user/kirill/messages/new", callWsHandler);
+ });
+ }
+
+ @Slf4j
+ @Component
+ public static class NewMessageWsHandler implements StompFrameHandler {
+ @Override
+ public Type getPayloadType(StompHeaders headers) {
+ return String.class;
+ }
+
+ @Override
+ public void handleFrame(StompHeaders headers, Object payload) {
+ log.info(">> [New Message]: {}", payload);
+ }
+ }
+
+ @Slf4j
+ @Component
+ public static class CallWsHandler implements StompFrameHandler {
+ @Override
+ public Type getPayloadType(StompHeaders headers) {
+ return String.class;
+ }
+
+ @Override
+ public void handleFrame(StompHeaders headers, Object payload) {
+ log.info(">> [Call]: {}", payload);
+ }
+ }
+
+ @Slf4j
+ @Component
+ public static class SessionWsHandler extends StompSessionHandlerAdapter {
+
+ @Lazy
+ @Autowired
+ private Ws ws;
+
+ @Override
+ public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) {
+ log.error("Exception", exception);
+ }
+
+ @Override
+ @SneakyThrows
+ public void handleTransportError(StompSession session, Throwable exception) {
+ log.error("Error", exception);
+ Thread.sleep(5000);
+ ws.run();
+ }
+ }
+}
diff --git a/crypto-messenger-server/pom.xml b/crypto-messenger-server/pom.xml
index 90523e5..3057b73 100644
--- a/crypto-messenger-server/pom.xml
+++ b/crypto-messenger-server/pom.xml
@@ -18,6 +18,11 @@
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
org.springframework.boot
spring-boot-starter-data-mongodb
diff --git a/crypto-messenger-server/src/main/java/cryptomessenger/server/infrastructure/websocket/NewMessageNotifier.java b/crypto-messenger-server/src/main/java/cryptomessenger/server/infrastructure/websocket/NewMessageNotifier.java
new file mode 100644
index 0000000..645a07c
--- /dev/null
+++ b/crypto-messenger-server/src/main/java/cryptomessenger/server/infrastructure/websocket/NewMessageNotifier.java
@@ -0,0 +1,20 @@
+package cryptomessenger.server.infrastructure.websocket;
+
+import cryptomessenger.server.service.message.Message;
+import cryptomessenger.server.service.message.NewMessageListener;
+import lombok.RequiredArgsConstructor;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class NewMessageNotifier implements NewMessageListener {
+
+ private final SimpMessagingTemplate simpMessagingTemplate;
+
+ @Override
+ public void onNewMessage(Message message) {
+ var receiver = message.getReceiverId().toString();
+ simpMessagingTemplate.convertAndSendToUser(receiver, "/messages/new", "New message");
+ }
+}
diff --git a/crypto-messenger-server/src/main/java/cryptomessenger/server/infrastructure/websocket/WebSocketConfiguration.java b/crypto-messenger-server/src/main/java/cryptomessenger/server/infrastructure/websocket/WebSocketConfiguration.java
new file mode 100644
index 0000000..ab9c103
--- /dev/null
+++ b/crypto-messenger-server/src/main/java/cryptomessenger/server/infrastructure/websocket/WebSocketConfiguration.java
@@ -0,0 +1,16 @@
+package cryptomessenger.server.infrastructure.websocket;
+
+import org.springframework.context.annotation.Configuration;
+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 registerStompEndpoints(StompEndpointRegistry registry) {
+ registry.addEndpoint("/ws");
+ }
+}
diff --git a/crypto-messenger-server/src/main/java/cryptomessenger/server/service/message/MessageServiceImpl.java b/crypto-messenger-server/src/main/java/cryptomessenger/server/service/message/MessageServiceImpl.java
index d3d850a..7507145 100644
--- a/crypto-messenger-server/src/main/java/cryptomessenger/server/service/message/MessageServiceImpl.java
+++ b/crypto-messenger-server/src/main/java/cryptomessenger/server/service/message/MessageServiceImpl.java
@@ -6,6 +6,7 @@
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
+import java.util.Set;
import java.util.UUID;
import static java.util.UUID.randomUUID;
@@ -15,6 +16,7 @@
public class MessageServiceImpl implements MessageService {
private final MessageRepository messageRepository;
+ private final Set newMessageListeners;
@Override
public Message send(MessageSending sending) {
@@ -26,7 +28,9 @@ public Message send(MessageSending sending) {
.contentForSender(sending.getContentForSender())
.contentForReceiver(sending.getContentForReceiver())
.build();
- return messageRepository.save(message);
+ messageRepository.save(message);
+ newMessageListeners.forEach(listener -> listener.onNewMessage(message));
+ return message;
}
@Override
diff --git a/crypto-messenger-server/src/main/java/cryptomessenger/server/service/message/NewMessageListener.java b/crypto-messenger-server/src/main/java/cryptomessenger/server/service/message/NewMessageListener.java
new file mode 100644
index 0000000..d1a1ee0
--- /dev/null
+++ b/crypto-messenger-server/src/main/java/cryptomessenger/server/service/message/NewMessageListener.java
@@ -0,0 +1,6 @@
+package cryptomessenger.server.service.message;
+
+public interface NewMessageListener {
+
+ void onNewMessage(Message message);
+}