http://cloudsole-metrics.herokuapp.com
https://github.com/thysmichels/cloudsole-metrics
1. Basic WebAppInitializer
2. WebConfiguration with EnableScheduling
3. WebSocketConfiguration with EnableWebSocketMessageBroker
4. Random Number Generator with ApplicationListener
5. Sock.js Javascript
1. Basic WebAppInitializer
package com.thysmichels.websockets.configuration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext context) throws ServletException {
final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.scan("com.thysmichels.websockets");
context.addListener(new ContextLoaderListener(root));
final ServletRegistration.Dynamic appServlet = context.addServlet("appServlet",new DispatcherServlet(new GenericWebApplicationContext()));
appServlet.setAsyncSupported(true);
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/*");
}
}
2. WebConfiguration with EnableScheduling
package com.thysmichels.websockets.configuration;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
@EnableScheduling
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureDefaultServletHandling(
final DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
3. WebSocketConfiguration with EnableWebSocketMessageBroker
package com.thysmichels.websockets.configuration;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
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 WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
}
@Override
public void registerStompEndpoints(final StompEndpointRegistry registry) {
registry.addEndpoint("/metrics").withSockJS();
}
@Override
public void configureClientInboundChannel(final ChannelRegistration registration) {}
@Override
public void configureClientOutboundChannel(final ChannelRegistration registration) { }
}
4. Random Number Generator with ApplicationListener
package com.thysmichels.websockets.utils;
import java.util.Random;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.messaging.core.MessageSendingOperations;
import org.springframework.messaging.simp.broker.BrokerAvailabilityEvent;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class RandomDataGenerator implements ApplicationListener<BrokerAvailabilityEvent> {
private final MessageSendingOperations<String> messagingTemplate;
@Autowired
public RandomDataGenerator(final MessageSendingOperations<String> messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@Override
public void onApplicationEvent(final BrokerAvailabilityEvent event) {
}
@Scheduled(fixedDelay = 1000)
public void sendDataUpdates() {
this.messagingTemplate.convertAndSend("/data", new Random().nextInt(100));
}
}
5. Sock.js Javascript
/**
* Created by tmichels on 8/19/14.
*/
//var stompClient = null;
var updateOpts = {'minVal':'0','maxVal':'100','newVal':'1'};
var randomData;
var socket = new SockJS('/metrics');
var client = Stomp.over(socket);
client.connect('admin', 'password', function(frame) {
client.subscribe("/data", function(message) {
var point = [ (new Date()).getTime(), parseInt(message.body) ];
gaugeUpdate('cf-gauge-1', {'minVal':'0','maxVal':'100','newVal':parseInt(message.body)})
$('#spark-1').each(function(){
customSparkOptions = {};
customSparkOptions.minSpotColor = true;
var sparkOptions = cf_defaultSparkOpts;
var sparkOptions = $.extend({}, cf_defaultSparkOpts, customSparkOptions);
data.push(parseInt(message.body));
createSparkline($(this), data, sparkOptions);
});
$('#metric-1 .metric').html(message.body);
$('#metric-1 .large').html(message.body);
$('#metric-2 .metric').html(message.body);
$('#metric-2 .large').html(message.body);
var element = $(this).data('update');
cf_rSVPs[$('#svp-1').attr('id')].chart.update(parseInt(message.body));
$('#svp-1 .chart').data('percent', parseInt(message.body));
$('#svp-1 .metric').html(message.body);
// $('#cf-svmc-sparkline .metric').html(message.body);
$('#cf-rag-1').each(function(){
// Dummy data for RAG
ragData = [60,30,parseInt(message.body)];
ragLabels = ['Success','Bounce','Abandoned'];
ragOpts = {postfix:'%'}
cf_rRags[$(this).prop('id')] = new RagChart($(this).prop('id'), ragData, ragLabels, ragOpts);
});
$('#cf-pie-1').each(function(){
var pdata = [
{
value : parseInt(message.body),
color : pieSegColors[3],
label: 'Success'
},
{
value : parseInt(message.body)+50,
color : pieSegColors[2],
label: 'Bounce'
},
{
value: parseInt(message.body)+100,
color: pieSegColors[1],
label: 'Abandoned'
}
]
var $container = $(this);
var pId = $container.prop('id');
// Store chart information
cf_rPs[pId] = {};
cf_rPs[pId].data = pdata;
// Set options per chart
customOptions = {};
customOptions.animation = false;
cf_rPs[pId].options = customOptions;
// Create chart
createPieChart($container);
});
$('#cf-funnel-1').each(function(){
funData = [parseInt(message.body)+3000,parseInt(message.body)+1500,parseInt(message.body)+500,parseInt(message.body)+250,parseInt(message.body)];
funLabels = ['Visits','Cart','Checkout','Purchase','Refund'];
funOptions = {barOpacity:true, layout:'left'};
cf_rFunnels[$(this).prop('id')] = new FunnelChart($(this).prop('id'), funData, funLabels, funOptions);
});
});
});
Like this:
Like Loading...