From 55daef524d5dbf2e3b0b1c7c82309d1f3a163b5c Mon Sep 17 00:00:00 2001
From: Christoph Thelen <christoph.thelen@mni.thm.de>
Date: Thu, 19 Feb 2015 12:39:02 +0100
Subject: [PATCH] Remove socket dependency, add @Async for Answer events

---
 .../de/thm/arsnova/config/ExtraConfig.java    |  5 +-
 .../arsnova/controller/SocketController.java  |  4 +-
 .../domain/LearningProgressFactory.java       | 12 +++++
 .../DeleteFeedbackForSessionsEvent.java       | 52 +++++++++++++++++++
 .../thm/arsnova/events/NewFeedbackEvent.java  | 35 +++++++++++++
 .../thm/arsnova/events/NovaEventVisitor.java  |  6 +++
 .../arsnova/events/StatusSessionEvent.java    | 35 +++++++++++++
 .../thm/arsnova/services/FeedbackService.java | 24 ++++++---
 .../thm/arsnova/services/QuestionService.java |  4 --
 .../thm/arsnova/services/SessionService.java  | 18 ++++---
 .../de/thm/arsnova/services/UserService.java  |  4 --
 .../de/thm/arsnova/socket/ARSnovaSocket.java  | 31 +++++++++++
 .../arsnova/socket/ARSnovaSocketIOServer.java | 27 ++++++++--
 .../arsnova/socket/ARSnovaSocketListener.java | 41 +++++++++++++++
 14 files changed, 267 insertions(+), 31 deletions(-)
 create mode 100644 src/main/java/de/thm/arsnova/events/DeleteFeedbackForSessionsEvent.java
 create mode 100644 src/main/java/de/thm/arsnova/events/NewFeedbackEvent.java
 create mode 100644 src/main/java/de/thm/arsnova/events/StatusSessionEvent.java
 create mode 100644 src/main/java/de/thm/arsnova/socket/ARSnovaSocket.java
 create mode 100644 src/main/java/de/thm/arsnova/socket/ARSnovaSocketListener.java

diff --git a/src/main/java/de/thm/arsnova/config/ExtraConfig.java b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
index 0e6ba84a..45b375c2 100644
--- a/src/main/java/de/thm/arsnova/config/ExtraConfig.java
+++ b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
@@ -33,6 +33,7 @@ import org.springframework.core.io.Resource;
 
 import de.thm.arsnova.connector.client.ConnectorClient;
 import de.thm.arsnova.connector.client.ConnectorClientImpl;
+import de.thm.arsnova.socket.ARSnovaSocket;
 import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Configuration
