diff --git a/src/main/java/de/thm/arsnova/services/IUserService.java b/src/main/java/de/thm/arsnova/services/IUserService.java
index 4e94a08f74ac76e0c79f718622712be502efa29a..735815357b6cab781051a5c7da110ce0d9a65bc4 100644
--- a/src/main/java/de/thm/arsnova/services/IUserService.java
+++ b/src/main/java/de/thm/arsnova/services/IUserService.java
@@ -44,4 +44,8 @@ public interface IUserService {
 	void addCurrentUserToSessionMap(String keyword);
 
 	String getSessionForUser(String username);
+
+	void addUserToSessionBySocketId(UUID socketId, String keyword);
+
+	void removeUserFromSessionBySocketId(UUID socketId);
 }
diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java
index a568c205f769714702e9f81420de2c623842fd9f..52343f340ec87dcba53cfbc308487bc8eabc4426 100644
--- a/src/main/java/de/thm/arsnova/services/SessionService.java
+++ b/src/main/java/de/thm/arsnova/services/SessionService.java
@@ -38,6 +38,7 @@ import de.thm.arsnova.entities.LoggedIn;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.exceptions.ForbiddenException;
+import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Service
 public class SessionService implements ISessionService {
@@ -49,7 +50,10 @@ public class SessionService implements ISessionService {
 
 	@Autowired
 	private IUserService userService;
-	
+
+	@Autowired
+	private ARSnovaSocketIOServer socketIoServer;
+
 	@Autowired(required=false)
 	private ConnectorClient connectorClient;
 
@@ -61,15 +65,16 @@ public class SessionService implements ISessionService {
 	@Authenticated
 	public final Session joinSession(final String keyword) {
 		userService.addCurrentUserToSessionMap(keyword);
+		socketIoServer.reportActiveUserCountForSession(keyword);
+
 		Session session = databaseDao.getSession(keyword);
-		
 		if (connectorClient != null && session.isCourseSession()) {
 			String courseid = session.getCourseId();
 			if (!connectorClient.getMembership(userService.getCurrentUser().getUsername(), courseid).isMember()) {
 				throw new ForbiddenException();
 			}
 		}
-		
+
 		return session;
 	}
 
diff --git a/src/main/java/de/thm/arsnova/services/UserService.java b/src/main/java/de/thm/arsnova/services/UserService.java
index d4f2660af9ca648e05d15a58e818977c52321396..b2e0dcdb31b035c8d970632ee23ab55cefafe9d3 100644
--- a/src/main/java/de/thm/arsnova/services/UserService.java
+++ b/src/main/java/de/thm/arsnova/services/UserService.java
@@ -41,8 +41,13 @@ public class UserService implements IUserService, InitializingBean, DisposableBe
 	public static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
 
 	private static final ConcurrentHashMap<UUID, User> socketid2user = new ConcurrentHashMap<UUID, User>();
+
+	/* used for Socket.IO online check solution (new) */
 	private static final ConcurrentHashMap<User, String> user2session = new ConcurrentHashMap<User, String>();
 
+	/* used for HTTP polling online check solution (legacy) */
+	private static final ConcurrentHashMap<User, String> user2sessionLegacy = new ConcurrentHashMap<User, String>();
+
 	@Override
 	public User getCurrentUser() {
 		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
@@ -106,7 +111,7 @@ public class UserService implements IUserService, InitializingBean, DisposableBe
 	public boolean isUserInSession(User user, String keyword) {
 		if (keyword == null)
 			return false;
-		String session = user2session.get(user);
+		String session = user2sessionLegacy.get(user);
 		if (session == null)
 			return false;
 		return keyword.equals(session);
@@ -120,6 +125,12 @@ public class UserService implements IUserService, InitializingBean, DisposableBe
 				result.add(e.getKey());
 			}
 		}
+		for (Entry<User, String> e : user2sessionLegacy.entrySet()) {
+			if (e.getValue().equals(keyword)) {
+				result.add(e.getKey());
+			}
+		}
+
 		return result;
 	}
 
@@ -129,14 +140,37 @@ public class UserService implements IUserService, InitializingBean, DisposableBe
 		User user = getCurrentUser();
 		if (user == null)
 			throw new UnauthorizedException();
+		LOGGER.info("Mapping user " + user.getUsername() + " to session " + keyword + " [legacy].");
+		user2sessionLegacy.put(user, keyword);
+	}
+
+	@Override
+	@Transactional(isolation = Isolation.READ_COMMITTED)
+	public void addUserToSessionBySocketId(UUID socketId, String keyword) {
+		User user = socketid2user.get(socketId);
+		LOGGER.info("Mapping user " + user.getUsername() + " to session " + keyword + ".");
 		user2session.put(user, keyword);
 	}
 
+	@Override
+	@Transactional(isolation = Isolation.READ_COMMITTED)
+	public void removeUserFromSessionBySocketId(UUID socketId) {
+		user2session.remove(socketId);
+	}
+
 	@Override
 	public String getSessionForUser(String username) {
 		for (Entry<User, String> entry  : user2session.entrySet()) {
-			if (entry.getKey().getUsername().equals(username)) return entry.getValue();
+			if (entry.getKey().getUsername().equals(username)) {
+				return entry.getValue();
+			}
+		}
+		for (Entry<User, String> entry  : user2sessionLegacy.entrySet()) {
+			if (entry.getKey().getUsername().equals(username)) {
+				return entry.getValue();
+			}
 		}
+
 		return null;
 	}
 	
@@ -157,7 +191,7 @@ public class UserService implements IUserService, InitializingBean, DisposableBe
 			LOGGER.info("load from store: {}", map);
 
 			socketid2user.putAll(s2u);
-			user2session.putAll(u2s);
+			user2sessionLegacy.putAll(u2s);
 
 		} catch (IOException e) {
 			LOGGER.error("IOException during restoring UserService", e);
@@ -170,7 +204,7 @@ public class UserService implements IUserService, InitializingBean, DisposableBe
 	public void destroy() {
 		Hashtable<String, Map<?, ?>> map = new Hashtable<String, Map<?, ?>>();
 		map.put("socketid2user", socketid2user);
-		map.put("user2session", user2session);
+		map.put("user2session", user2sessionLegacy);
 
 		try {
 			File tmpDir = new File(System.getProperty("java.io.tmpdir"));
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
index 6c8ad2c9c36973e53bb84efe75c0dd519888e985..9ce63e7fe3568f80417b3307ec483663fe420afc 100644
--- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
@@ -26,8 +26,10 @@ import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.services.IFeedbackService;
 import de.thm.arsnova.services.IQuestionService;
+import de.thm.arsnova.services.ISessionService;
 import de.thm.arsnova.services.IUserService;
 import de.thm.arsnova.socket.message.Feedback;
+import de.thm.arsnova.socket.message.Session;
 
 public class ARSnovaSocketIOServer {
 
@@ -40,6 +42,9 @@ public class ARSnovaSocketIOServer {
 	@Autowired
 	private IUserService userService;
 
+	@Autowired
+	private ISessionService sessionService;
+
 	private final Logger logger = LoggerFactory.getLogger(getClass());
 
 	private int portNumber;
@@ -49,6 +54,8 @@ public class ARSnovaSocketIOServer {
 	private String storepass;
 	private final Configuration config;
 	private SocketIOServer server;
+	
+	private int lastActiveUserCount = 0;
 
 	public ARSnovaSocketIOServer() {
 		config = new Configuration();
@@ -93,6 +100,15 @@ public class ARSnovaSocketIOServer {
 			}
 		});
 
+		server.addEventListener("setSession", Session.class, new DataListener<Session>() {
+			@Override
+			public void onData(SocketIOClient client, Session session, AckRequest ackSender) {
+				userService.addUserToSessionBySocketId(client.getSessionId(), session.getKeyword());
+				reportActiveUserCountForSession(session.getKeyword());
+				reportSessionDataToClient(session.getKeyword(), client);
+			}
+		});
+
 		server.addEventListener("arsnova/question/create", Question.class, new DataListener<Question>() {
 			@Override
 			public void onData(SocketIOClient client, Question question, AckRequest ackSender) {
@@ -111,6 +127,11 @@ public class ARSnovaSocketIOServer {
 			@Override
 			public void onDisconnect(SocketIOClient client) {
 				logger.info("addDisconnectListener.onDisconnect: Client: {}", new Object[] { client });
+				String sessionKey = userService.getSessionForUser(
+					userService.getUser2SocketId(client.getSessionId()).getUsername()
+				);
+				reportActiveUserCountForSession(sessionKey);
+				userService.removeUserFromSessionBySocketId(client.getSessionId());
 				userService.removeUser2SocketId(client.getSessionId());
 			}
 		});
@@ -196,21 +217,51 @@ public class ARSnovaSocketIOServer {
 		return result;
 	}
 
-	public void reportUpdatedFeedbackForSession(String session) {
+	/**
+	 * Currently only sends the feedback data to the client. Should be used for all
+	 * relevant Socket.IO data, the client needs to know after joining a session.
+	 *
+	 * @param sessionKey
+	 * @param client
+	 */
+	public void reportSessionDataToClient(String sessionKey, SocketIOClient client) {
+		de.thm.arsnova.entities.Feedback fb = feedbackService.getFeedback(sessionKey);
+		client.sendEvent("updateFeedback", fb.getValues());
+
+		/* updateActiveUserCount does not need to be send since it is broadcasted
+		 * after the client joined the session */
+	}
+
+	public void reportUpdatedFeedbackForSession(String sessionKey) {
+		de.thm.arsnova.entities.Feedback fb = feedbackService.getFeedback(sessionKey);
+		broadcastInSession(sessionKey, "updateFeedback", fb.getValues());
+	}
+
+	public void reportActiveUserCountForSession(String sessionKey) {
+		int count = sessionService.countActiveUsers(sessionKey);
+		if (count == lastActiveUserCount) {
+			return;
+		}
+		lastActiveUserCount = count;
+		broadcastInSession(sessionKey, "updateActiveUserCount", count);
+	}
+
+	public void broadcastInSession(String sessionKey, String eventName, Object data) {
+		logger.info("Broadcasting " + eventName + " for session " + sessionKey + ".");
+
 		/**
 		 * collect a list of users which are in the current session iterate over
 		 * all connected clients and if send feedback, if user is in current
 		 * session
 		 */
-		List<User> users = userService.getUsersInSession(session);
-		de.thm.arsnova.entities.Feedback fb = feedbackService.getFeedback(session);
+		List<User> users = userService.getUsersInSession(sessionKey);
 
 		for (SocketIOClient c : server.getAllClients()) {
 			User u = userService.getUser2SocketId(c.getSessionId());
 			if (u != null && users.contains(u)) {
 				logger.info("sending out to client {}, username is: {}, current session is: {}",
-						new Object[] { c.getSessionId(), u.getUsername(), session });
-				c.sendEvent("updateFeedback", fb.getValues());
+						new Object[] { c.getSessionId(), u.getUsername(), sessionKey });
+				c.sendEvent(eventName, data);
 			}
 		}
 	}
diff --git a/src/main/java/de/thm/arsnova/socket/message/Session.java b/src/main/java/de/thm/arsnova/socket/message/Session.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b56fe50c035f2c77d19c9d8db581755e249fc01
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/socket/message/Session.java
@@ -0,0 +1,13 @@
+package de.thm.arsnova.socket.message;
+
+public class Session {
+	private String keyword;
+
+	public String getKeyword() {
+		return keyword;
+	}
+
+	public void setKeyword(String keyword) {
+		this.keyword = keyword;
+	}
+}