From 69af3f60d399157a8951988fa2f91d29c553fbb5 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Mon, 25 Jul 2016 21:36:50 +0300 Subject: juick-ws: websocket terminal --- .../src/main/java/com/juick/ws/ApiController.java | 24 +++++++++++ .../main/java/com/juick/ws/StatusController.java | 9 ++++- .../java/com/juick/ws/api/WebSocketStatus.java | 16 ++++++++ .../ws/configuration/WebsocketConfiguration.java | 47 ++++++++++++++++++++++ juick-ws/src/main/static/scripts.js | 36 +++++++++++++++++ juick-ws/src/main/static/style.css | 2 + .../src/main/webapp/WEB-INF/templates/index.html | 14 +++++++ 7 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 juick-ws/src/main/java/com/juick/ws/ApiController.java create mode 100644 juick-ws/src/main/java/com/juick/ws/api/WebSocketStatus.java create mode 100644 juick-ws/src/main/static/scripts.js create mode 100644 juick-ws/src/main/static/style.css create mode 100644 juick-ws/src/main/webapp/WEB-INF/templates/index.html (limited to 'juick-ws/src/main') diff --git a/juick-ws/src/main/java/com/juick/ws/ApiController.java b/juick-ws/src/main/java/com/juick/ws/ApiController.java new file mode 100644 index 00000000..9adda912 --- /dev/null +++ b/juick-ws/src/main/java/com/juick/ws/ApiController.java @@ -0,0 +1,24 @@ +package com.juick.ws; + +import com.juick.ws.api.WebSocketStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import javax.inject.Inject; + +/** + * Created by vitalyster on 25.07.2016. + */ +@RestController +public class ApiController { + @Inject + WebsocketComponent wsHandler; + + @RequestMapping(value = "/api/status", method = RequestMethod.GET, + produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public WebSocketStatus status() { + return new WebSocketStatus(wsHandler.clients.size()); + } +} diff --git a/juick-ws/src/main/java/com/juick/ws/StatusController.java b/juick-ws/src/main/java/com/juick/ws/StatusController.java index b212af19..9c3e2404 100644 --- a/juick-ws/src/main/java/com/juick/ws/StatusController.java +++ b/juick-ws/src/main/java/com/juick/ws/StatusController.java @@ -4,6 +4,7 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; import javax.inject.Inject; @@ -17,7 +18,11 @@ public class StatusController { WebsocketComponent wsHandler; @RequestMapping(method = RequestMethod.GET, headers = "Connection!=Upgrade", value = "/") - public String status() { - return String.format("Clients: %d", wsHandler.clients.size()); + public ModelAndView status() { + ModelAndView modelAndView = new ModelAndView(); + modelAndView.addObject("clients", wsHandler.clients.size()); + modelAndView.setViewName("index"); + return modelAndView; } + } diff --git a/juick-ws/src/main/java/com/juick/ws/api/WebSocketStatus.java b/juick-ws/src/main/java/com/juick/ws/api/WebSocketStatus.java new file mode 100644 index 00000000..ada19f89 --- /dev/null +++ b/juick-ws/src/main/java/com/juick/ws/api/WebSocketStatus.java @@ -0,0 +1,16 @@ +package com.juick.ws.api; + +/** + * Created by vitalyster on 25.07.2016. + */ +public class WebSocketStatus { + private int clientsCount; + + public WebSocketStatus(int count) { + clientsCount = count; + } + + public int getClientsCount() { + return clientsCount; + } +} diff --git a/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java index d432b19c..c25f8f42 100644 --- a/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java +++ b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java @@ -2,6 +2,11 @@ package com.juick.ws.configuration; import com.juick.ws.WebsocketComponent; import com.juick.ws.XMPPConnection; +import com.mitchellbosecke.pebble.PebbleEngine; +import com.mitchellbosecke.pebble.loader.Loader; +import com.mitchellbosecke.pebble.loader.ServletLoader; +import com.mitchellbosecke.pebble.spring4.PebbleViewResolver; +import com.mitchellbosecke.pebble.spring4.extension.SpringExtension; import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -9,13 +14,18 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; import javax.inject.Inject; +import javax.servlet.ServletContext; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -47,6 +57,36 @@ public class WebsocketConfiguration extends WebMvcConfigurationSupport implement dataSource.setUrl(env.getProperty("datasource_url")); return new JdbcTemplate(dataSource); } + @Inject + private ServletContext servletContext; + + @Bean + public Loader templateLoader(){ + return new ServletLoader(servletContext); + } + + @Bean + public SpringExtension springExtension() { + return new SpringExtension(); + } + + @Bean + public PebbleEngine pebbleEngine() { + return new PebbleEngine.Builder() + .loader(this.templateLoader()) + .extension(springExtension()) + .build(); + } + + @Bean + public ViewResolver viewResolver() { + PebbleViewResolver viewResolver = new PebbleViewResolver(); + viewResolver.setPrefix("/WEB-INF/templates/"); + viewResolver.setSuffix(".html"); + viewResolver.setPebbleEngine(pebbleEngine()); + return viewResolver; + } + @Override public RequestMappingHandlerMapping requestMappingHandlerMapping() { RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping(); @@ -57,4 +97,11 @@ public class WebsocketConfiguration extends WebMvcConfigurationSupport implement public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(wsHandler(), "/**").setAllowedOrigins("*"); } + + @Override + protected void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.setOrder(0); + registry.addResourceHandler("/scripts.js").addResourceLocations("/"); + registry.addResourceHandler("/style.css").addResourceLocations("/"); + } } diff --git a/juick-ws/src/main/static/scripts.js b/juick-ws/src/main/static/scripts.js new file mode 100644 index 00000000..2691816d --- /dev/null +++ b/juick-ws/src/main/static/scripts.js @@ -0,0 +1,36 @@ +var Terminal = require('terminal'); +require('whatwg-fetch'); + +function ready(fn) { + if (document.readyState != 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } +} + +ready(function() { + var ws = new WebSocket('wss://ws.juick.com/_replies'); + var term = new Terminal('terminal', {}, {}); + var status = document.querySelector("#status"); + ws.onopen = function() { + term.output("
connected"); + }; + ws.onclose = function() { + term.output("
disconnected"); + } + ws.onmessage = function(msg) { + term.output("
" + JSON.stringify(JSON.parse(msg.data), null, 2)); + } + setTimeout(function() { + ws.send(" "); + }, 60000); + setTimeout(function() { + fetch("/api/status") + .then(function(response) { + return response.text(); + }).then(function(body) { + status.textContent = JSON.parse(body).clientsCount; + }) + }, 5000); +}) \ No newline at end of file diff --git a/juick-ws/src/main/static/style.css b/juick-ws/src/main/static/style.css new file mode 100644 index 00000000..ee5ec6b7 --- /dev/null +++ b/juick-ws/src/main/static/style.css @@ -0,0 +1,2 @@ +@import "normalize.css"; +@import "terminal"; \ No newline at end of file diff --git a/juick-ws/src/main/webapp/WEB-INF/templates/index.html b/juick-ws/src/main/webapp/WEB-INF/templates/index.html new file mode 100644 index 00000000..e888e365 --- /dev/null +++ b/juick-ws/src/main/webapp/WEB-INF/templates/index.html @@ -0,0 +1,14 @@ + + + + + Status + + + + +

+
+ + + \ No newline at end of file -- cgit v1.2.3