@@ -80,7 +81,7 @@ public class ExtraConfig {
 
 	@Profile("!test")
 	@Bean(name = "socketServer", initMethod = "startServer", destroyMethod = "stopServer")
-	public ARSnovaSocketIOServer socketServer() {
+	public ARSnovaSocket socketServer() {
 		final ARSnovaSocketIOServer socketServer = new ARSnovaSocketIOServer();
 		socketServer.setHostIp(socketIp);
 		socketServer.setPortNumber(socketPort);
@@ -92,7 +93,7 @@ public class ExtraConfig {
 
 	@Profile("test")
 	@Bean(name = "socketServer", initMethod = "startServer", destroyMethod = "stopServer")
-	public ARSnovaSocketIOServer socketTestServer() {
+	public ARSnovaSocket socketTestServer() {
 		final int testSocketPort = 1234;
 		final ARSnovaSocketIOServer socketServer = new ARSnovaSocketIOServer();
 		socketServer.setHostIp(socketIp);
diff --git a/src/main/java/de/thm/arsnova/controller/SocketController.java b/src/main/java/de/thm/arsnova/controller/SocketController.java
index 7d5945d8..9c698087 100644
--- a/src/main/java/de/thm/arsnova/controller/SocketController.java
+++ b/src/main/java/de/thm/arsnova/controller/SocketController.java
@@ -35,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.services.IUserService;
 import de.thm.arsnova.services.UserSessionService;
-import de.thm.arsnova.socket.ARSnovaSocketIOServer;
+import de.thm.arsnova.socket.ARSnovaSocket;
 
 @RestController
 @RequestMapping("/socket")
@@ -48,7 +48,7 @@ public class SocketController extends AbstractController {
 	private UserSessionService userSessionService;
 
 	@Autowired
-	private ARSnovaSocketIOServer server;
+	private ARSnovaSocket server;
 
 	private static final Logger LOGGER = LoggerFactory.getLogger(SocketController.class);
 
diff --git a/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java b/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
index ef69aadc..ab378a46 100644
--- a/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
+++ b/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
@@ -26,12 +26,15 @@ import de.thm.arsnova.events.DeleteAllLectureAnswersEvent;
 import de.thm.arsnova.events.DeleteAllPreparationAnswersEvent;
 import de.thm.arsnova.events.DeleteAllQuestionsAnswersEvent;
 import de.thm.arsnova.events.DeleteAnswerEvent;
+import de.thm.arsnova.events.DeleteFeedbackForSessionsEvent;
 import de.thm.arsnova.events.DeleteInterposedQuestionEvent;
 import de.thm.arsnova.events.DeleteQuestionEvent;
 import de.thm.arsnova.events.NewAnswerEvent;
+import de.thm.arsnova.events.NewFeedbackEvent;
 import de.thm.arsnova.events.NewInterposedQuestionEvent;
 import de.thm.arsnova.events.NewQuestionEvent;
 import de.thm.arsnova.events.NovaEventVisitor;
+import de.thm.arsnova.events.StatusSessionEvent;
 
 @Component
 public class LearningProgressFactory implements NovaEventVisitor, ILearningProgressFactory {
@@ -82,4 +85,13 @@ public class LearningProgressFactory implements NovaEventVisitor, ILearningProgr
 	@Override
 	public void visit(DeleteAllLectureAnswersEvent event) {}
 
+	@Override
+	public void visit(NewFeedbackEvent newFeedbackEvent) {}
+
+	@Override
+	public void visit(DeleteFeedbackForSessionsEvent deleteFeedbackEvent) {}
+
+	@Override
+	public void visit(StatusSessionEvent statusSessionEvent) {}
+
 }
diff --git a/src/main/java/de/thm/arsnova/events/DeleteFeedbackForSessionsEvent.java b/src/main/java/de/thm/arsnova/events/DeleteFeedbackForSessionsEvent.java
new file mode 100644
index 00000000..857e5937
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/DeleteFeedbackForSessionsEvent.java
@@ -0,0 +1,52 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.events;
+
+import java.util.Set;
+
+import de.thm.arsnova.entities.Session;
+import de.thm.arsnova.entities.User;
+
+public class DeleteFeedbackForSessionsEvent extends NovaEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	private final Set<Session> sessions;
+
+	private final User user;
+
+	public DeleteFeedbackForSessionsEvent(Object source, Set<Session> sessions, User user) {
+		super(source);
+		this.sessions = sessions;
+		this.user = user;
+	}
+
+	public Set<Session> getSessions() {
+		return sessions;
+	}
+
+	public User getUser() {
+		return user;
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/events/NewFeedbackEvent.java b/src/main/java/de/thm/arsnova/events/NewFeedbackEvent.java
new file mode 100644
index 00000000..c06f84ca
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/NewFeedbackEvent.java
@@ -0,0 +1,35 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.events;
+
+import de.thm.arsnova.entities.Session;
+
+public class NewFeedbackEvent extends SessionEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	public NewFeedbackEvent(Object source, Session session) {
+		super(source, session);
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java b/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
index 75968075..ab820bf2 100644
--- a/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
+++ b/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
@@ -37,4 +37,10 @@ public interface NovaEventVisitor {
 
 	void visit(DeleteAllLectureAnswersEvent deleteAllLectureAnswersEvent);
 
+	void visit(NewFeedbackEvent newFeedbackEvent);
+
+	void visit(DeleteFeedbackForSessionsEvent deleteFeedbackEvent);
+
+	void visit(StatusSessionEvent statusSessionEvent);
+
 }
diff --git a/src/main/java/de/thm/arsnova/events/StatusSessionEvent.java b/src/main/java/de/thm/arsnova/events/StatusSessionEvent.java
new file mode 100644
index 00000000..19034dc9
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/StatusSessionEvent.java
@@ -0,0 +1,35 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.events;
+
+import de.thm.arsnova.entities.Session;
+
+public class StatusSessionEvent extends SessionEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	public StatusSessionEvent(Object source, Session session) {
+		super(source, session);
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/services/FeedbackService.java b/src/main/java/de/thm/arsnova/services/FeedbackService.java
index 7b178229..bb594d0e 100644
--- a/src/main/java/de/thm/arsnova/services/FeedbackService.java
+++ b/src/main/java/de/thm/arsnova/services/FeedbackService.java
@@ -27,6 +27,8 @@ import javax.annotation.PostConstruct;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
@@ -35,18 +37,16 @@ import de.thm.arsnova.dao.IDatabaseDao;
 import de.thm.arsnova.entities.Feedback;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
+import de.thm.arsnova.events.DeleteFeedbackForSessionsEvent;
+import de.thm.arsnova.events.NewFeedbackEvent;
 import de.thm.arsnova.exceptions.NoContentException;
 import de.thm.arsnova.exceptions.NotFoundException;
-import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Service
-public class FeedbackService implements IFeedbackService {
+public class FeedbackService implements IFeedbackService, ApplicationEventPublisherAware {
 
 	private static final int DEFAULT_SCHEDULER_DELAY = 5000;
 
-	@Autowired
-	private ARSnovaSocketIOServer server;
-
 	/**
 	 * minutes, after which the feedback is deleted
 	 */
@@ -58,6 +58,8 @@ public class FeedbackService implements IFeedbackService {
 
 	private FeedbackStorage feedbackStorage;
 
+	private ApplicationEventPublisher publisher;
+
 	public final void setDatabaseDao(final IDatabaseDao newDatabaseDao) {
 		databaseDao = newDatabaseDao;
 	}
@@ -96,11 +98,11 @@ public class FeedbackService implements IFeedbackService {
 		for (Map.Entry<User, Set<Session>> entry : affectedSessionsOfUsers.entrySet()) {
 			final User user = entry.getKey();
 			final Set<Session> arsSessions = entry.getValue();
-			server.reportDeletedFeedback(user, arsSessions);
+			this.publisher.publishEvent(new DeleteFeedbackForSessionsEvent(this, arsSessions, user));
 		}
 		// For each session that has deleted feedback, send the new feedback to all clients
 		for (Session session : deletedFeedbackOfUsersInSession.keySet()) {
-			server.reportUpdatedFeedbackForSession(session);
+			this.publisher.publishEvent(new NewFeedbackEvent(this, session));
 		}
 	}
 
@@ -152,7 +154,8 @@ public class FeedbackService implements IFeedbackService {
 			throw new NotFoundException();
 		}
 		feedbackStorage.saveFeedback(session, value, user);
-		server.reportUpdatedFeedbackForSession(session);
+
+		this.publisher.publishEvent(new NewFeedbackEvent(this, session));
 		return true;
 	}
 
@@ -164,4 +167,9 @@ public class FeedbackService implements IFeedbackService {
 		}
 		return feedbackStorage.getMyFeedback(session, user);
 	}
+
+	@Override
+	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
+		this.publisher = publisher;
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java
index 4bff1ebf..e5a4adfb 100644
--- a/src/main/java/de/thm/arsnova/services/QuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/QuestionService.java
@@ -56,7 +56,6 @@ import de.thm.arsnova.events.NewQuestionEvent;
 import de.thm.arsnova.exceptions.BadRequestException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.exceptions.UnauthorizedException;
-import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Service
 public class QuestionService implements IQuestionService, ApplicationEventPublisherAware {
@@ -67,9 +66,6 @@ public class QuestionService implements IQuestionService, ApplicationEventPublis
 	@Autowired
 	private IUserService userService;
 
-	@Autowired
-	private ARSnovaSocketIOServer socketIoServer;
-
 	@Value("${upload.filesize_b}")
 	private int uploadFileSizeByte;
 
diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java
index 7f3a9f71..e9b739e1 100644
--- a/src/main/java/de/thm/arsnova/services/SessionService.java
+++ b/src/main/java/de/thm/arsnova/services/SessionService.java
@@ -25,6 +25,8 @@ import java.util.UUID;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
 import org.slf4j.Logger;
@@ -41,14 +43,14 @@ import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.SessionInfo;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.entities.transport.ImportExportSession;
+import de.thm.arsnova.events.StatusSessionEvent;
 import de.thm.arsnova.exceptions.ForbiddenException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.exceptions.BadRequestException;
 import de.thm.arsnova.exceptions.RequestEntityTooLargeException;
-import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Service
-public class SessionService implements ISessionService {
+public class SessionService implements ISessionService, ApplicationEventPublisherAware {
 
 	public static class SessionNameComparator implements Comparator<Session>, Serializable {
 		private static final long serialVersionUID = 1L;
@@ -92,9 +94,6 @@ public class SessionService implements ISessionService {
 	@Autowired
 	private IUserService userService;
 
-	@Autowired
-	private ARSnovaSocketIOServer socketIoServer;
-
 	@Autowired
 	private ILearningProgressFactory learningProgressFactory;
 
@@ -104,6 +103,8 @@ public class SessionService implements ISessionService {
 	@Value("${pp.logofilesize_b}")
 	private int uploadFileSizeByte;
 
+	private ApplicationEventPublisher publisher;
+
 	public static final Logger LOGGER = LoggerFactory.getLogger(SessionService.class);
 
 	public void setDatabaseDao(final IDatabaseDao newDatabaseDao) {
@@ -278,7 +279,7 @@ public class SessionService implements ISessionService {
 			throw new ForbiddenException();
 		}
 		session.setActive(lock);
-		socketIoServer.reportSessionStatus(sessionkey, lock);
+		this.publisher.publishEvent(new StatusSessionEvent(this, session));
 		return databaseDao.updateSession(session);
 	}
 
@@ -337,4 +338,9 @@ public class SessionService implements ISessionService {
 		}
 		return info;
 	}
+
+	@Override
+	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
+		this.publisher = publisher;
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/services/UserService.java b/src/main/java/de/thm/arsnova/services/UserService.java
index 6ea53980..ced1cd28 100644
--- a/src/main/java/de/thm/arsnova/services/UserService.java
+++ b/src/main/java/de/thm/arsnova/services/UserService.java
@@ -70,7 +70,6 @@ import de.thm.arsnova.entities.User;
 import de.thm.arsnova.exceptions.BadRequestException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.exceptions.UnauthorizedException;
-import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Service
 public class UserService implements IUserService {
@@ -93,9 +92,6 @@ public class UserService implements IUserService {
 	@Autowired
 	private IDatabaseDao databaseDao;
 
-	@Autowired
-	private ARSnovaSocketIOServer socketIoServer;
-
 	@Autowired
 	private JavaMailSender mailSender;
 
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocket.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocket.java
new file mode 100644
index 00000000..4d0351f4
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocket.java
@@ -0,0 +1,31 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.socket;
+
+/**
+ * This interface is used to auto-wire the Socket Server.
+ *
+ * Extend this interface as you see fit.
+ */
+public interface ARSnovaSocket {
+
+	boolean isUseSSL();
+
+	int getPortNumber();
+
+}
\ No newline at end of file
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
index 59eaa008..e68d9917 100644
--- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
@@ -32,7 +32,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Required;
-import org.springframework.context.ApplicationListener;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import com.corundumstudio.socketio.AckRequest;
@@ -53,13 +53,15 @@ import de.thm.arsnova.events.DeleteAllLectureAnswersEvent;
 import de.thm.arsnova.events.DeleteAllPreparationAnswersEvent;
 import de.thm.arsnova.events.DeleteAllQuestionsAnswersEvent;
 import de.thm.arsnova.events.DeleteAnswerEvent;
+import de.thm.arsnova.events.DeleteFeedbackForSessionsEvent;
 import de.thm.arsnova.events.DeleteInterposedQuestionEvent;
 import de.thm.arsnova.events.DeleteQuestionEvent;
 import de.thm.arsnova.events.NewAnswerEvent;
+import de.thm.arsnova.events.NewFeedbackEvent;
 import de.thm.arsnova.events.NewInterposedQuestionEvent;
 import de.thm.arsnova.events.NewQuestionEvent;
-import de.thm.arsnova.events.NovaEvent;
 import de.thm.arsnova.events.NovaEventVisitor;
+import de.thm.arsnova.events.StatusSessionEvent;
 import de.thm.arsnova.exceptions.UnauthorizedException;
 import de.thm.arsnova.exceptions.NoContentException;
 import de.thm.arsnova.exceptions.NotFoundException;
@@ -72,7 +74,7 @@ import de.thm.arsnova.socket.message.Question;
 import de.thm.arsnova.socket.message.Session;
 
 @Component
-public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, NovaEventVisitor {
+public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 	@Autowired
 	private IFeedbackService feedbackService;
@@ -253,6 +255,7 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No
 
 	}
 
+	@Override
 	public int getPortNumber() {
 		return portNumber;
 	}
@@ -288,6 +291,7 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No
 		this.keystore = keystore;
 	}
 
+	@Override
 	public boolean isUseSSL() {
 		return useSSL;
 	}
@@ -440,6 +444,7 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No
 		this.reportAudienceQuestionAvailable(event.getSession(), event.getQuestion());
 	}
 
+	@Async
 	@Override
 	public void visit(NewAnswerEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
@@ -458,6 +463,7 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No
 		}
 	}
 
+	@Async
 	@Override
 	public void visit(DeleteAnswerEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
@@ -498,7 +504,18 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No
 	}
 
 	@Override
-	public void onApplicationEvent(NovaEvent event) {
-		event.accept(this);
+	public void visit(NewFeedbackEvent event) {
+		this.reportUpdatedFeedbackForSession(event.getSession());
+	}
+
+	@Override
+	public void visit(DeleteFeedbackForSessionsEvent event) {
+		this.reportDeletedFeedback(event.getUser(), event.getSessions());
+
+	}
+
+	@Override
+	public void visit(StatusSessionEvent event) {
+		this.reportSessionStatus(event.getSession().getKeyword(), event.getSession().isActive());
 	}
 }
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketListener.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketListener.java
new file mode 100644
index 00000000..68cae59e
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketListener.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.socket;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+import de.thm.arsnova.events.NovaEvent;
+
+/**
+ * An external Listener is required because otherwise the event methods are not called through a Spring proxy.
+ * This would result in Spring method annotations not working.
+ */
+@Component
+public class ARSnovaSocketListener implements ApplicationListener<NovaEvent> {
+
+	@Autowired
+	private ARSnovaSocketIOServer socketServer;
+
+	@Override
+	public void onApplicationEvent(NovaEvent event) {
+		event.accept(socketServer);
+	}
+
+}
-- 
GitLab