diff options
author | Zhongheng Liu <z.liu@outlook.com.gr> | 2023-12-21 14:12:59 +0200 |
---|---|---|
committer | Zhongheng Liu <z.liu@outlook.com.gr> | 2023-12-21 14:12:59 +0200 |
commit | 4329c5067f1a481e9fa4876169746a5d164b87e3 (patch) | |
tree | 861ff0239aaea4f589c7c56381a2691c01860fe6 | |
parent | 74700bfdc2b28c846cc372bac547187ebe986ab5 (diff) | |
download | epq-api-4329c5067f1a481e9fa4876169746a5d164b87e3.tar.gz epq-api-4329c5067f1a481e9fa4876169746a5d164b87e3.tar.bz2 epq-api-4329c5067f1a481e9fa4876169746a5d164b87e3.zip |
first successful ws impl
14 files changed, 175 insertions, 154 deletions
diff --git a/src/main/java/me/imsonmia/epqapi/EpqapiApplication.java b/src/main/java/me/imsonmia/epqapi/EpqapiApplication.java index ed48498..37e10fb 100644 --- a/src/main/java/me/imsonmia/epqapi/EpqapiApplication.java +++ b/src/main/java/me/imsonmia/epqapi/EpqapiApplication.java @@ -1,13 +1,16 @@ package me.imsonmia.epqapi; - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class EpqapiApplication { - +public class EpqapiApplication extends Thread { + private static Logger logger = LoggerFactory.getLogger(EpqapiApplication.class); public static void main(String[] args) { + logger.info("Main Spring Boot process running in thread!"); SpringApplication.run(EpqapiApplication.class, args); } + } diff --git a/src/main/java/me/imsonmia/epqapi/config/WebSocketConfig.java b/src/main/java/me/imsonmia/epqapi/config/WebSocketConfig.java new file mode 100644 index 0000000..3dc7dad --- /dev/null +++ b/src/main/java/me/imsonmia/epqapi/config/WebSocketConfig.java @@ -0,0 +1,21 @@ +package me.imsonmia.epqapi.config; + +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 WebSocketConfig implements WebSocketMessageBrokerConfigurer { + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/sub"); + registry.setApplicationDestinationPrefixes("/app"); + } + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws").setAllowedOrigins("*"); + } +} diff --git a/src/main/java/me/imsonmia/epqapi/controller/ChatMessageController.java b/src/main/java/me/imsonmia/epqapi/controller/ChatMessageController.java index bf94991..7bfcba6 100644 --- a/src/main/java/me/imsonmia/epqapi/controller/ChatMessageController.java +++ b/src/main/java/me/imsonmia/epqapi/controller/ChatMessageController.java @@ -1,19 +1,21 @@ package me.imsonmia.epqapi.controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.stereotype.Controller; -import me.imsonmia.epqapi.model.ChatMessage; -import me.imsonmia.epqapi.repository.ChatMessageRepository; +import me.imsonmia.epqapi.model.Message; -@RestController -@RequestMapping("/api/v1") +@Controller +// @RequestMapping("/api/v1") public class ChatMessageController { - private ChatMessageRepository chatMessageRepository; - @GetMapping("/msg/{id}") - public ChatMessage getMessageById(@PathVariable(value = "id") Long id) { - return chatMessageRepository.findById(id).get(); + @MessageMapping("/chat") + @SendTo("/sub/chat") + public Message messageHandler(Message message) throws Exception { + return message; } + // @GetMapping("/msg/{id}") + // public ChatMessage getMessageById(@PathVariable(value = "id") Long id) { + // return chatMessageRepository.findById(id).get(); + // } } diff --git a/src/main/java/me/imsonmia/epqapi/controller/TextMessage.java b/src/main/java/me/imsonmia/epqapi/controller/TextMessage.java new file mode 100644 index 0000000..a50dd2b --- /dev/null +++ b/src/main/java/me/imsonmia/epqapi/controller/TextMessage.java @@ -0,0 +1,17 @@ +package me.imsonmia.epqapi.controller; + +public class TextMessage { + private String text; + public TextMessage() { + + } + public TextMessage(String text) { + this.text = text; + } + public String getText() { + return text; + } + public void setText(String text) { + this.text = text; + } +} diff --git a/src/main/java/me/imsonmia/epqapi/messaging/MessageDecoder.java b/src/main/java/me/imsonmia/epqapi/messaging/MessageDecoder.java deleted file mode 100644 index 935e2c0..0000000 --- a/src/main/java/me/imsonmia/epqapi/messaging/MessageDecoder.java +++ /dev/null @@ -1,27 +0,0 @@ -package me.imsonmia.epqapi.messaging; - -import com.google.gson.Gson; - -import jakarta.websocket.DecodeException; -import jakarta.websocket.Decoder; -import jakarta.websocket.EndpointConfig; - -public class MessageDecoder implements Decoder.Text<Message> { - private static Gson gson = new Gson(); - @Override - public Message decode(String message) throws DecodeException { - return gson.fromJson(message, Message.class); - } - @Override - public void destroy() { - Text.super.destroy(); - } - @Override - public void init(EndpointConfig endpointConfig) { - Text.super.init(endpointConfig); - } - @Override - public boolean willDecode(String s) { - return (s != null); - } -}
\ No newline at end of file diff --git a/src/main/java/me/imsonmia/epqapi/messaging/MessageEncoder.java b/src/main/java/me/imsonmia/epqapi/messaging/MessageEncoder.java deleted file mode 100644 index 5fac391..0000000 --- a/src/main/java/me/imsonmia/epqapi/messaging/MessageEncoder.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.imsonmia.epqapi.messaging; - -import com.google.gson.Gson; - -import jakarta.websocket.EncodeException; -import jakarta.websocket.Encoder; -import jakarta.websocket.EndpointConfig; - -public class MessageEncoder implements Encoder.Text<Message> { - private static Gson gson = new Gson(); - @Override - public String encode(Message message) throws EncodeException { - return gson.toJson(message); - } - @Override - public void destroy() { - Text.super.destroy(); - } - @Override - public void init(EndpointConfig endpointConfig) { - Text.super.init(endpointConfig); - } -}
\ No newline at end of file diff --git a/src/main/java/me/imsonmia/epqapi/messaging/WebSocketHandler.java b/src/main/java/me/imsonmia/epqapi/messaging/WebSocketHandler.java deleted file mode 100644 index 25d653d..0000000 --- a/src/main/java/me/imsonmia/epqapi/messaging/WebSocketHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -package me.imsonmia.epqapi.messaging; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; - -import org.slf4j.Logger; - -import jakarta.websocket.EncodeException; -import jakarta.websocket.OnClose; -import jakarta.websocket.OnMessage; -import jakarta.websocket.OnOpen; -import jakarta.websocket.Session; -import jakarta.websocket.server.ServerEndpoint; -import me.imsonmia.epqapi.model.ChatConvert; -import me.imsonmia.epqapi.model.ChatMessage; -import me.imsonmia.epqapi.repository.ChatMessageRepository; - -// https://www.baeldung.com/java-websockets -@ServerEndpoint( - value = "/chat/{username}", - encoders = MessageEncoder.class, - decoders = MessageDecoder.class - ) -public class WebSocketHandler { - private Logger logger; - private ChatMessageRepository chatMessageRepository; - private Session session; - private Set<WebSocketHandler> chatEndpoints = new CopyOnWriteArraySet<>(); - private HashMap<String, String> users = new HashMap<>(); - @OnOpen - public void onOpen(Session session, String username) throws IOException { - this.session = session; - chatEndpoints.add(this); - users.put(session.getId(), username); - Message message = new Message(); - message.setFrom(username); - message.setContent("Connected, hello world!"); - broadcast(message); - ChatMessage cmessage = new ChatConvert().fromMessage(message); - chatMessageRepository.save(cmessage); - } - @OnMessage - public void onMessage(Session session, Message message) throws IOException { - message.setFrom(users.get(session.getId())); - broadcast(message); - } - @OnClose - public void onClose(Session session) throws IOException { - chatEndpoints.remove(this); - Message message = new Message(); - message.setFrom(users.get(session.getId())); - message.setContent("Disconnected!"); - broadcast(message); - } - public void broadcast(Message message) { - chatEndpoints.forEach(endpoint -> { - try { - endpoint.session.getBasicRemote().sendObject(message); - } - catch (IOException e) { - logger.info("Error sending message! IOException"); - logger.error(null, e); - } - catch (EncodeException e) { - logger.info("Error sending message! EncodeException"); - } - }); - } -} diff --git a/src/main/java/me/imsonmia/epqapi/model/ChatConvert.java b/src/main/java/me/imsonmia/epqapi/model/ChatConvert.java index 69528d6..92dda20 100644 --- a/src/main/java/me/imsonmia/epqapi/model/ChatConvert.java +++ b/src/main/java/me/imsonmia/epqapi/model/ChatConvert.java @@ -1,11 +1,10 @@ package me.imsonmia.epqapi.model; -import me.imsonmia.epqapi.messaging.Message; import me.imsonmia.epqapi.repository.UserRepository; public class ChatConvert { private UserRepository r; public ChatMessage fromMessage(Message s) { - return new ChatMessage(r.findByFirstName(s.getFrom()).getId(), s.getContent()); + return new ChatMessage(r.findByUserName(s.getFrom()).getId(), s.getContent()); } } diff --git a/src/main/java/me/imsonmia/epqapi/messaging/Message.java b/src/main/java/me/imsonmia/epqapi/model/Message.java index c11d96e..1e7844a 100644 --- a/src/main/java/me/imsonmia/epqapi/messaging/Message.java +++ b/src/main/java/me/imsonmia/epqapi/model/Message.java @@ -1,4 +1,4 @@ -package me.imsonmia.epqapi.messaging; +package me.imsonmia.epqapi.model; public class Message { private String from; diff --git a/src/main/java/me/imsonmia/epqapi/repository/UserRepository.java b/src/main/java/me/imsonmia/epqapi/repository/UserRepository.java index b877899..8b98587 100644 --- a/src/main/java/me/imsonmia/epqapi/repository/UserRepository.java +++ b/src/main/java/me/imsonmia/epqapi/repository/UserRepository.java @@ -5,5 +5,5 @@ import org.springframework.data.repository.CrudRepository; import me.imsonmia.epqapi.model.User; public interface UserRepository extends CrudRepository<User, Long> { - User findByFirstName(String userName); + User findByUserName(String userName); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a6bbf47..6a29230 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,6 @@ -spring.datasource.url=jdbc:mariadb://localhost:3306/test +spring.datasource.url=jdbc:mariadb://127.0.0.1:3306/test spring.datasource.username=dbuser spring.datasource.password=dbpasswd spring.datasource.driver-class-name=org.mariadb.jdbc.Driver +spring.jpa.show-sql: true spring.jpa.hibernate.ddl-auto=create-drop
\ No newline at end of file diff --git a/src/main/resources/static/app.js b/src/main/resources/static/app.js new file mode 100644 index 0000000..20fafd4 --- /dev/null +++ b/src/main/resources/static/app.js @@ -0,0 +1,60 @@ +const stompClient = new StompJs.Client({ + brokerURL: 'ws://localhost:8080/ws' +}); + +stompClient.onConnect = (frame) => { + setConnected(true); + console.log('Connected: ' + frame); + stompClient.subscribe('/sub/chat', (greeting) => { + showGreeting(JSON.parse(greeting.body).content); + }); +}; + +stompClient.onWebSocketError = (error) => { + console.error('Error with websocket', error); +}; + +stompClient.onStompError = (frame) => { + console.error('Broker reported error: ' + frame.headers['message']); + console.error('Additional details: ' + frame.body); +}; + +function setConnected(connected) { + $("#connect").prop("disabled", connected); + $("#disconnect").prop("disabled", !connected); + if (connected) { + $("#conversation").show(); + } + else { + $("#conversation").hide(); + } + $("#greetings").html(""); +} + +function connect() { + stompClient.activate(); +} + +function disconnect() { + stompClient.deactivate(); + setConnected(false); + console.log("Disconnected"); +} + +function sendName() { + stompClient.publish({ + destination: "/app/chat", + body: JSON.stringify({'text': $("#name").val()}) + }); +} + +function showGreeting(message) { + $("#greetings").append("<tr><td>" + message + "</td></tr>"); +} + +$(function () { + $("form").on('submit', (e) => e.preventDefault()); + $( "#connect" ).click(() => connect()); + $( "#disconnect" ).click(() => disconnect()); + $( "#send" ).click(() => sendName()); +});
\ No newline at end of file diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100644 index 0000000..c767704 --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> + <title>Hello WebSocket</title> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> + <link href="/main.css" rel="stylesheet"> + <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> + <script src="https://cdn.jsdelivr.net/npm/@stomp/stompjs@7.0.0/bundles/stomp.umd.min.js"></script> + <script src="/app.js"></script> +</head> +<body> +<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being + enabled. Please enable + Javascript and reload this page!</h2></noscript> +<div id="main-content" class="container"> + <div class="row"> + <div class="col-md-6"> + <form class="form-inline"> + <div class="form-group"> + <label for="connect">WebSocket connection:</label> + <button id="connect" class="btn btn-default" type="submit">Connect</button> + <button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect + </button> + </div> + </form> + </div> + <div class="col-md-6"> + <form class="form-inline"> + <div class="form-group"> + <label for="name">What is your name?</label> + <input type="text" id="name" class="form-control" placeholder="Your name here..."> + </div> + <button id="send" class="btn btn-default" type="submit">Send</button> + </form> + </div> + </div> + <div class="row"> + <div class="col-md-12"> + <table id="conversation" class="table table-striped"> + <thead> + <tr> + <th>Greetings</th> + </tr> + </thead> + <tbody id="greetings"> + </tbody> + </table> + </div> + </div> +</div> +</body> +</html>
\ No newline at end of file diff --git a/src/test/java/me/imsonmia/epqapi/EpqapiApplicationTests.java b/src/test/java/me/imsonmia/epqapi/EpqapiApplicationTests.java deleted file mode 100644 index f6d3d45..0000000 --- a/src/test/java/me/imsonmia/epqapi/EpqapiApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.imsonmia.epqapi; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class EpqapiApplicationTests { - - @Test - void contextLoads() { - } - -} |