diff --git a/pom.xml b/pom.xml
index dd80def2243f4570ece4da109678d81ba934f227..ccd6a0d596f9507b9cc726e4adcbd6ca8f2f99a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -169,6 +169,16 @@
 			<groupId>org.springframework.integration</groupId>
 			<artifactId>spring-integration-mail</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-messaging</artifactId>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-websocket</artifactId>
+			<scope>compile</scope>
+		</dependency>
 		<!-- Security -->
 		<dependency>
 			<groupId>org.springframework.security</groupId>
@@ -235,8 +245,8 @@
 			<artifactId>javax.mail</artifactId>
 		</dependency>
 		<dependency>
-			<groupId>org.springframework</groupId>
-			<artifactId>spring-test</artifactId>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-test</artifactId>
 			<scope>test</scope>
 		</dependency>
 		<dependency>
@@ -244,6 +254,17 @@
 			<artifactId>spring-security-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+			<groupId>org.assertj</groupId>
+			<artifactId>assertj-core</artifactId>
+			<version>3.11.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-test</artifactId>
+			<scope>test</scope>
+		</dependency>
 		<dependency>
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
@@ -342,6 +363,12 @@
 			<artifactId>checker-qual</artifactId>
 			<version>2.5.8</version>
 		</dependency>
+		<dependency>
+			<groupId>javax.websocket</groupId>
+			<artifactId>javax.websocket-api</artifactId>
+			<version>1.1</version>
+			<scope>provided</scope>
+		</dependency>
 	</dependencies>
 
 	<build>
