         return socket.send(message)
     }
 
+    // MARK: - Presence
+
+    private func getPresenceMeta(entry: AnyObject) -> [String: AnyObject]? {
+        guard let metas = entry["metas"] as? [[String: AnyObject]] else {
+            return nil
+        }
+
+        return metas.first
+    }
+
+    private func presenceState(response: Response) {
+        response.payload.forEach { id, dict in
+            presence[id] = getPresenceMeta(dict)
+        }
+
+        presenceStateCallback?(presence)
+    }
+
+    private func presenceDiff(response: Response) {
+        if let leaves = response.payload["leaves"] as? [String: AnyObject] {
+            leaves.forEach { id, dict in
+                presence.removeValueForKey(id)
+            }
+        }
+
+        if let joins = response.payload["joins"] as? [String: AnyObject] {
+            joins.forEach { id, dict in
+                presence[id] = getPresenceMeta(dict)
+            }
+        }
+
+        presenceStateCallback?(presence)
+    }
+
     // MARK: - Raw events
 
     func received(response: Response) {

import Foundation

public class Channel {
    public let topic: String
    public let params: Socket.Payload
    private let socket: Socket
    private(set) public var state: State

    private var callbacks: [String: (Response) -> ()] = [:]

    init(socket: Socket, topic: String, params: Socket.Payload = [:]) {
        self.socket = socket
        self.topic = topic
        self.params = params
        self.state = .Closed
    }

    // MARK: - Control

        return self
    }

    public func onNewState(callback: Presence -> ()) -> Self {
        presenceStateCallback = callback
        return self
    }

    // MARK: - States

    public enum State: String {
