working on websocket

This commit is contained in:
Lucas Pleß 2012-03-10 21:38:05 +01:00
parent 23bc67c8ca
commit a1feb25187
13 changed files with 243 additions and 183 deletions

30
pom.xml
View File

@ -8,7 +8,8 @@
<properties>
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
<jettyVersion>7.2.0.v20101020</jettyVersion>
<!--<jettyVersion>7.2.0.v20101020</jettyVersion>-->
<jettyVersion>8.1.0.RC4</jettyVersion>
<org.slf4j.version>1.6.4</org.slf4j.version>
</properties>
@ -19,6 +20,11 @@
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>org.eclipse.repository.development</id>
<name>Jetty Repo</name>
<url>http://oss.sonatype.org/content/groups/jetty/</url>
</repository>
</repositories>
<dependencies>
@ -111,6 +117,28 @@
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>0.7.2</version>
<scope>compile</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>javax.inject</groupId>-->
<!--<artifactId>javax.inject</artifactId>-->
<!--<version>1</version>-->
<!--<scope>compile</scope>-->
<!--</dependency>-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.9</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@ -9,7 +9,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.HashMap;
@ -27,14 +26,13 @@ public class DMXMixerImpl implements DMXMixer, ApplicationListener<DeviceChanged
@Autowired
public final void setArtNetSender(SimpleArtNetSender artNetSender) {
this.artNetSender = artNetSender;
LOGGER.debug("autowired arnetSender in DMXMixerImpl");
}
public void setArtNetDeviceAddress(String artNetDeviceAddress) {
this.artNetDeviceAddress = artNetDeviceAddress;
}
public final void initDMXData() {
private void initDMXData() {
for (int i = DMX.DMX_CHANNEL_INDEX_MIN; i <= DMX.DMX_CHANNEL_INDEX_MAX; i++) {
dmxMap.put(i, DMX.DMX_CHANNEL_VALUE_MIN);
}
@ -52,7 +50,12 @@ public class DMXMixerImpl implements DMXMixer, ApplicationListener<DeviceChanged
}
}
@Override
public final boolean updateDevice(BuntiDevice device, Map<String, Object> options) {
if(device == null || options == null || options.size() == 0) {
return false;
}
BuntiDMXDevice dmxDev = (BuntiDMXDevice) device;
if (dmxDev.setValuesFromOptions(options)) {

View File

@ -0,0 +1,30 @@
/**
*
*/
package de.ctdo.bunti.websocket;
import javax.servlet.http.HttpServletRequest;
import org.atmosphere.cpr.AtmosphereResource;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.context.request.NativeWebRequest;
public class AtmosphereResourceArgumentResolver implements WebArgumentResolver {
/* (non-Javadoc)
* @see org.springframework.web.bind.support.WebArgumentResolver#resolveArgument(org.springframework.core.MethodParameter, org.springframework.web.context.request.NativeWebRequest)
*/
@Override
public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {
if (AtmosphereResource.class.isAssignableFrom(methodParameter.getParameterType())) {
return AtmosphereUtils.getAtmosphereResource(webRequest.getNativeRequest(HttpServletRequest.class));
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}

View File

@ -0,0 +1,24 @@
package de.ctdo.bunti.websocket;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereServlet;
import org.springframework.util.Assert;
public final class AtmosphereUtils {
public static AtmosphereResource<HttpServletRequest, HttpServletResponse> getAtmosphereResource(
HttpServletRequest request) {
AtmosphereResource<HttpServletRequest, HttpServletResponse> resource =
(AtmosphereResource<HttpServletRequest, HttpServletResponse>) request.getAttribute(AtmosphereServlet.ATMOSPHERE_RESOURCE);
Assert.notNull(resource,"AtmosphereResource could not be located for the request. Check that AtmosphereServlet is configured correctly in web.xml");
return resource;
}
}

View File

@ -1,51 +0,0 @@
package de.ctdo.bunti.websocket;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.stereotype.Component;
//
//import com.sun.grizzly.tcp.Request;
//import com.sun.grizzly.websockets.ProtocolHandler;
//import com.sun.grizzly.websockets.WebSocket;
//import com.sun.grizzly.websockets.WebSocketApplication;
//import com.sun.grizzly.websockets.WebSocketListener;
//
//@Component
//public class BuntiControllerApplication extends WebSocketApplication {
// private static final Logger LOGGER = LoggerFactory.getLogger(BuntiControllerApplication.class);
//
// @Override
// public final WebSocket createWebSocket(ProtocolHandler protocolHandler, WebSocketListener... listeners) {
// BuntiControllerWebSocket socket = new BuntiControllerWebSocket(protocolHandler, listeners);
//// BuntiControllerImpl.getInstance().addListener(socket);
// return socket;
// }
//
// @Override
// public final boolean isApplicationRequest(Request request) {
// final String uri = request.requestURI().toString();
// return uri.endsWith("/bunti");
// }
//
// @Override
// public final void onClose(WebSocket socket, com.sun.grizzly.websockets.DataFrame frame) {
// BuntiControllerWebSocket ws = (BuntiControllerWebSocket) socket;
//// BuntiControllerImpl.getInstance().removeListener(ws);
// }
//
// @Override
// public void onMessage(WebSocket socket, String text) {
//
//
//// BuntiControllerImpl.getInstance().performJSONString(text);
//
//
//// for (final WebSocket webSocket : getWebSockets()) {
//// DMXControllerWebSocket ws = (DMXControllerWebSocket) webSocket;
////
////
//// }
// //super.onMessage(socket, text);
// }
//
//}

View File

@ -1,40 +0,0 @@
package de.ctdo.bunti.websocket;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//// das klappt so jedenfalls alles noch nicht :)
//@Component
//public class BuntiControllerServlet { // extends HttpServlet {
// private static final long serialVersionUID = 1L;
// private static final Logger LOGGER = LoggerFactory.getLogger(BuntiControllerServlet.class);
//
// private BuntiControllerApplication app;
//
// @Autowired
// public final void setApp(BuntiControllerApplication app) {
// this.app = app;
// }
//
//
//
// public void buntiControllerApplication() {
//// WebSocketEngine.getEngine().register(app);
//// LOGGER.debug("registered buntiControllerApplication");
// }
//
//// @Override
//// public void init(ServletConfig config) throws ServletException {
//// WebSocketEngine.getEngine().register(app);
//// LOGGER.debug("registered buntiControllerApplication");
//// }
////
//// @Override
//// public void destroy() {
//// WebSocketEngine.getEngine().unregister(app);
//// LOGGER.debug("unregistered buntiControllerApplication");
//// }
//
//}

View File

@ -1,36 +0,0 @@
package de.ctdo.bunti.websocket;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import com.sun.grizzly.websockets.DefaultWebSocket;
//import com.sun.grizzly.websockets.ProtocolHandler;
//import com.sun.grizzly.websockets.WebSocketListener;
//
///**
// * Ein DMXControllerWebSocket gehoert immer zu einem Browserfenster/Tab
// * @author lucas
// *
// */
//public class BuntiControllerWebSocket extends DefaultWebSocket {
//
// private static final Logger LOGGER = LoggerFactory.getLogger(BuntiControllerWebSocket.class);
//
// public BuntiControllerWebSocket(ProtocolHandler protocolHandler, WebSocketListener[] listeners) {
// super(protocolHandler, listeners);
// }
//
//
//// @Override
//// public void DMXDataChanged(int[] dmx512data) {
////
//// JSONArray arr = JSONArray.fromObject(dmx512data);
//// JSONObject obj = new JSONObject();
//// obj.put("dmx512values", arr);
////
//// send(obj.toString());
//// }
//
//
//
//}

View File

@ -0,0 +1,57 @@
package de.ctdo.bunti.websocket;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.Broadcaster;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
@Controller
public class WebSocketController {
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketController.class);
@RequestMapping(value="/buntisocket", method=RequestMethod.GET)
@ResponseBody
public void websockets(final AtmosphereResource<HttpServletRequest,HttpServletResponse> event) {
final HttpServletRequest req = event.getRequest();
// final HttpServletResponse res = event.getResponse();
LOGGER.debug("call to websockets " + req.toString());
final ObjectMapper mapper = new ObjectMapper();
event.suspend();
final Broadcaster bc = event.getBroadcaster();
bc.scheduleFixedBroadcast(new Callable<String>() {
private long sinceId = 0;
@Override
public String call() throws Exception {
LOGGER.debug("call was called");
return mapper.writeValueAsString("blafaselblubb");
}
}, 10, TimeUnit.SECONDS);
}
}

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"
>
<!--<context:component-scan base-package="de.ctdo">-->
<!--&lt;!&ndash;<context:exclude-filter type="regex" expression="de\.ctdo\.bunti\.web.*" />&ndash;&gt;-->
<!--</context:component-scan>-->
<!--<task:annotation-driven scheduler="myScheduler"/>-->
<!--<task:scheduler id="myScheduler" pool-size="3"/>-->
<!--<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">-->
<!--<property name="location" value="classpath:bunti.properties"/>-->
<!--</bean>-->
<!--<bean id="dmxMixer" class="de.ctdo.bunti.dmx.DMXMixerImpl">-->
<!--<property name="artNetDeviceAddress" value="${artnet.deviceAddress}"/>-->
<!--</bean>-->
</beans>

View File

@ -19,7 +19,7 @@
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
@ -32,6 +32,10 @@
<level value="debug" />
</logger>
<logger name="org.atmosphere">
<level value="debug" />
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />

View File

@ -27,11 +27,11 @@
<task:scheduler id="myScheduler" pool-size="3"/>
<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:bunti.properties"/>
</bean>
<bean id="dmxMixer" class="de.ctdo.bunti.dmx.DMXMixerImpl">
<bean class="de.ctdo.bunti.dmx.DMXMixerImpl">
<property name="artNetDeviceAddress" value="${artnet.deviceAddress}"/>
</bean>

View File

@ -29,21 +29,60 @@
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--<servlet>-->
<!--<servlet-name>dispatcher</servlet-name>-->
<!--<servlet-class>-->
<!--org.springframework.web.servlet.DispatcherServlet-->
<!--</servlet-class>-->
<!--<load-on-startup>1</load-on-startup>-->
<!--</servlet>-->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>25</session-timeout>
</session-config>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.MeteorServlet</servlet-class>
<init-param>
<param-name>org.atmosphere.servlet</param-name>
<param-value>org.springframework.web.servlet.DispatcherServlet</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterClass</param-name>
<param-value>org.atmosphere.cpr.DefaultBroadcaster</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
<param-value>org.atmosphere.client.JavascriptClientFilter</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.CometSupport.maxInactiveActivity</param-name>
<param-value>30</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.useStream</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.useWebSocket</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.useNative</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -1,8 +1,13 @@
package de.ctdo.bunti.dmx;
import de.ctdo.bunti.model.BuntiDevice;
import de.ctdo.bunti.model.Par56Spot;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
public class DMXMixerImplTest {
@ -20,22 +25,49 @@ public class DMXMixerImplTest {
@Test
public void testSetArtNetDeviceAddress() throws Exception {
dut.setArtNetDeviceAddress("172.0.0.1");
}
@Test
public void testInitDMXData() throws Exception {
}
@Test
@Test(expected = NullPointerException.class)
public void testSendOutDMXBuffer() throws Exception {
dut.sendOutDMXBuffer();
}
@Test
public void testUpdateDevice() throws Exception {
BuntiDevice device = new Par56Spot(23,42,"deviceName");
Map<String,Object> options = new HashMap<String, Object>();
options.put("red", 44);
assertTrue(dut.updateDevice(device, options));
}
@Test
public void testUpdateDeviceWrong1() throws Exception {
BuntiDevice device = new Par56Spot(23,42,"deviceName");
assertFalse(dut.updateDevice(device, null));
}
@Test
public void testUpdateDeviceWrong2() throws Exception {
Map<String,Object> options = new HashMap<String, Object>();
options.put("red", 44);
assertFalse(dut.updateDevice(null, options));
}
@Test
public void testUpdateDeviceWrong3() throws Exception {
BuntiDevice device = new Par56Spot(23,42,"deviceName");
Map<String,Object> options = new HashMap<String, Object>();
assertFalse(dut.updateDevice(device, options));
}
@Test
public void testUpdateDeviceWrong4() throws Exception {
BuntiDevice device = new Par56Spot(23,42,"deviceName");
Map<String,Object> options = new HashMap<String, Object>();
options.put("rednonexistent", 44);
assertFalse(dut.updateDevice(device, options));
}
@Test
@ -73,9 +105,6 @@ public class DMXMixerImplTest {
assertFalse(dut.setDMX512Channel(-1, -10));
}
@Test
public void testOnApplicationEvent() throws Exception {