import random

from gevent.pywsgi import WSGIServer
from gevent.queue import Queue
from geventsocketio.protocol import SocketIOProtocol
from geventsocketio.handler import SocketIOHandler


__all__ = ['SocketIOServer']

class SocketIOServer(WSGIServer):
    """A WSGI Server with a resource that acts like an SocketIO."""

    def __init__(self, *args, **kwargs):
        self.sessions = {}
        self.resource = kwargs.pop('resource')
        kwargs['handler_class'] = SocketIOHandler
        super(SocketIOServer, self).__init__(*args, **kwargs)

    def handle(self, socket, address):
        handler = self.handler_class(socket, address, self)
        self.set_environ({'socketio': SocketIOProtocol(handler)})
        handler.handle()

    def get_session(self, session_id=''):
        """Return an existing or new client Session."""

        session = self.sessions.get(session_id)

        if session is None:
            session = Session()
            self.sessions[session.session_id] = session
        else:
            session.incr_hits()

        return session


class Session(object):
    """
    Client session which checks the connection health and the queues for
    message passing.
    """

    def __init__(self):
        self.session_id = str(random.random())[2:]
        self.client_queue = Queue() # queue for messages to client
        self.server_queue = Queue() # queue for messages to server
        self.hits = 0
        self.hearbeats = 0
        self.connected = False

    def incr_hits(self):
        self.hits += 1

    def heartbeats(self):
        self.hearbeats += 1
        return self.hearbeats

    def valid_heartbeat(self, counter):
        return self.hearbeats == counter

    def is_new(self):
        return self.hits == 0

    def kill(self):
        if self.connected:
            self.connected = False
            self.server_queue.put_nowait(None)
            self.client_queue.put_nowait(None)
        else:
            pass # Fail silently

    def put_server_msg(self, msg):
        self.server_queue.put_nowait(msg)

    def put_client_msg(self, msg):
        self.client_queue.put_nowait(msg)

    def get_client_msg(self, **kwargs):
        return self.client_queue.get(**kwargs)

    def get_server_msg(self, **kwargs):
        return self.server_queue.get(**kwargs)

@@ -1,12 +1,23 @@
+import sys%0A
 import rando
@@ -17,16 +17,58 @@
 t random
+%0Aimport traceback%0Afrom socket import error
 %0A%0Afrom g
@@ -233,16 +233,74 @@
 Handler%0A
+from geventsocketio.policyserver import FlashPolicyServer%0A
 %0A%0A__all_
@@ -553,110 +553,857 @@
     
-kwargs%5B'handler_class'%5D = SocketIOHandler%0A        super(SocketIOServer, self).__init__(*args, **kwargs
+if kwargs.pop('policy_server', True):%0A            self.policy_server = FlashPolicyServer()%0A        else:%0A            self.policy_server = None%0A        kwargs%5B'handler_class'%5D = SocketIOHandler%0A        super(SocketIOServer, self).__init__(*args, **kwargs)%0A%0A    def start_accepting(self):%0A        if self.policy_server is not None:%0A            try:%0A                self.policy_server.start()%0A            except error, ex:%0A                sys.stderr.write('FAILED to start flash policy server: %25s%5Cn' %25 (ex, ))%0A            except Exception:%0A                traceback.print_exc()%0A                sys.stderr.write('FAILED to start flash policy server.%5Cn%5Cn')%0A        super(SocketIOServer, self).start_accepting()%0A%0A    def kill(self):%0A        if self.policy_server is not None:%0A            self.policy_server.kill()%0A        super(SocketIOServer, self).kill(
 )%0A%0A 

make SocketIOServer autostart FlashPolicyServer