diff --git a/src/main/java/de/thm/arsnova/config/AppConfig.java b/src/main/java/de/thm/arsnova/config/AppConfig.java
index f1b869f1a9f87044dc46592b8d73f22430c489f2..50b9af42706f918dd23c79d6abdd2cd622710243 100644
--- a/src/main/java/de/thm/arsnova/config/AppConfig.java
+++ b/src/main/java/de/thm/arsnova/config/AppConfig.java
@@ -82,6 +82,7 @@ import java.util.List;
 @ComponentScan({
 		"de.thm.arsnova.cache",
 		"de.thm.arsnova.controller",
+		"de.thm.arsnova.controller.handler",
 		"de.thm.arsnova.event",
 		"de.thm.arsnova.security",
 		"de.thm.arsnova.service",
diff --git a/src/main/java/de/thm/arsnova/config/AppInitializer.java b/src/main/java/de/thm/arsnova/config/AppInitializer.java
index 6cf48b595e73a784bd5e3f7c7c5bab6316d827d8..26aae5722848cbc0a48f75fb1e332d7a8970b134 100644
--- a/src/main/java/de/thm/arsnova/config/AppInitializer.java
+++ b/src/main/java/de/thm/arsnova/config/AppInitializer.java
@@ -30,7 +30,8 @@ public class AppInitializer extends AbstractAnnotationConfigDispatcherServletIni
 		return new Class[] {
 				AppConfig.class,
 				PersistenceConfig.class,
-				SecurityConfig.class
+				SecurityConfig.class,
+				WebSocketConfig.class,
 		};
 	}
 
diff --git a/src/main/java/de/thm/arsnova/config/WebSocketConfig.java b/src/main/java/de/thm/arsnova/config/WebSocketConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..c81588390702a23c946c7d4851416b7f428dabbe
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/config/WebSocketConfig.java
@@ -0,0 +1,26 @@
+package de.thm.arsnova.config;
+
+import org.springframework.context.annotation.Bean;
+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;
+import org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy;
+
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
+
+	@Override
+	public void configureMessageBroker(MessageBrokerRegistry config) {
+		config.enableSimpleBroker("/room");
+		config.setApplicationDestinationPrefixes("/backend");
+	}
+
+	@Override
+	public void registerStompEndpoints(StompEndpointRegistry registry) {
+		registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/controller/handler/FeedbackCommandHandler.java b/src/main/java/de/thm/arsnova/controller/handler/FeedbackCommandHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1d5bea1ddd1f24b198e4d7482a94a54a286461e
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/controller/handler/FeedbackCommandHandler.java
@@ -0,0 +1,101 @@
+package de.thm.arsnova.controller.handler;
+
+import de.thm.arsnova.websocket.message.CreateFeedback;
+import de.thm.arsnova.websocket.message.FeedbackChanged;
+import de.thm.arsnova.websocket.message.FeedbackChangedPayload;
+import de.thm.arsnova.websocket.message.GetFeedback;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+
+@Component
+public class FeedbackCommandHandler {
+
+	HashMap<String, int[]> roomValues = new HashMap<>();
+
+	private final SimpMessagingTemplate messagingTemplate;
+
+	@Autowired
+	public FeedbackCommandHandler(SimpMessagingTemplate messagingTemplate) {
+		this.messagingTemplate = messagingTemplate;
+	}
+
+	synchronized private int[] updateFeedbackForRoom(String roomId, int index) {
+		int[] values = roomValues.getOrDefault(roomId, new int[4]);
+		values[index]++;
+		roomValues.put(roomId, values);
+		return values;
+	}
+
+	public void handle(CreateFeedbackCommand command) {
+		int updatedIndex = command.getPayload().getPayload().getValue();
+		int[] newVals = updateFeedbackForRoom(command.getRoomId(), updatedIndex);
+
+		FeedbackChanged feedbackChanged = new FeedbackChanged();
+		FeedbackChangedPayload feedbackChangedPayload = new FeedbackChangedPayload();
+		feedbackChangedPayload.setValues(newVals);
+		feedbackChanged.setPayload(feedbackChangedPayload);
+
+		messagingTemplate.convertAndSend(
+				"/room/" + command.getRoomId() + "/feedback.stream",
+				feedbackChanged
+		);
+	}
+
+	public void handle(GetFeedbackCommand command) {
+		int[] currentVals = roomValues.getOrDefault(command.getRoomId(), new int[4]);
+
+		FeedbackChanged feedbackChanged = new FeedbackChanged();
+		FeedbackChangedPayload feedbackChangedPayload = new FeedbackChangedPayload();
+		feedbackChangedPayload.setValues(currentVals);
+		feedbackChanged.setPayload(feedbackChangedPayload);
+
+		messagingTemplate.convertAndSend(
+				"/room/" + command.getRoomId() + "/feedback.stream",
+				feedbackChanged
+		);
+	}
+
+
+
+	public static class CreateFeedbackCommand {
+
+		private String roomId;
+		private CreateFeedback payload;
+
+		public CreateFeedbackCommand(String roomId, CreateFeedback payload) {
+			this.roomId = roomId;
+			this.payload = payload;
+		}
+
+		public CreateFeedback getPayload() {
+			return payload;
+		}
+
+		public String getRoomId() {
+			return roomId;
+		}
+	}
+
+	public static class GetFeedbackCommand {
+
+		private String roomId;
+		private GetFeedback payload;
+
+		public GetFeedbackCommand(String roomId, GetFeedback payload) {
+			this.roomId = roomId;
+			this.payload = payload;
+		}
+
+		public GetFeedback getPayload() {
+			return payload;
+		}
+
+		public String getRoomId() {
+			return roomId;
+		}
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/controller/handler/FeedbackHandler.java b/src/main/java/de/thm/arsnova/controller/handler/FeedbackHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad7946f937d8ef062cdc45f40747ec294609ff53
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/controller/handler/FeedbackHandler.java
@@ -0,0 +1,43 @@
+package de.thm.arsnova.controller.handler;
+
+import de.thm.arsnova.websocket.message.CreateFeedback;
+import de.thm.arsnova.websocket.message.GetFeedback;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.handler.annotation.DestinationVariable;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class FeedbackHandler {
+	private final FeedbackCommandHandler commandHandler;
+
+	@Autowired
+	public FeedbackHandler(FeedbackCommandHandler commandHandler) {
+		this.commandHandler = commandHandler;
+	}
+
+	@MessageMapping("/room/{roomId}/feedback.command")
+	public void send(
+			@DestinationVariable("roomId") String roomId,
+			CreateFeedback value
+	) throws Exception {
+
+		commandHandler.handle(
+				new FeedbackCommandHandler.CreateFeedbackCommand(roomId, value)
+		);
+
+	}
+
+	@MessageMapping("/room/{roomId}/feedback.query")
+	public void send(
+			@DestinationVariable("roomId") String roomId,
+			GetFeedback value
+	) throws Exception {
+
+		commandHandler.handle(
+				new FeedbackCommandHandler.GetFeedbackCommand(roomId, value)
+		);
+
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/CreateFeedback.java b/src/main/java/de/thm/arsnova/websocket/message/CreateFeedback.java
new file mode 100644
index 0000000000000000000000000000000000000000..f329d5f5c7de7b07e19eaa7760a22af406e6553a
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/CreateFeedback.java
@@ -0,0 +1,7 @@
+package de.thm.arsnova.websocket.message;
+
+public class CreateFeedback extends WebSocketMessage<CreateFeedbackPayload> {
+	public CreateFeedback() {
+		super(CreateFeedback.class.getSimpleName());
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/CreateFeedbackPayload.java b/src/main/java/de/thm/arsnova/websocket/message/CreateFeedbackPayload.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee74510fd0e835804bc32a152270c713c689a979
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/CreateFeedbackPayload.java
@@ -0,0 +1,20 @@
+package de.thm.arsnova.websocket.message;
+
+public class CreateFeedbackPayload implements WebSocketPayload {
+	int value;
+
+	public CreateFeedbackPayload() {
+	}
+
+	public CreateFeedbackPayload(int value) {
+		this.value = value;
+	}
+
+	public int getValue() {
+		return value;
+	}
+
+	public void setValue(int value) {
+		this.value = value;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/FeedbackChanged.java b/src/main/java/de/thm/arsnova/websocket/message/FeedbackChanged.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b0c6e62e0b30c2cdb9392fb0d97f26394028d3b
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/FeedbackChanged.java
@@ -0,0 +1,15 @@
+package de.thm.arsnova.websocket.message;
+
+public class FeedbackChanged extends WebSocketMessage<FeedbackChangedPayload> {
+	public FeedbackChanged() {
+		super(FeedbackChanged.class.getSimpleName());
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (o == null || getClass() != o.getClass()) return false;
+		FeedbackChanged that = (FeedbackChanged) o;
+		return this.getPayload().equals(that.getPayload());
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/FeedbackChangedPayload.java b/src/main/java/de/thm/arsnova/websocket/message/FeedbackChangedPayload.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb7e738baf2dde2e94c98e1d126f0b9b5017ebba
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/FeedbackChangedPayload.java
@@ -0,0 +1,28 @@
+package de.thm.arsnova.websocket.message;
+
+import java.util.Arrays;
+
+public class FeedbackChangedPayload implements WebSocketPayload {
+	int[] values = new int[4];
+
+	public int[] getValues() {
+		return values;
+	}
+
+	public void setValues(int[] values) {
+		this.values = values;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (o == null || getClass() != o.getClass()) return false;
+		FeedbackChangedPayload that = (FeedbackChangedPayload) o;
+		return Arrays.equals(values, that.values);
+	}
+
+	@Override
+	public int hashCode() {
+		return Arrays.hashCode(values);
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/GetFeedback.java b/src/main/java/de/thm/arsnova/websocket/message/GetFeedback.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6cd9ea267cc809cdc53b0c7ee5e0475cb236580
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/GetFeedback.java
@@ -0,0 +1,8 @@
+package de.thm.arsnova.websocket.message;
+
+public class GetFeedback extends WebSocketMessage<WebSocketPayload> {
+	public GetFeedback() {
+		super(GetFeedback.class.getSimpleName());
+	}
+}
+
diff --git a/src/main/java/de/thm/arsnova/websocket/message/Patched.java b/src/main/java/de/thm/arsnova/websocket/message/Patched.java
new file mode 100644
index 0000000000000000000000000000000000000000..87f84cab6e5bbd32db75c2dc5599ace34c8ae1c7
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/Patched.java
@@ -0,0 +1,7 @@
+package de.thm.arsnova.websocket.message;
+
+public class Patched extends WebSocketMessage<PatchedPayload> {
+	public Patched(String type) {
+		super(type);
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/PatchedPayload.java b/src/main/java/de/thm/arsnova/websocket/message/PatchedPayload.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c94099a0bc4448eaac3c9ed70d382f99e55fddc
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/PatchedPayload.java
@@ -0,0 +1,47 @@
+package de.thm.arsnova.websocket.message;
+
+public class PatchedPayload implements WebSocketPayload {
+	String type;
+
+	String id;
+
+	String propertyName;
+
+	boolean propertyValue;
+
+	public PatchedPayload(String type) {
+		this.type = type;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getPropertyName() {
+		return propertyName;
+	}
+
+	public void setPropertyName(String propertyName) {
+		this.propertyName = propertyName;
+	}
+
+	public boolean isPropertyValue() {
+		return propertyValue;
+	}
+
+	public void setPropertyValue(boolean propertyValue) {
+		this.propertyValue = propertyValue;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/WebSocketMessage.java b/src/main/java/de/thm/arsnova/websocket/message/WebSocketMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a0b6d4152f821554a36ae15f25c113b4ee1561f
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/WebSocketMessage.java
@@ -0,0 +1,27 @@
+package de.thm.arsnova.websocket.message;
+
+public class WebSocketMessage<P extends WebSocketPayload> {
+	private String type;
+
+	private P payload;
+
+	public WebSocketMessage(String type) {
+		this.type = type;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public P getPayload() {
+		return payload;
+	}
+
+	public void setPayload(P payload) {
+		this.payload = payload;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/websocket/message/WebSocketPayload.java b/src/main/java/de/thm/arsnova/websocket/message/WebSocketPayload.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ca21c77ca38cb5e9340f094385a4189ecc78744
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websocket/message/WebSocketPayload.java
@@ -0,0 +1,4 @@
+package de.thm.arsnova.websocket.message;
+
+public interface WebSocketPayload {
+}
diff --git a/src/test/java/de/thm/arsnova/websocket/FeedbackCommandHandlerTest.java b/src/test/java/de/thm/arsnova/websocket/FeedbackCommandHandlerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f99e9026eabe2c3599a792e0e3798ec709882bfb
--- /dev/null
+++ b/src/test/java/de/thm/arsnova/websocket/FeedbackCommandHandlerTest.java
@@ -0,0 +1,76 @@
+package de.thm.arsnova.websocket;
+
+import de.thm.arsnova.controller.handler.FeedbackCommandHandler;
+import de.thm.arsnova.websocket.message.CreateFeedback;
+import de.thm.arsnova.websocket.message.CreateFeedbackPayload;
+import de.thm.arsnova.websocket.message.FeedbackChanged;
+import de.thm.arsnova.websocket.message.FeedbackChangedPayload;
+import de.thm.arsnova.websocket.message.GetFeedback;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+
+@RunWith(SpringRunner.class)
+public class FeedbackCommandHandlerTest {
+
+	@MockBean
+	private SimpMessagingTemplate messagingTemplate;
+
+	private FeedbackCommandHandler commandHandler;
+
+	@Before
+	public void setUp() {
+		this.commandHandler = new FeedbackCommandHandler(messagingTemplate);
+	}
+
+	@Test
+	public void getFeedback() {
+		String roomId = "12345678";
+		GetFeedback getFeedback = new GetFeedback();
+		FeedbackCommandHandler.GetFeedbackCommand getFeedbackCommand =
+				new FeedbackCommandHandler.GetFeedbackCommand(roomId, null);
+
+		commandHandler.handle(getFeedbackCommand);
+
+		FeedbackChangedPayload feedbackChangedPayload = new FeedbackChangedPayload();
+		int[] expectedVals = new int[]{0, 0, 0, 0};
+		feedbackChangedPayload.setValues(expectedVals);
+		FeedbackChanged feedbackChanged = new FeedbackChanged();
+		feedbackChanged.setPayload(feedbackChangedPayload);
+
+		ArgumentCaptor<String> topicCaptor = ArgumentCaptor.forClass(String.class);
+		ArgumentCaptor<FeedbackChanged> messageCaptor =
+				ArgumentCaptor.forClass(FeedbackChanged.class);
+
+		verify(messagingTemplate).convertAndSend(topicCaptor.capture(), messageCaptor.capture());
+		assertThat(topicCaptor.getValue()).isEqualTo("/room/" + roomId + "/feedback");
+		assertThat(messageCaptor.getValue()).isEqualTo(feedbackChanged);
+	}
+
+	@Test
+	public void sendFeedback() {
+		String roomId = "12345678";
+		CreateFeedbackPayload createFeedbackPayload = new CreateFeedbackPayload(1);
+		createFeedbackPayload.setValue(1);
+		CreateFeedback createFeedback = new CreateFeedback();
+		createFeedback.setPayload(createFeedbackPayload);
+		FeedbackCommandHandler.CreateFeedbackCommand createFeedbackCommand =
+				new FeedbackCommandHandler.CreateFeedbackCommand(roomId, createFeedback);
+
+		commandHandler.handle(createFeedbackCommand);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(messagingTemplate).convertAndSend(captor.capture(), any(FeedbackChanged.class));
+		assertThat(captor.getValue()).isEqualTo("/room/" + roomId + "/feedback");
+	}
+}
+
+
diff --git a/src/test/java/de/thm/arsnova/websocket/FeedbackHandlerTest.java b/src/test/java/de/thm/arsnova/websocket/FeedbackHandlerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a5748995768aeb1719334e8bf8a4a1b76206135
--- /dev/null
+++ b/src/test/java/de/thm/arsnova/websocket/FeedbackHandlerTest.java
@@ -0,0 +1,44 @@
+package de.thm.arsnova.websocket;
+
+import de.thm.arsnova.controller.handler.FeedbackCommandHandler;
+import de.thm.arsnova.controller.handler.FeedbackHandler;
+import de.thm.arsnova.websocket.message.CreateFeedback;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@RunWith(SpringRunner.class)
+public class FeedbackHandlerTest {
+
+	@MockBean
+	private FeedbackCommandHandler feedbackCommandHandler;
+
+	private FeedbackHandler feedbackHandler;
+
+	@Before
+	public void setUp() {
+		this.feedbackHandler = new FeedbackHandler(feedbackCommandHandler);
+	}
+
+	@Test
+	public void sendFeedback() throws Exception {
+		feedbackHandler.send(
+				"12345678",
+				new CreateFeedback()
+		);
+
+		ArgumentCaptor<FeedbackCommandHandler.CreateFeedbackCommand> captor =
+				ArgumentCaptor.forClass(FeedbackCommandHandler.CreateFeedbackCommand.class);
+		verify(feedbackCommandHandler, times(1)).handle(captor.capture());
+
+		assertThat(captor.getValue().getRoomId()).isEqualTo("12345678");
+		assertThat(captor.getValue().getPayload()).isInstanceOf(CreateFeedback.class);
+	}
+}