Пример #1
0
def websocket():
    print('im in ws')
    env = request.environ
    uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
    r = redis.StrictRedis(host='localhost', port=6379, db=0)
    channel = r.pubsub()
    channel.subscribe('teste_ws')
    websocket_fd = uwsgi.connection_fd()
    redis_fd = channel.connection._sock.fileno()
    while True:
        print("here in the loop")
        # wait max 4 seconds to allow ping to be sent
        ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
        # send ping on timeout
        if not ready[0]:
            uwsgi.websocket_recv_nb()
        for fd in ready[0]:
            if fd == websocket_fd:
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    r.publish('teste_ws', msg)
            elif fd == redis_fd:
                msg = channel.parse_response()
                # only interested in user messages
                if msg[0] == b'message':
                    uwsgi.websocket_send(msg[2])
Пример #2
0
    def __call__(self, environ, start_response):
        uwsgi.websocket_handshake(environ['HTTP_SEC_WEBSOCKET_KEY'], environ.get('HTTP_ORIGIN', ''))
        self.r = redis.StrictRedis(host=self.redis_host, port=self.redis_port, db=0)
        channel = self.r.pubsub()
        channel.subscribe(self.room)

        websocket_fd = uwsgi.connection_fd()
        redis_fd = channel.connection._sock.fileno()

        core_id = environ['uwsgi.core']
        self.setup(core_id)

        while True:
            ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
            if not ready[0]:
                uwsgi.websocket_recv_nb()
            for fd in ready[0]:
                if fd == websocket_fd:
                    try:
                        msg = uwsgi.websocket_recv_nb()
                    except IOError:
                        self.end(core_id)
                        return ""
                    if msg:
                        self.websocket(core_id, msg)
                elif fd == redis_fd:
                    msg = channel.parse_response()
                    if msg[0] == 'message':
                        uwsgi.websocket_send(msg[2])
Пример #3
0
 def serve_handler(self, handler, values):
     def invoke_handler(handler, sock):
         try:
             handler(sock, **values)
         finally:
             sock.close()
     th = Thread(target=invoke_handler, args=(handler, self,))
     th.setDaemon(True)
     th.start()
     try:
         fd = uwsgi.connection_fd()
         while not self.evt_close.is_set():
             uwsgi.wait_fd_read(fd, 0.3)
             uwsgi.suspend()
             _fd = uwsgi.ready_fd()
             msg = uwsgi.websocket.recv_nb()
             if msg:
                 self.q_recv.put(msg)
             try:
                 msg = self.q.get(True, 0.1)
                 if msg:
                     uwsgi.websocket_send(msg)
             except Empty:
                 pass
     finally:
         self.close()
         th.join()
     return []
Пример #4
0
    def get_request_socket(self, env):
        if not self.ca:
            return None

        sock = None

        if env.get('uwsgi.version'):  # pragma: no cover
            try:
                import uwsgi
                fd = uwsgi.connection_fd()
                conn = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
                try:
                    sock = socket.socket(_sock=conn)
                except:
                    sock = conn
            except Exception as e:
                pass
        elif env.get('gunicorn.socket'):  # pragma: no cover
            sock = env['gunicorn.socket']

        if not sock:
            # attempt to find socket from wsgi.input
            input_ = env.get('wsgi.input')
            if input_:
                if hasattr(input_, '_sock'):  # pragma: no cover
                    raw = input_._sock
                    sock = socket.socket(_sock=raw)  # pragma: no cover
                elif hasattr(input_, 'raw'):
                    sock = input_.raw._sock

        return sock
Пример #5
0
 def get_file_descriptor(self):
     """Return the file descriptor for the given websocket"""
     try:
         return uwsgi.connection_fd()
     except IOError, e:
         self.close()
         raise WebSocketError(e)
Пример #6
0
 def __init__(self, environ, start_response, application):
     self.environ = environ
     self.socket = socket.fromfd(uwsgi.connection_fd(), socket.AF_INET, socket.SOCK_STREAM)
     self.rfile = makefile(self.socket)
     self.application = application
     self.start_response = start_response
     self.request_version = environ['SERVER_PROTOCOL']
Пример #7
0
    def get_raw_socket(cls, env):  #pragma: no cover
        sock = None

        if env.get('uwsgi.version'):
            try:
                import uwsgi
                fd = uwsgi.connection_fd()
                sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
            except Exception as e:
                pass
        elif env.get('gunicorn.socket'):
            sock = env['gunicorn.socket']

        if not sock:
            # attempt to find socket from wsgi.input
            input_ = env.get('wsgi.input')
            if input_:
                if hasattr(input_, '_sock'):
                    raw = input_._sock
                    sock = socket.socket(_sock=raw)
                elif hasattr(input_, 'raw'):
                    sock = input_.raw._sock
                elif hasattr(input_, 'rfile'):
                    # PY3
                    if hasattr(input_.rfile, 'raw'):
                        sock = input_.rfile.raw._sock
                    # PY2
                    else:
                        sock = input_.rfile._sock

        return sock
Пример #8
0
    def __call__(self, environ, start_response):
        self._sock = uwsgi.connection_fd()
        self.environ = environ

        uwsgi.websocket_handshake()

        self._req_ctx = None
        if hasattr(uwsgi, 'request_context'):
            # uWSGI >= 2.1.x with support for api access across-greenlets
            self._req_ctx = uwsgi.request_context()
        else:
            # use event and queue for sending messages
            from gevent.event import Event
            from gevent.queue import Queue
            from gevent.select import select
            self._event = Event()
            self._send_queue = Queue()

            # spawn a select greenlet
            def select_greenlet_runner(fd, event):
                """Sets event when data becomes available to read on fd."""
                while True:
                    event.set()
                    try:
                        select([fd], [], [])[0]
                    except ValueError:
                        break
            self._select_greenlet = gevent.spawn(
                select_greenlet_runner,
                self._sock,
                self._event)

        self.app(self)
Пример #9
0
def chat(request):
    try:
        room = Room.objects.get(pk=1)
    except:
        room = None

    uwsgi.websocket_handshake(request['HTTP_SEC_WEBSOCKET_KEY'],
                              request.get('HTTP_ORIGIN', ''))
    r = redis.StrictRedis(host='localhost', port=6379, db=0)
    channel = r.pubsub()
    channel.subscribe(room.name)
    websocket_fd = uwsgi.connection_fd()
    redis_fd = channel.connection._sock.fileno()
    while True:
        ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
        if not ready[0]:
            uwsgi.websocket_recv_nb()
        for fd in ready[0]:
            if fd == websocket_fd:
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    msg = json.loads(msg)
                    if msg['c'] == 'm':
                        first_msg = "%s: %s" % (msg['u'], msg['ms'])
                        second_msg = None
                        if first_msg and not second_msg:
                            r.publish(room.name, first_msg)
                        elif second_msg and first_msg:
                            r.publish(room.name,
                                      "%s <br> %s" % (first_msg, second_msg))
            elif fd == redis_fd:
                msg = channel.parse_response()
                if msg[0] == 'message':
                    uwsgi.websocket_send("[%s] %s" % (time.time(), msg[2]))
Пример #10
0
    def get_request_socket(self, env):
        if not self.ca:
            return None

        sock = None

        if env.get('uwsgi.version'):  # pragma: no cover
            try:
                import uwsgi
                fd = uwsgi.connection_fd()
                conn = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
                try:
                    sock = socket.socket(_sock=conn)
                except:
                    sock = conn
            except Exception as e:
                pass
        elif env.get('gunicorn.socket'):  # pragma: no cover
            sock = env['gunicorn.socket']

        if not sock:
            # attempt to find socket from wsgi.input
            input_ = env.get('wsgi.input')
            if input_:
                if hasattr(input_, '_sock'):  # pragma: no cover
                    raw = input_._sock
                    sock = socket.socket(_sock=raw)  # pragma: no cover
                elif hasattr(input_, 'raw'):
                    sock = input_.raw._sock

        return sock
 def get_file_descriptor(self):
     """Return the file descriptor for the given websocket"""
     try:
         return uwsgi.connection_fd()
     except IOError as e:
         self.close()
         raise WebSocketError(e)
Пример #12
0
    def __call__(self, environ, start_response):
        uwsgi.websocket_handshake(environ['HTTP_SEC_WEBSOCKET_KEY'],
                                  environ.get('HTTP_ORIGIN', ''))
        print "websockets..."
        self.r = redis.StrictRedis(host=self.redis_host,
                                   port=self.redis_port,
                                   db=0)
        channel = self.r.pubsub()
        channel.subscribe(self.room)

        websocket_fd = uwsgi.connection_fd()
        redis_fd = channel.connection._sock.fileno()

        core_id = environ['uwsgi.core']
        self.setup(core_id)

        while True:
            ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
            if not ready[0]:
                uwsgi.websocket_recv_nb()
            for fd in ready[0]:
                if fd == websocket_fd:
                    try:
                        msg = uwsgi.websocket_recv_nb()
                    except IOError:
                        self.end(core_id)
                        return ""
                    if msg:
                        self.websocket(core_id, msg)
                elif fd == redis_fd:
                    msg = channel.parse_response()
                    if msg[0] == 'message':
                        uwsgi.websocket_send(msg[2])
    def __call__(self, environ, start_response):
        self._sock = uwsgi.connection_fd()
        self.environ = environ

        uwsgi.websocket_handshake()

        self._req_ctx = None
        if hasattr(uwsgi, 'request_context'):
            # uWSGI >= 2.1.x with support for api access across-greenlets
            self._req_ctx = uwsgi.request_context()
        else:
            # use event and queue for sending messages
            self._event = Event()
            self._send_queue = queue.Queue()

            # spawn a select greenlet
            def select_greenlet_runner(fd, event):
                """Sets event when data becomes available to read on fd."""
                sel = selectors.DefaultSelector()
                sel.register(fd, selectors.EVENT_READ)
                try:
                    while True:
                        sel.select()
                        event.set()
                except gevent.GreenletExit:
                    sel.unregister(fd)
            self._select_greenlet = gevent.spawn(
                select_greenlet_runner,
                self._sock,
                self._event)

        self.app(self)
Пример #14
0
def application(env, start_response):
    # complete the handshake
    uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))

    r = redis.StrictRedis(host='redis-gandamu', port=6379, db=0)
    channel = r.pubsub()
    channel.subscribe('portfolio')
    websocket_fd = uwsgi.connection_fd()
    redis_fd = channel.connection._sock.fileno()

    while True:
        uwsgi.wait_fd_read(websocket_fd, 3)
        uwsgi.wait_fd_read(redis_fd)
        uwsgi.suspend()
        fd = uwsgi.ready_fd()
        if fd > -1:
            if fd == websocket_fd:
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    r.publish('portfolio', msg)
            elif fd == redis_fd:
                msg = channel.parse_response()
                # only interested in user messages
                t = 'message'
                if sys.version_info[0] > 2:
                    t = b'message'
                if msg[0] == t:
                    json = msg[2].decode('utf-8')
                    uwsgi.websocket_send("%s" % json)
                    # uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
        else:
            # on timeout call websocket_recv_nb again to manage ping/pong
            msg = uwsgi.websocket_recv_nb()
            if msg:
                r.publish('portfolio', msg)
Пример #15
0
    def __call__(self, environ, start_response):
        self.environ = environ

        uwsgi.websocket_handshake()

        self._req_ctx = None
        if hasattr(uwsgi, 'request_context'):
            # uWSGI >= 2.1.x with support for api access across-greenlets
            self._req_ctx = uwsgi.request_context()
        else:
            # use event and queue for sending messages
            from gevent.event import Event
            from gevent.queue import Queue
            from gevent.select import select
            self._event = Event()
            self._send_queue = Queue()

            # spawn a select greenlet
            def select_greenlet_runner(fd, event):
                """Sets event when data becomes available to read on fd."""
                while True:
                    event.set()
                    select([fd], [], [])[0]
            self._select_greenlet = gevent.spawn(
                select_greenlet_runner,
                uwsgi.connection_fd(),
                self._event)

        return self.app(self)
Пример #16
0
def chat(request):
    try:
        room = Room.objects.get(pk=1)
    except:
        room = None

    uwsgi.websocket_handshake(request['HTTP_SEC_WEBSOCKET_KEY'], request.get('HTTP_ORIGIN', ''))
    r = redis.StrictRedis(host='localhost', port=6379, db=0)
    channel = r.pubsub()
    channel.subscribe(room.name)
    websocket_fd = uwsgi.connection_fd()
    redis_fd = channel.connection._sock.fileno()
    while True:
        ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
        if not ready[0]:
            uwsgi.websocket_recv_nb()
        for fd in ready[0]:
            if fd == websocket_fd:
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    msg = json.loads(msg)
                    if msg['c'] == 'm':
                        first_msg = "%s: %s" % (msg['u'], msg['ms'])
                        second_msg = None
                        if first_msg and not second_msg:
                            r.publish(room.name, first_msg)
                        elif second_msg and first_msg:
                            r.publish(room.name, "%s <br> %s" % (first_msg, second_msg))
            elif fd == redis_fd:
                msg = channel.parse_response() 
                if msg[0] == 'message':
                    uwsgi.websocket_send("[%s] %s" % (time.time(), msg[2]))
Пример #17
0
    def __init__(self, env, startresponse):

        if env['PATH_INFO'] == '/':
            print('in init method')
            uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                      env.get('HTTP_ORIGIN', ''))
            r = redis.StrictRedis(host='localhost', port=6379, db=0)
            channel = r.pubsub()
            channel.subscribe('websocket')
            websocket_fd = uwsgi.connection_fd()
            redis_fd = channel.connection._sock.fileno()

            while True:
                # wait max 4 seconds to allow ping to be sent
                ready = gevent.select.select([websocket_fd, redis_fd], [], [],
                                             4.0)
                # send ping on timeout
                if not ready[0]:
                    uwsgi.websocket_recv_nb()

                for fd in ready[0]:
                    if fd == websocket_fd:
                        # receiving
                        msg = uwsgi.websocket_recv_nb()
                        if msg:
                            # getting message from browser, publishing to redis
                            # receive, sending back answer
                            print('websocket_fd', msg)
                            r.publish('websocket', msg)
                    elif fd == redis_fd:
                        msg = channel.parse_response()
                        # self.send_to_client(msg)
                        if msg[0].decode() == 'message':
                            self.send_pong(msg[2].decode())
def application(env, start_response):
    '''https://github.com/unbit/uwsgi/blob/master/tests/websockets_chat.py'''
    uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
    print 'websocket relay connecting...'
    r = redis.StrictRedis(host='redis', port=6379, db=0)
    channel = r.pubsub()
    channel.subscribe('broadcast')

    websocket_fd = uwsgi.connection_fd()
    redis_fd = channel.connection._sock.fileno()

    while True:
        # wait max 4 seconds to allow ping to be sent
        ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
        # send ping on timeout
        if not ready[0]:
            uwsgi.websocket_recv_nb()
        for fd in ready[0]:
            if fd == websocket_fd:
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    r.publish('incoming', msg)
            elif fd == redis_fd:
                msg = channel.parse_response()
                # only interested in user messages
                if msg[0] == 'message':
                    uwsgi.websocket_send(msg[-1])
Пример #19
0
        def websocket_view(context, request):
            uwsgi.websocket_handshake()
            this = greenlet.getcurrent()
            this.has_message = False
            q_in = asyncio.Queue()
            q_out = asyncio.Queue()

            # make socket proxy
            if inspect.isclass(view):
                view_callable = view(context, request)
            else:
                view_callable = view
            ws = UWSGIWebsocket(this, q_in, q_out)

            # start monitoring websocket events
            asyncio.get_event_loop().add_reader(
                uwsgi.connection_fd(),
                uwsgi_recv_msg,
                this
            )

            # NOTE: don't use synchronize because we aren't waiting
            # for this future, instead we are using the reader to return
            # to the child greenlet.

            future = asyncio.Future()
            asyncio.async(
                run_in_greenlet(this, future, view_callable, ws)
            )

            # switch to open
            this.parent.switch()

            while True:
                if future.done():
                    if future.exception() is not None:
                        raise future.exception()
                    raise WebsocketClosed

                # message in
                if this.has_message:
                    this.has_message = False
                    try:
                        msg = uwsgi.websocket_recv_nb()
                    except OSError:
                        msg = None

                    if msg or msg is None:
                        q_in.put_nowait(msg)

                # message out
                if not q_out.empty():
                    msg = q_out.get_nowait()
                    try:
                        uwsgi.websocket_send(msg)
                    except OSError:
                        q_in.put_nowait(None)

                this.parent.switch()
Пример #20
0
        def websocket_view(context, request):
            uwsgi.websocket_handshake()
            this = greenlet.getcurrent()
            this.has_message = False
            q_in = asyncio.Queue()
            q_out = asyncio.Queue()

            # make socket proxy
            if inspect.isclass(view):
                view_callable = view(context, request)
            else:
                view_callable = view
            ws = UWSGIWebsocket(this, q_in, q_out)

            # start monitoring websocket events
            asyncio.get_event_loop().add_reader(uwsgi.connection_fd(),
                                                uwsgi_recv_msg, this)

            # NOTE: don't use synchronize because we aren't waiting
            # for this future, instead we are using the reader to return
            # to the child greenlet.

            future = asyncio.Future()
            asyncio. async (run_in_greenlet(this, future, view_callable, ws))

            # switch to open
            this.parent.switch()

            while True:
                if future.done():
                    if future.exception() is not None:
                        raise WebsocketClosed from future.exception()
                    raise WebsocketClosed

                # message in
                if this.has_message:
                    this.has_message = False
                    try:
                        msg = uwsgi.websocket_recv_nb()
                    except OSError:
                        msg = None

                    if UWSGIWebsocketMapper.use_str:
                        with suppress(Exception):
                            print('howdy')
                            msg = bytes.decode(msg)

                    if msg or msg is None:
                        q_in.put_nowait(msg)

                # message out
                if not q_out.empty():
                    msg = q_out.get_nowait()
                    try:
                        uwsgi.websocket_send(msg)
                    except OSError:
                        q_in.put_nowait(None)

                this.parent.switch()
Пример #21
0
def request_id():
    """
    uwsgi.request_id is broken on async mode

    This function, used along with request_id_inc return a unique request id in current worker.
    """
    fd = uwsgi.connection_fd()
    return fd * uwsgi.opt.get("async-cores", 64) + _fd_count[fd]
Пример #22
0
 def __init__(self, environ, start_response, application):
     self.environ = environ
     self.socket = socket.fromfd(uwsgi.connection_fd(), socket.AF_INET,
                                 socket.SOCK_STREAM)
     self.rfile = makefile(self.socket)
     self.application = application
     self.start_response = start_response
     self.request_version = environ['SERVER_PROTOCOL']
Пример #23
0
def application(e, sr):
    if e['PATH_INFO'] == '/phys':
        uwsgi.websocket_handshake()

        w = World()
        me = Box('box0', w, 1000, 250, -1000, 250, 0)
        box1 = Box('box1', w, 20, 50, -1000, 250, 0)
        box2 = Box('box2', w, 20, 50, -1500, 350, 0)
        box3 = Box('box3', w, 20, 50, -1500, 450, 0)
        box4 = Box('box4', w, 200, 150, -1500, 550, 0)

        ramp = Ramp('ramp0', w, 400, 0, 100, 7000, 10, 400)

        print "BOX DRAWING COMPLETE"

        gevent.spawn(physic_engine, w)
        ufd = uwsgi.connection_fd()
        while True:

            ready = gevent.select.select([ufd, w.redis_fd], [], [], timeout=4.0)

            if not ready[0]:
                uwsgi.websocket_recv_nb()

            for fd in ready[0]:
                if fd == ufd:
                    try:
                        msg = uwsgi.websocket_recv_nb()
                        if msg == 'fw':
                            orientation = me.body.getOrientation()
                            v = Vector3(0, 0, 5000).rotate(orientation.getAxis(), orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyCentralImpulse( v )
                        elif msg == 'bw':
                            orientation = me.body.getOrientation()
                            v = Vector3(0, 0, -5000).rotate(orientation.getAxis(), orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyCentralImpulse( v )
                        elif msg == 'rl':
			    orientation = me.body.getOrientation()
                            v = Vector3(0, 2000000, 0).rotate(orientation.getAxis(), orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyTorqueImpulse( v )
                        elif msg == 'rr':
			    orientation = me.body.getOrientation()
                            v = Vector3(0, -2000000, 0).rotate(orientation.getAxis(), orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyTorqueImpulse( v )
                            #me.body.applyForce( Vector3(0, 0, 10000), Vector3(-200, 0, 0))
                            #me.body.applyForce( Vector3(0, 0, -10000), Vector3(200, 0, 0))
                    except IOError:
                        import sys
                        print sys.exc_info()
                        return [""]
                elif fd == w.redis_fd:
                    msg = w.channel.parse_response()
                    if msg[0] == 'message':
                        uwsgi.websocket_send(msg[2])
Пример #24
0
 def __init__(self, ws, channel, fawn):
     if uwsgi is None:
         abort(412)
     self.websocket_fd = uwsgi.connection_fd()
     self.fawn = fawn
     self.ws = ws
     self.handle_connection(fawn.connection_factory, fawn.channels)
     self.db_fd = os.dup(self.connection.fileno())
     self.channel = channel
Пример #25
0
def request_id_inc():
    """
    uwsgi.request_id is broken on async mode

    This function, called on every request, ensures that ours request_id return value is unique for
    current worker.
    """
    fd = uwsgi.connection_fd()
    count = _fd_count.get(fd, -1) + 1
    _fd_count[fd] = count % uwsgi.opt.get("async-cores", 64)
Пример #26
0
    def application(self, request):
        if 'HTTP_SEC_WEBSOCKET_KEY' not in request.environ:
            return JSONResponse(self.http_error, status=status.HTTP_400_BAD_REQUEST)

        uwsgi.websocket_handshake(request.environ['HTTP_SEC_WEBSOCKET_KEY'], request.environ.get('HTTP_ORIGIN', ''))

        # setup events
        send_event = Event()
        send_queue = Queue()

        recv_event = Event()
        recv_queue = Queue()

        client = self.client(request, uwsgi.connection_fd(), send_event,
                             send_queue, recv_event, recv_queue)

        # spawn handler
        handler = gevent.spawn(self.ws_handler, request, client)

        # spawn recv listener
        listener = gevent.spawn(self.listener_func, client, recv_event)

        while True:
            if not client.connected:
                recv_queue.put(None)

                if listener is not None:
                    listener.kill()

                handler.join(client.timeout)

                return ''

            # wait for event to draw our attention
            gevent.wait([handler, send_event, recv_event], None, 1)

            # handle receive events
            if recv_event.is_set():
                listener = self.handle_recv_event(client, recv_event, recv_queue)

            # handle send events
            elif send_event.is_set():
                self.handle_send_event(client, send_event, send_queue)

            # handler done, we're outta here
            elif handler.ready():
                listener.kill()

                return ''
Пример #27
0
    def GET(self):
        env = web.ctx.env
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                  env.get('HTTP_ORIGIN', ''))
        websocket_fd = uwsgi.connection_fd()
        inputs = [websocket_fd]

        while True:
            readable, _, _ = select.select(inputs, [], [], 1.0)

            for fid in readable:
                if fid == websocket_fd:
                    data = uwsgi.websocket_recv_nb()
                    now = datetime.datetime.now()
                    print("{0}: Received ws message: '{1}'".format(now, data))
Пример #28
0
 def recv(server, sock):
     while not sock.evt_open.is_set():
         time.sleep(0.05)
     if hasattr(server, 'on_open'):
         server.on_open(self)
     try:
         fd = uwsgi.connection_fd()
         while not sock.evt_close.is_set():
             uwsgi.wait_fd_read(fd, 1.0)
             uwsgi.suspend()
             _fd = uwsgi.ready_fd()
             msg = uwsgi.websocket_recv_nb()
             if msg:
                 frame = (1, OP_TEXT, msg)
                 server.on_message(sock, frame)
     finally:
         sock.evt_close.set()
Пример #29
0
def app(environ, start_response):
    match = re.match('/(?P<job_id>.+)/', environ['PATH_INFO'])
    if not match:
        start_response('404', [('Content-Type', 'text/plain')])
    job_id = match.group('job_id')

    uwsgi.websocket_handshake(environ['HTTP_SEC_WEBSOCKET_KEY'],
                              environ.get('HTTP_ORIGIN', ''))

    # Emit the backlog of messages
    lines = redis.lrange(job_id, 0, -1)
    send_message('message', ''.join(lines))

    channel = redis.pubsub()
    channel.subscribe(job_id)
    channel_socket_fd = channel.connection._sock.fileno()
    websocket_fd = uwsgi.connection_fd()

    while True:
        rlist, _, _ = gevent.select.select([channel_socket_fd, websocket_fd],
                                           [], [], 5.0)
        if rlist:
            for fd in rlist:
                if fd == channel_socket_fd:
                    message = channel.parse_response()
                    # See http://redis.io/topics/pubsub for format of `message`
                    if message[0] == 'message':
                        send_message('message', message[2])
                elif fd == websocket_fd:
                    # Let uwsgi do it's job to receive pong and send ping
                    uwsgi.websocket_recv_nb()
        else:
            # Have not heard from the channel and the client in 5 seconds...
            try:
                # Check if the client is still here by sending ping
                # (`websocket_recv` sends ping implicitly,
                # `websocket_recv_nb` -- non-blocking variant of it)
                uwsgi.websocket_recv_nb()
            except IOError:
                break
            # Check if the job is still ongoing
            if not redis.exists(job_id):
                send_message('status', 'finished')
                break
    return ''
Пример #30
0
    def start(self):
        self.init_context()
        if self.context['access_level'] < self.channel.min_access_level:
            raise ClientError('Insufficient privileges.')

        uwsgi.websocket_handshake()
        self.websocket_fd = uwsgi.connection_fd()
        logger.info(f'<Client {self.id}> Opening websocket connection')

        client_count = self.redis.get('websocket-clients')
        if client_count:
            client_count = int(client_count.decode('utf-8'))
            if client_count >= config.websockets_max_clients:
                raise ClientError('No available slots.')
        self.redis.incr('websocket-clients')
        self.state = ClientState.started

        self.fd_select_job = gevent.spawn(self._fd_select)
        self.spawn_jobs()
        self.main_loop()
Пример #31
0
def application(e, sr):
    if e['PATH_INFO'] == '/phys':
        uwsgi.websocket_handshake()

        w = World()
        me = Box('box0', w, 900, 200)
        me.set_pos(0, 1150, 0)
        box1 = Box('box1', w, 20, 50)
        box1.set_pos(0, 250, 0)
        box2 = Box('box2', w, 20, 50)
        box2.set_pos(0, 350, 0)
        box3 = Box('box3', w, 20, 50)
        box3.set_pos(0, 450, 0)
        box4 = Box('box4', w, 200, 150)
        box4.set_pos(0, 550, 0)


        gevent.spawn(physic_engine, w)
        ufd = uwsgi.connection_fd()
        while True:

            ready = gevent.select.select([ufd, w.redis_fd], [], [], timeout=4.0)

            if not ready[0]:
                uwsgi.websocket_recv_nb()

            for fd in ready[0]:
                if fd == ufd:
                    try:
                        msg = uwsgi.websocket_recv_nb()
                        if msg == 'fw':
                            me.body.addForce((0, 250, 0))
                    except IOError:
                        import sys
                        print sys.exc_info()
                        return [""]
                elif fd == w.redis_fd:
                    msg = w.channel.parse_response()
                    if msg[0] == 'message':
                        uwsgi.websocket_send(msg[2])
def _start_websocket():
    """
    This is the most important piece of the code. It's the only one that is allowed to use the uwsgi websocket api.
    It deals with receiving:
    - spawn a _listen greenlet
    _ when notified that the websocket fd is ready, it will fetch the message, and push it to the right handler
    and writing:
    - spawns a handler whenever necessary
    - when notified that a handler wants to writes, does the writing
    :return:
    """
    assert request.headers.get('Upgrade') == "websocket", "/websockets is only available for websocket protocol"
    assert uwsgi is not None, "You must run your app using uwsgi if you want to use the /websockets route"
    env = request.headers.environ
    uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))  # engage in websocket

    _websocket_handlers['_websocket_listen'] = spawn(_listen, uwsgi.connection_fd())  # Spawn greenlet that will listen to fd

    while True:
        ready = wait([_websocket_send_event, _websocket_recv_event], None, 1)  # wait for events
        if ready:  # an event was set
            if ready[0] == _websocket_recv_event:
                try:
                    msg = uwsgi.websocket_recv_nb()
                except IOError:
                    _kill_all()
                    return
                if msg:
                    json_msg = json.loads(msg)
                    handler = _websocket_handlers[json_msg['namespace']]
                    handler.go(json_msg)
                _websocket_recv_event.clear()
            elif ready[0] == _websocket_send_event:  # One or more handlers requested a message to be sent
                while True:
                    try:
                        msg = _websocket_send_queue.get_nowait()
                    except Empty:
                        break
                    uwsgi.websocket_send(json.dumps(msg))
                _websocket_send_event.clear()
Пример #33
0
def application(env, start_response):
    parse = parse_qs(env['QUERY_STRING'])
    if 'uid' not in parse:
        print('Connection error: uid not found')
        return ''
    uid = parse['uid'][0]

    uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                              env.get('HTTP_ORIGIN', ''))
    print('Connection to websocket %s', uid)

    channel = rd.pubsub()
    channel.subscribe(uid)
    print('Subscribe to channel %s', uid)
    ws_fd = uwsgi.connection_fd()
    rd_fd = channel.connection._sock.fileno()

    while True:
        # wait max 4 seconds to allow ping to be sent
        ready = select.select([ws_fd, rd_fd], [], [], 4.0)
        # send ping on timeout
        if not ready[0]:
            uwsgi.websocket_recv_nb()
        for fd in ready[0]:
            if fd == ws_fd:
                try:
                    msg = uwsgi.websocket_recv_nb()
                    if msg:
                        print('Pub msg %s', msg)
                        rd.publish(uid, msg)
                except IOError:
                    print('Websocket Closed: %s', uid)
                    return ''
            elif fd == rd_fd:
                msg = channel.parse_response()
                # only interested in user messages
                if msg[0] == 'message':
                    print('Send msg %s', msg[2])
                    uwsgi.websocket_send(msg[2])
Пример #34
0
    def run(self):
        websocket_fd = uwsgi.connection_fd()
        channel_fd = self.channel.connection._sock.fileno()

        fds = [websocket_fd, channel_fd]

        try:
            while True:
                readable, _, _ = select.select(fds, [], [], TIMEOUT)
                if not readable:
                    self.recv()
                    continue

                self.recv()
                data = self.channel.get_message(ignore_subscribe_messages=True)
                if data:
                    self.on_channel_data(data)

        except self.WebSocketError:
            return HttpResponse('ws ok')
        finally:
            self.channel.unsubscribe()
            self.on_connection_lost()
Пример #35
0
 def wsSubData_nb(self):
     """Websocket subscribe redis pubsub nonbolocking.
        Keepalive websocket connection with client."""
     uwsgi.websocket_handshake(self.environ['HTTP_SEC_WEBSOCKET_KEY'], self.environ.get('HTTP_ORIGIN', ''))
     channel = self.r.pubsub()
     channel.subscribe(self.channel)
     channel.parse_response()
     websocket_fd = uwsgi.connection_fd()
     redis_fd = channel.connection._sock.fileno()
     while True:
         uwsgi.wait_fd_read(websocket_fd, 3)
         uwsgi.wait_fd_read(redis_fd)
         uwsgi.suspend()
         fd = uwsgi.ready_fd()
         if fd > -1:
             if fd == websocket_fd:
                 uwsgi.websocket_recv_nb()
             elif fd == redis_fd:
                 wsdata = channel.parse_response()[2]
                 uwsgi.websocket_send(wsdata)
         else:
             uwsgi.websocket_recv_nb()
             time.sleep(1)
Пример #36
0
    def get(self):
        def handle_request(r, msg):
            """Handle request for more messages received from websocket."""

            request = json.loads(msg)
            first = int(request["first_id"])
            last = int(request["last_id"])
            # Don't fetch more than 50 messages at once:
            if (last > 0 and (last - 50 > first)) or (last < 0):
                first = last - 50
            pickled_messages = r.lrange(REDIS_MESSAGES_KEY, first, last)
            messages = []
            for pickled_message in pickled_messages:
                message = pickle.loads(pickled_message)
                messages.append(message)

            uwsgi.websocket_send(encode_messages(messages))

        # The first thing we need to do is take what seems like a normal HTTP
        # request and upgrade it to be a websocket request:
        uwsgi.websocket_handshake(os.getenv('HTTP_SEC_WEBSOCKET_KEY', ''),
                                  os.getenv('HTTP_ORIGIN', ''))

        # Open a connection to the Redis server, and ask to be notified of any
        # messages on the channel REDIS_CHANNEL:
        r = redis.StrictRedis(host='localhost', port=6379, db=0)
        channel = r.pubsub()
        channel.subscribe(REDIS_CHANNEL)

        # We then want to go to sleep and wait for messages either from Redis,
        # or from this websocket.  So we need to know their file descriptors:
        websocket_fd = uwsgi.connection_fd()
        redis_fd = channel.connection._sock.fileno()

        while True:
            # Setup both FDs with epoll so we can wait for messages.  Wake up
            # every 3 seconds to ensure that ping messages get exchanged on the
            # websocket connection to keep it alive:
            uwsgi.wait_fd_read(websocket_fd, 3)
            uwsgi.wait_fd_read(redis_fd)

            # Put thread to sleep until message arrives or timeout.  Note that
            # if you do not use a suspend engine (such as ugreen) this will just
            # immediately return without suspending, nothing will work, and you
            # will get horribly confused.
            uwsgi.suspend()

            fd = uwsgi.ready_fd()
            if fd > -1:
                if fd == websocket_fd:
                    try:
                        msg = uwsgi.websocket_recv_nb()
                        if msg:
                            handle_request(r, msg)

                    except IOError, e:
                        # Websocket has failed in some way (such as a browser
                        # reload), just close it and let the app re-open if it
                        # is still there to do so:
                        return
                elif fd == redis_fd:
                    # Got a message from Redis, pass it on to the browser
                    # through the websocket.
                    msg = channel.parse_response()
                    # Redis sends both control messages and user messages
                    # through this fd.  Send only user-generated messages to all
                    # clients:
                    if msg[0] == b'message':
                        uwsgi.websocket_send(msg[2])
            else:
                # We got a timeout.  Call websocket_recv_nb again to manage
                # ping/pong:
                try:
                    msg = uwsgi.websocket_recv_nb()
                    if msg:
                        handle_request(r, msg)

                except IOError, e:
                    # Websocket has failed in some way (such as a browser
                    # reload), just close it and let the app re-open if it is
                    # still there to do so:
                    return
Пример #37
0
def application(env, start_response):
    request = Request(env)

    try:
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                  env.get('HTTP_ORIGIN', ''))
    except OSError as err:
        logging.info('handshake_failed')

    else:
        with cursor_for_request(request) as cursor:
            db_connection = cursor.connection
            db_connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

            session_id = get_session_id(request, cursor)

            logging.info('event/table/session/row/%s:connected (role: %s)' %
                         (session_id, env['DB_USER']))

            db_conn_fd = db_connection.fileno()
            websocket_fd = uwsgi.connection_fd()

            cursor.execute('listen "event/table/session/rows/%i"' % session_id)

            try:
                while True:
                    uwsgi.wait_fd_read(websocket_fd)
                    uwsgi.wait_fd_read(db_conn_fd)
                    uwsgi.suspend()

                    fd = uwsgi.ready_fd()

                    if fd == websocket_fd:
                        cmd_json = uwsgi.websocket_recv_nb()

                        if cmd_json:
                            cmd = json.loads(cmd_json.decode('utf-8'))

                            if cmd:
                                try:
                                    if cmd['method'] == 'subscribe':
                                        selector, type = cmd['args'][
                                            'selector'].rsplit(':', 1)
                                        cursor.execute(
                                            "select event.subscribe_session(%s, %s, %s);",
                                            (session_id, selector, type))

                                    elif cmd['method'] == 'unsubscribe':
                                        selector, type = cmd['args'][
                                            'selector'].rsplit(':', 1)
                                        cursor.execute(
                                            "select event.unsubscribe_session(%s, %s, %s);",
                                            (session_id, selector, type))

                                except Warning as err:
                                    logging.error(str(err))
                                    uwsgi.websocket_send(
                                        json.dumps({
                                            "method": "log",
                                            "args": {
                                                "level": "warning",
                                                "message":
                                                err.diag.message_primary
                                            }
                                        }))

                    elif fd == db_conn_fd:
                        db_connection.poll()

                        if db_connection.notifies:
                            del db_connection.notifies[:]

                            cursor.execute(
                                '''
                                select *
                                from event.session_queued_events_json(%s)
                            ''', (session_id, ))

                            qe_ids = []
                            logging.info(
                                'event/table/session/row/%s:flushing_queue (role: %s)'
                                % (session_id, env['DB_USER']))

                            for row in cursor:
                                uwsgi.websocket_send(json.dumps(
                                    row.event_json))
                                logging.info(
                                    'event/table/session/row/%s:sent_json (role: %s)'
                                    % (session_id, env['DB_USER']))
                                qe_ids.append(row.queued_event_id)

                            cursor.execute(
                                '''
                                delete from event.queued_event qe
                                where qe.id = any(%s)
                            ''', (qe_ids, ))
                    else:
                        # handle timeout of above wait_fd_read for ping/pong
                        uwsgi.websocket_recv_nb()

            except OSError as err:
                logging.info(
                    'event/table/session/row/%s:disconnected (role: %s)' %
                    (session_id, env['DB_USER']))

        return []
Пример #38
0
def application(env, start_response):
    request = Request(env)

    try:
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                  env.get('HTTP_ORIGIN', ''))
    except OSError as err:
        logging.info('handshake_failed')

    else:
        with cursor_for_request(request) as cursor:
            db_connection = cursor.connection
            db_connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

            db_conn_fd = db_connection.fileno()
            websocket_fd = uwsgi.connection_fd()

            logging.info('connection established')

            try:
                while True:
                    uwsgi.wait_fd_read(websocket_fd)
                    uwsgi.wait_fd_read(db_conn_fd)
                    uwsgi.suspend()

                    fd = uwsgi.ready_fd()

                    if fd == websocket_fd:
                        cmd_json = uwsgi.websocket_recv_nb()

                        if cmd_json:
                            cmd = json.loads(cmd_json.decode('utf-8'))

                            if cmd:
                                try:
                                    if cmd['method'] != 'ping':
                                        logging.info('command received: %s' % cmd['method'])

                                    if cmd['method'] == 'request':
                                        request_method(cmd, cursor)

                                    elif cmd['method'] == 'attach':
                                        attach_method(cmd, cursor, db_connection, env)

                                    elif cmd['method'] == 'detach':
                                        detach_method(cmd, cursor, db_connection, env)

                                except Warning as err:
                                    logging.error(str(err))
#                                    uwsgi.websocket_send(json.dumps({
#                                        "method": "log",
#                                        "args": {
#                                            "level": "warning",
#                                            "message": err.diag.message_primary
#                                        }
#                                    }))

                    elif fd == db_conn_fd:
                        handle_db_notifications(db_connection)

                    else:
                        logging.info('timeout reached') # This is never reached

                        # handle timeout of above wait_fd_read for ping/pong
                        uwsgi.websocket_recv_nb()

            except (OSError, IOError) as err:
                logging.info('connection closed (role: %s)' % env['DB_USER'])

        return []
Пример #39
0
def application(e, sr):
    if e['PATH_INFO'] == '/phys':
        uwsgi.websocket_handshake()

        w = World()
        me = Box('box0', w, 1000, 250, -1000, 250, 0)
        box1 = Box('box1', w, 20, 50, -1000, 250, 0)
        box2 = Box('box2', w, 20, 50, -1500, 350, 0)
        box3 = Box('box3', w, 20, 50, -1500, 450, 0)
        box4 = Box('box4', w, 200, 150, -1500, 550, 0)

        ramp = Ramp('ramp0', w, 400, 0, 100, 7000, 10, 400)

        print "BOX DRAWING COMPLETE"

        gevent.spawn(physic_engine, w)
        ufd = uwsgi.connection_fd()
        while True:

            ready = gevent.select.select([ufd, w.redis_fd], [], [],
                                         timeout=4.0)

            if not ready[0]:
                uwsgi.websocket_recv_nb()

            for fd in ready[0]:
                if fd == ufd:
                    try:
                        msg = uwsgi.websocket_recv_nb()
                        if msg == 'fw':
                            orientation = me.body.getOrientation()
                            v = Vector3(0, 0,
                                        5000).rotate(orientation.getAxis(),
                                                     orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyCentralImpulse(v)
                        elif msg == 'bw':
                            orientation = me.body.getOrientation()
                            v = Vector3(0, 0,
                                        -5000).rotate(orientation.getAxis(),
                                                      orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyCentralImpulse(v)
                        elif msg == 'rl':
                            orientation = me.body.getOrientation()
                            v = Vector3(0, 2000000,
                                        0).rotate(orientation.getAxis(),
                                                  orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyTorqueImpulse(v)
                        elif msg == 'rr':
                            orientation = me.body.getOrientation()
                            v = Vector3(0, -2000000,
                                        0).rotate(orientation.getAxis(),
                                                  orientation.getAngle())
                            me.body.activate(True)
                            me.body.applyTorqueImpulse(v)
                        #me.body.applyForce( Vector3(0, 0, 10000), Vector3(-200, 0, 0))
                        #me.body.applyForce( Vector3(0, 0, -10000), Vector3(200, 0, 0))
                    except IOError:
                        import sys
                        print sys.exc_info()
                        return [""]
                elif fd == w.redis_fd:
                    msg = w.channel.parse_response()
                    if msg[0] == 'message':
                        uwsgi.websocket_send(msg[2])
Пример #40
0
def application(env, start_response):
    request = Request(env)

    try:
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                  env.get('HTTP_ORIGIN', ''))
    except OSError as err:
        logging.info('handshake_failed')

    else:
        with cursor_for_request(request) as cursor:
            db_connection = cursor.connection
            db_connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

            db_conn_fd = db_connection.fileno()
            websocket_fd = uwsgi.connection_fd()

            logging.info('connection established')

            try:
                while True:
                    uwsgi.wait_fd_read(websocket_fd)
                    uwsgi.wait_fd_read(db_conn_fd)
                    uwsgi.suspend()

                    fd = uwsgi.ready_fd()

                    if fd == websocket_fd:
                        cmd_json = uwsgi.websocket_recv_nb()

                        if cmd_json:
                            cmd = json.loads(cmd_json.decode('utf-8'))

                            if cmd:
                                try:
                                    if cmd['method'] != 'ping':
                                        logging.info('command received: %s' %
                                                     cmd['method'])

                                    if cmd['method'] == 'request':
                                        request_method(cmd, cursor)

                                    elif cmd['method'] == 'attach':
                                        attach_method(cmd, cursor,
                                                      db_connection, env)

                                    elif cmd['method'] == 'detach':
                                        detach_method(cmd, cursor,
                                                      db_connection, env)

                                except Warning as err:
                                    logging.error(str(err))
#                                    uwsgi.websocket_send(json.dumps({
#                                        "method": "log",
#                                        "args": {
#                                            "level": "warning",
#                                            "message": err.diag.message_primary
#                                        }
#                                    }))

                    elif fd == db_conn_fd:
                        handle_db_notifications(db_connection)

                    else:
                        logging.info(
                            'timeout reached')  # This is never reached

                        # handle timeout of above wait_fd_read for ping/pong
                        uwsgi.websocket_recv_nb()

            except (OSError, IOError) as err:
                logging.info('connection closed (role: %s)' % env['DB_USER'])

        return []
Пример #41
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type','text/html')])
        output = """
    <!doctype html>
    <html>
      <head>
          <meta charset="utf-8">
          <script language="Javascript">
            var s = new WebSocket("%s://%s/foobar/");
            s.onopen = function() {
              console.log("connected !!!");
              s.send("hello");
            };
            s.onmessage = function(e) {
        var bb = document.getElementById('blackboard')
        var html = bb.innerHTML;
        bb.innerHTML = html + '<br/>' + e.data;
            };

        s.onerror = function(e) {
            console.log(e);
        }

    s.onclose = function(e) {
        console.log("connection closed");
    }

            function invia() {
              var value = document.getElementById('testo').value;
              s.send(value);
            }
          </script>
     </head>
    <body>
        <h1>WebSocket</h1>
        <input type="text" id="testo"/>
        <input type="button" value="invia" onClick="invia();"/>
    <div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
    </div>
    </body>
    </html>
        """ % (ws_scheme, env['HTTP_HOST'])
        return output.encode()
    elif env['PATH_INFO'] == '/favicon.ico':
        return ""
    elif env['PATH_INFO'] == '/foobar/':
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
        print("websockets...")
        msg_srv_fd = uwsgi.async_connect("127.0.0.1:8888")
        websocket_fd = uwsgi.connection_fd()
        while True:
            uwsgi.wait_fd_read(websocket_fd, 3)
            uwsgi.wait_fd_read(msg_srv_fd)
            uwsgi.suspend()
            fd = uwsgi.ready_fd()
            if fd > -1:
                if fd == websocket_fd:
                    msg = uwsgi.websocket_recv_nb()
                    print("got message over ws: {}".format(msg))
                    if msg:
                        uwsgi.send(msg_srv_fd, msg)
                elif fd == msg_srv_fd:
                    msg = uwsgi.recv(msg_srv_fd)
                    print("got message over msg_srv: {}".format(msg))
                    uwsgi.websocket_send("[%s] %s" % (time.time(), msg.decode()))
            else:
                # on timeout call websocket_recv_nb again to manage ping/pong
                msg = uwsgi.websocket_recv_nb()
                print("ws ping/pong")
                if msg:
                    print("got message over ws: {}".format(msg))
                    uwsgi.send(msg_srv_fd, msg)
Пример #42
0
def application(env, sr):
    
    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'
    
    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type','text/html')])
        data = {
            'ws_scheme': ws_scheme,
            'host': env['HTTP_HOST'],
            'id': env['uwsgi.core'],
        }

        return HTML%(ws_scheme, data['host'])
    elif env['PATH_INFO'] == '/foobar/':
        connection_info = (env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
        
        redis_com = redis.StrictRedis(**redis_conf)
        channel = redis_com.pubsub()
        channel.subscribe(COMMON_ROOM_ID)
 
        websocket_fd = uwsgi.connection_fd()
        redis_fd = channel.connection._sock.fileno()

        core_id = str(env['uwsgi.core'])
        all_users_info[core_id] = {'redis_channel': channel}

        print "#########################websockets...", core_id
        print "REMOTE_ADDR:", env['REMOTE_ADDR']
        
        while True:
            ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
            if not ready[0]:
                try:
                    msg =  uwsgi.websocket_recv_nb()
                    
                except IOError:
                    print 'disconnect uid ***** no ready', core_id
                    del_user(core_id, redis_com)
                    continue
            for fd in ready[0]:
                if fd == websocket_fd:
                    try:
                        msg =  uwsgi.websocket_recv_nb()
                    except IOError:
                        print 'disconnect uid ***** no msg', core_id
                        del_user(core_id, redis_com)
                        return '' 
                    if msg:
                        print 'this msg str', msg
                        msg_dict = json.loads(msg.replace("\n", "\\n   "))
                        print "~~~~~~~~~~reseve", msg_dict
                        if 'c' not in msg_dict:
                            continue
                        if msg_dict['c'] in ['s', 'rn']:
                            if core_id not in all_users_info:
                                return 'guochen'
                            if msg_dict['u'].strip(): 
                                all_users_info[core_id]['user_name'] = msg_dict['u']
                            else:
                                all_users_info[core_id]['user_name'] = u'游客' + str(core_id) 
                            response = get_response_user_msg(c=msg_dict['c'])
                            redis_com.publish(COMMON_ROOM_ID, dumps(response))
                            response['uname'] = all_users_info[core_id]['user_name']
                            response['self_id'] = core_id
                            if msg_dict['c'] == 's':
                                response['history_msg'] = history_msg
                            uwsgi.websocket_send(dumps(response))
                        elif msg_dict['c'] == 'chat':
                            chat_msg = msg_dict['m'].strip()
                            if not chat_msg:
                                continue
                            now_channel = COMMON_ROOM_ID
                            if msg_dict['opp'] != COMMON_ROOM_ID:
                                opp = msg_dict['opp'] 
                                now_channel = '|'.join(map(str, sorted(map(int, [core_id, opp]))))
                                if now_channel not in channels:
                                    channels.append(now_channel)
                                    channel.subscribe(now_channel)
                                    all_users_info[opp]['redis_channel'].subscribe(now_channel)
                                    redis_com.publish(now_channel,dumps({})) 
                                    channel.parse_response()
                                    #all_users_info[opp]['redis_channel'].parse_response()

                            response = {
                                'uname': all_users_info[core_id]['user_name'], 
                                'time': str(datetime.datetime.now())[0:-7],
                                'msg': chat_msg,
                                'c': 'chat', 
                                'channel': now_channel, 
                            }
                            add_history(response)
                            logging.info(response['uname'] +" :\n    " + response['msg'] )
                            response = dumps(response)
                            s = redis_com.publish(now_channel, response)
                            print "why no send", s
                            #print channel.parse_response()
                            #uwsgi.websocket_send(response)
    
                        elif msg_dict['c'] == 'e': # end 
                            print 'disconnect uid ***** client close', core_id
                            del_user(core_id, redis_com)
                            return '' 

                elif fd == redis_fd:
                    msg = channel.parse_response()
                    if msg[0] == 'message':
                        uwsgi.websocket_send(msg[2])
Пример #43
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type', 'text/html')])
        return ("""
    <html>
      <head>
          <script language="Javascript">
            var s = new WebSocket("%s://%s/foobar/");
            s.onopen = function() {
              alert("connected !!!");
              s.send("ciao");
            };
            s.onmessage = function(e) {
                var bb = document.getElementById('blackboard')
                var html = bb.innerHTML;
                bb.innerHTML = html + '<br/>' + e.data;
            };

            s.onerror = function(e) {
                        alert(e);
                }

        s.onclose = function(e) {
                alert("connection closed");
        }

            function invia() {
              var value = document.getElementById('testo').value;
              s.send(value);
            }
          </script>
     </head>
    <body>
        <h1>WebSocket</h1>
        <input type="text" id="testo"/>
        <input type="button" value="invia" onClick="invia();"/>
        <div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
        </div>
    </body>
    </html>
        """ % (ws_scheme, env['HTTP_HOST'])).encode()
    elif env['PATH_INFO'] == '/favicon.ico':
        return b""
    elif env['PATH_INFO'] == '/foobar/':
        uwsgi.websocket_handshake()
        print("websockets...")
        # a future for waiting for redis connection
        f = GreenFuture()
        asyncio.Task(redis_subscribe(f))
        # the result() method will switch greenlets if needed
        subscriber = f.result()

        # open another redis connection for publishing messages
        f0 = GreenFuture()
        t = asyncio.Task(redis_open(f0))
        connection = f0.result()

        myself = greenlet.getcurrent()
        myself.has_ws_msg = False
        # start monitoring websocket events
        asyncio.get_event_loop().add_reader(uwsgi.connection_fd(), ws_recv_msg, myself)

        # add a 4 seconds timer to manage ping/pong
        asyncio.get_event_loop().call_later(4, ws_recv_msg, myself)

        # add a coroutine for redis messages
        f = GreenFuture()
        asyncio.Task(redis_wait(subscriber, f))

        # switch again
        f.greenlet.parent.switch()

        while True:
            # any redis message in the queue ?
            if f.done():
                msg = f.result()
                uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
                # restart coroutine
                f = GreenFuture()
                asyncio.Task(redis_wait(subscriber, f))
            if myself.has_ws_msg:
                myself.has_ws_msg = False
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    asyncio.Task(redis_publish(connection, msg))
            # switch again
            f.greenlet.parent.switch()
Пример #44
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type', 'text/html')])
        output = """
    <html>
      <head>
          <script language="Javascript">
            var s = new WebSocket("%s://%s/foobar/");
            s.onopen = function() {
              alert("connected !!!");
              s.send("ciao");
            };
            s.onmessage = function(e) {
                var bb = document.getElementById('blackboard')
                var html = bb.innerHTML;
                bb.innerHTML = html + '<br/>' + e.data;
            };

            s.onerror = function(e) {
                        alert(e);
                }

        s.onclose = function(e) {
                alert("connection closed");
        }

            function invia() {
              var value = document.getElementById('testo').value;
              s.send(value);
            }
          </script>
     </head>
    <body>
        <h1>WebSocket</h1>
        <input type="text" id="testo"/>
        <input type="button" value="invia" onClick="invia();"/>
        <div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
        </div>
    </body>
    </html>
        """ % (ws_scheme, env['HTTP_HOST'])
        if sys.version_info[0] > 2:
            return output.encode('latin1')
        return output
    elif env['PATH_INFO'] == '/favicon.ico':
        return ""
    elif env['PATH_INFO'] == '/foobar/':
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                  env.get('HTTP_ORIGIN', ''))
        print("websockets...")
        r = redis.StrictRedis(host='localhost', port=6379, db=0)
        channel = r.pubsub()
        channel.subscribe('foobar')

        websocket_fd = uwsgi.connection_fd()
        redis_fd = channel.connection._sock.fileno()

        while True:
            uwsgi.wait_fd_read(websocket_fd, 3)
            uwsgi.wait_fd_read(redis_fd)
            uwsgi.suspend()
            fd = uwsgi.ready_fd()
            if fd > -1:
                if fd == websocket_fd:
                    msg = uwsgi.websocket_recv_nb()
                    if msg:
                        r.publish('foobar', msg)
                elif fd == redis_fd:
                    msg = channel.parse_response()
                    print(msg)
                    # only interested in user messages
                    t = 'message'
                    if sys.version_info[0] > 2:
                        t = b'message'
                    if msg[0] == t:
                        uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
            else:
                # on timeout call websocket_recv_nb again to manage ping/pong
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    r.publish('foobar', msg)
Пример #45
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type','text/html')])
        return """
    <!DOCTYPE html>
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!-- Consider specifying the language of your content by adding the `lang` attribute to <html> -->
  <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
      <!--[if IE 8]>    <html class="no-js lt-ie9"> <![endif]-->
        <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
          <head>
            <!--
            hey all! i made this as a prototype thinking of collective instruments and
            real time web interactivity.

            A couple days ago I started playing with the web audio api, so this is
            pretty minimal.  I'm putting this out to see how people feel playing with it,
            and how it fares scaling up.  It was built with socketio and node.

            let me know what you think tweet me at @whichlight, or whichlight at gmail dot com

            see other projects at http://whichlight.com/

            -->

            <meta charset="utf-8">

            <title>dancey dots</title>
            <meta name="description" content="">
            <!-- Mobile viewport optimized: h5bp.com/viewport -->
            <meta name="viewport" content="width=device-width">
            <style type="text/css">
              #container{
                font-family:helvetica;
                margin: 0px auto;
                width:650px;
              }

              .synth{
                background-color:pink;
                position: absolute;
                height: 40px;
                min-width: 40px;
                border-radius:20px;
                z-index:-1;
              }
              #info{
                position: absolute;
                right: 10px;
                bottom: 10px;
                z-index: 2;
                padding: 16px 24px;
                color:grey;
                font-size:15px;
                font-family: helvetica;

              }

              #fun{
                position:absolute;
                width:100%;
                height:100%;
              }
            </style>
           </head>
           <body>

             <div id="fun">
               <div id="info">dancey dots by <a href="http://www.whichlight.com">whichlight</a></div>
             </div>
             <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
             <script type="text/javascript" src="bower_components/hammerjs/hammer.min.js"></script>
             <script type="text/javascript" src="main.js"></script>
           </body>
         </html>
        """
    elif env['PATH_INFO'] == '/favicon.ico':
        return ""
    elif env['PATH_INFO'] == '/foobar/':
	uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
        print "websockets..."
        r = redis.StrictRedis(host='localhost', port=6379, db=0)
        channel = r.pubsub()
        channel.subscribe('foobar')

        websocket_fd = uwsgi.connection_fd()
        redis_fd = channel.connection._sock.fileno()
        
        while True:
            # wait max 4 seconds to allow ping to be sent
            ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
            # send ping on timeout
            if not ready[0]:
                uwsgi.websocket_recv_nb()
            for fd in ready[0]:
                if fd == websocket_fd:
                    msg = uwsgi.websocket_recv_nb()
                    if msg:
                        r.publish('foobar', msg)
                elif fd == redis_fd:
                    msg = channel.parse_response() 
                    # only interested in user messages
                    if msg[0] == 'message':
                        uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
Пример #46
0
    def ws_async_cgi(self, work, ws_args):

        try:

            import uwsgi
            import greenlet

            uwsgi.websocket_handshake()
            print("websockets...")

            me = greenlet.getcurrent()
            me.has_ws_msg = False
            me.task_ending = False
            me.sq_unregist = False
            me.rq_unregist = False

            self.ws = WSClient()
            for k, v in ws_args.items():
                setattr(self.ws, k, v)

            self.t = asyncio.Task(self.ws_work(me, work))

            asyncio.get_event_loop().add_reader(uwsgi.connection_fd(),
                                                self.ws_recv_msg, me)

            f = asyncio.Future()
            asyncio.Task(self.ws_get_sq_msg(me, self.ws.sq, f))

            while not (me.task_ending and me.sq_unregist):

                me.parent.switch()

                if f.done():

                    r = f.result()
                    if r == Exception:
                        me.sq_unregist = True
                    else:
                        uwsgi.websocket_send(r)
                        f = asyncio.Future()
                        asyncio.Task(self.ws_get_sq_msg(me, self.ws.sq, f))

                if me.has_ws_msg:

                    me.has_ws_msg = False

                    try:
                        msg = uwsgi.websocket_recv_nb()
                    except OSError:
                        print('.......')
                        self.ws.sq.put(Exception)
                        asyncio.get_event_loop().remove_reader(
                            uwsgi.connection_fd())
                        me.rq_unregist = True
                        self.t.cancel()
                        continue

                    msg = msg.decode('utf-8')
                    self.ws.rq.put_nowait(msg)

            if me.rq_unregist == False:
                asyncio.get_event_loop().remove_reader(uwsgi.connection_fd())

            print('exit')

        except:
            import traceback
            traceback.print_exc()

        return
Пример #47
0
def application(env, start_response):
    request = Request(env)

    try:
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                  env.get('HTTP_ORIGIN', ''))
    except OSError as err:
        logging.info('handshake_failed')

    else:
        with cursor_for_request(request) as cursor:
            db_connection = cursor.connection
            db_connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

            db_conn_fd = db_connection.fileno()
            websocket_fd = uwsgi.connection_fd()

            logging.info('connection established')

            try:
                while True:
                    uwsgi.wait_fd_read(websocket_fd)
                    uwsgi.wait_fd_read(db_conn_fd)
                    uwsgi.suspend()

                    fd = uwsgi.ready_fd()

                    if fd == websocket_fd:
                        cmd_json = uwsgi.websocket_recv_nb()

                        if cmd_json:
                            cmd = json.loads(cmd_json.decode('utf-8'))

                            if cmd:
                                try:
                                    if cmd['method'] != 'ping':
                                        logging.info('command received: %s' %
                                                     cmd['method'])

                                    if cmd['method'] == 'request':

                                        logging.info(
                                            'websocket endpoint request: %s, %s, %s, %s'
                                            % (
                                                cmd['verb'],  # HTTP method               - GET, POST, PATCH, DELETE
                                                cmd['uri'],  # selector                  - '/relation/widget/dependency_js'
                                                ImmutableMultiDict(
                                                    json.loads(cmd['query'])
                                                ),  # query string arguments    - including event.session id
                                                json.dumps(
                                                    cmd['data'])  # post data
                                            ))

                                        cursor.execute(
                                            'select status, message, response, mimetype from endpoint.request2(%s, %s, %s::json, %s::json);',
                                            (
                                                cmd['verb'],  # HTTP method               - GET, POST, PATCH, DELETE
                                                cmd['uri'],  # selector                  - '/relation/widget/dependency_js'
                                                json.dumps(
                                                    ImmutableMultiDict(
                                                        json.loads(
                                                            cmd['query'])
                                                    ).to_dict(flat=False)
                                                ),  # query string arguments    - including event.session id
                                                json.dumps(
                                                    cmd['data'])  # post data
                                            ))

                                        result = cursor.fetchone()

                                        uwsgi.websocket_send('''{
                                            "method": "response",
                                            "request_id": "%s",
                                            "data": %s
                                        }''' % (cmd['request_id'],
                                                result.response))

                                    elif cmd['method'] == 'attach':
                                        session_id = cmd['session_id']
                                        if session_id is not None:
                                            cursor.execute(
                                                'select event.session_attach(%s);',
                                                (session_id, ))
                                            logging.info(
                                                'session attached: %s (role: %s)'
                                                % (session_id, env['DB_USER']))
                                            handle_db_notifications(
                                                db_connection)

                                            uwsgi.websocket_send('''{
                                                "method": "response",
                                                "request_id": "%s",
                                                "data": "true"
                                            }''' % (cmd['request_id'], ))

                                    elif cmd['method'] == 'detach':
                                        session_id = cmd['session_id']
                                        if session_id is not None:
                                            cursor.execute(
                                                'select event.session_detach(%s);',
                                                (session_id, ))
                                            logging.info(
                                                'session detached: %s (role: %s)'
                                                % (session_id, env['DB_USER']))

                                            uwsgi.websocket_send('''{
                                                "method": "response",
                                                "request_id": "%s",
                                                "data": "true"
                                            }''' % (cmd['request_id'], ))

                                    #uwsgi.websocket_send('''{
                                    #    "method": "response",
                                    #    "request_id": "%s",
                                    #    "data": %s
                                    #}''' % (cmd['request_id'], result.response))

                                except Warning as err:
                                    logging.error(str(err))
#                                    uwsgi.websocket_send(json.dumps({
#                                        "method": "log",
#                                        "args": {
#                                            "level": "warning",
#                                            "message": err.diag.message_primary
#                                        }
#                                    }))

                    elif fd == db_conn_fd:
                        handle_db_notifications(db_connection)

                    else:
                        logging.info(
                            'timeout reached')  # This is never reached

                        # handle timeout of above wait_fd_read for ping/pong
                        uwsgi.websocket_recv_nb()

            except (OSError, IOError) as err:
                logging.info('connection closed (role: %s)' % env['DB_USER'])

        return []
Пример #48
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type', 'text/html')])
        return ("""
    <html>
      <head>
          <script language="Javascript">
            var s = new WebSocket("%s://%s/foobar/");
            s.onopen = function() {
              alert("connected !!!");
              s.send("ciao");
            };
            s.onmessage = function(e) {
                var bb = document.getElementById('blackboard')
                var html = bb.innerHTML;
                bb.innerHTML = html + '<br/>' + e.data;
            };

            s.onerror = function(e) {
                        alert(e);
                }

        s.onclose = function(e) {
                alert("connection closed");
        }

            function invia() {
              var value = document.getElementById('testo').value;
              s.send(value);
            }
          </script>
     </head>
    <body>
        <h1>WebSocket</h1>
        <input type="text" id="testo"/>
        <input type="button" value="invia" onClick="invia();"/>
        <div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
        </div>
    </body>
    </html>
        """ % (ws_scheme, env['HTTP_HOST'])).encode()
    elif env['PATH_INFO'] == '/favicon.ico':
        return b""
    elif env['PATH_INFO'] == '/foobar/':
        uwsgi.websocket_handshake()
        print("websockets...")
        # a future for waiting for redis connection
        f = GreenFuture()
        asyncio.Task(redis_subscribe(f))
        # the result() method will switch greenlets if needed
        subscriber = f.result()

        # open another redis connection for publishing messages
        f0 = GreenFuture()
        t = asyncio.Task(redis_open(f0))
        connection = f0.result()

        myself = greenlet.getcurrent()
        myself.has_ws_msg = False
        # start monitoring websocket events
        asyncio.get_event_loop().add_reader(uwsgi.connection_fd(), ws_recv_msg,
                                            myself)

        # add a 4 seconds timer to manage ping/pong
        asyncio.get_event_loop().call_later(4, ws_recv_msg, myself)

        # add a coroutine for redis messages
        f = GreenFuture()
        asyncio.Task(redis_wait(subscriber, f))

        # switch again
        f.greenlet.parent.switch()

        while True:
            # any redis message in the queue ?
            if f.done():
                msg = f.result()
                uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
                # restart coroutine
                f = GreenFuture()
                asyncio.Task(redis_wait(subscriber, f))
            if myself.has_ws_msg:
                myself.has_ws_msg = False
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    asyncio.Task(redis_publish(connection, msg))
            # switch again
            f.greenlet.parent.switch()
Пример #49
0
    def __call__(self, e, sr):
        if e['PATH_INFO'] == '/':
            sr('200 OK', [('Content-Type', 'text/html')])
            return [open('robotab_ws.html').read()]

        if e['PATH_INFO'] == '/robotab.js':
            sr('200 OK', [('Content-Type', 'application/javascript')])
            return [open('static/js/robotab.js').read()]

        if e['PATH_INFO'] == '/robotab':
            uwsgi.websocket_handshake()
            username, avatar = uwsgi.websocket_recv().split(':')
            try:
                robot_coordinates = self.spawn_iterator.next()
            except StopIteration:
                self.spawn_iterator = iter(self.spawn_points)
                robot_coordinates = self.spawn_iterator.next()

            uwsgi.websocket_send('posters:{}'.format(';'.join(self.posters)))

            for wall in self.walls:
                uwsgi.websocket_send('wall:{},{},{},{},{},{},{}'.format(*wall))

            player = Player(self, username, avatar, uwsgi.connection_fd(),
                            *robot_coordinates)

            if (self.started or self.finished
                    or len(self.players) > self.max_players
                    or len(self.waiting_players) > 0):
                print('{}:{}:{}:{}'.format(
                    self.started, self.finished,
                    len(self.players) > self.max_players,
                    len(self.waiting_players) > 0))

                self.waiting_players.append(player)
                uwsgi.websocket_send("arena:hey {}, wait for next game".format(
                    player.name))
                player.wait_for_game()
                self.waiting_players.remove(player)
            else:
                self.players[player.name] = player

            self.spawn_greenlets()

            for p in self.players.keys():
                self.players[p].update_gfx()

            while True:
                ready = gevent.select.select([player.fd, player.redis_fd], [],
                                             [],
                                             timeout=4.0)

                if not ready[0]:
                    uwsgi.websocket_recv_nb()

                for fd in ready[0]:
                    if fd == player.fd:
                        try:
                            msg = uwsgi.websocket_recv_nb()
                        except IOError:
                            import sys
                            print sys.exc_info()
                            if player.name in self.players:
                                player.end('leaver')
                            return [""]
                        if msg and not self.finished:
                            self.msg_handler(player, msg)
                    elif fd == player.redis_fd:
                        msg = player.channel.parse_response()
                        if msg[0] == 'message':
                            uwsgi.websocket_send(msg[2])
Пример #50
0
        def websockets_wrapper(environ, start_response):
            handler = self.routes.get(environ['PATH_INFO'])

            if not handler:
                return app(environ, start_response)

            # do handshake
            uwsgi.websocket_handshake(
                environ['HTTP_SEC_WEBSOCKET_KEY'],
                environ.get('HTTP_ORIGIN', ''))

            # setup events
            send_event = Event()
            send_queue = Queue(maxsize=1)

            recv_event = Event()
            recv_queue = Queue(maxsize=1)

            # create websocket client
            wfd = uwsgi.connection_fd()
            client = self.create_worker(
                environ, wfd, send_event, send_queue, recv_event, recv_queue)

            # spawn handler
            handler = spawn(handler, client)

            # spawn recv listener
            def listener(client):
                ready = select([client.fd], [], [], client.timeout)
                recv_event.set()
            listening = spawn(listener, client)

            while True:
                if not client.connected:
                    recv_queue.put(None)
                    listening.kill()
                    handler.join(client.timeout)
                    return ''

                # wait for event to draw our attention
                ready = wait([handler, send_event, recv_event], None, 1)

                # handle send events
                if send_event.is_set():
                    try:
                        uwsgi.websocket_send(send_queue.get())
                        send_event.clear()
                    except IOError:
                        client.connected = False

                # handle receive events
                elif recv_event.is_set():
                    recv_event.clear()
                    try:
                        recv_queue.put(uwsgi.websocket_recv_nb())
                        listening = spawn(listener, client)
                    except IOError:
                        client.close()
                        self.unregister_worker(client)

                # handler done, we're outta here
                elif handler.ready():
                    listening.kill()
                    return ''
Пример #51
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type','text/html')])
        return """
    <html>
      <head>
          <script language="Javascript">
            var s = new WebSocket("%s://%s/foobar/");
            s.onopen = function() {
              alert("connected !!!");
              s.send("ciao");
            };
            s.onmessage = function(e) {
		var bb = document.getElementById('blackboard')
		var html = bb.innerHTML;
		bb.innerHTML = html + '<br/>' + e.data;
            };

	    s.onerror = function(e) {
			alert(e);
		}

	s.onclose = function(e) {
		alert("connection closed");
	}

            function invia() {
              var value = document.getElementById('testo').value;
              s.send(value);
            }
          </script>
     </head>
    <body>
        <h1>WebSocket</h1>
        <input type="text" id="testo"/>
        <input type="button" value="invia" onClick="invia();"/>
	<div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
	</div>
    </body>
    </html>
        """ % (ws_scheme, env['HTTP_HOST'])
    elif env['PATH_INFO'] == '/favicon.ico':
        return ""
    elif env['PATH_INFO'] == '/foobar/':
	uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
        print "websockets..."
        r = redis.StrictRedis(host='localhost', port=6379, db=0)
        channel = r.pubsub()
        channel.subscribe('foobar')

        websocket_fd = uwsgi.connection_fd()
        redis_fd = channel.connection._sock.fileno()
        
        while True:
            # wait max 4 seconds to allow ping to be sent
            ready = gevent.select.select([websocket_fd, redis_fd], [], [], 4.0)
            # send ping on timeout
            if not ready[0]:
                uwsgi.websocket_recv_nb()
            for fd in ready[0]:
                if fd == websocket_fd:
                    msg = uwsgi.websocket_recv_nb()
                    if msg:
                        r.publish('foobar', msg)
                elif fd == redis_fd:
                    msg = channel.parse_response() 
                    # only interested in user messages
                    if msg[0] == 'message':
                        uwsgi.websocket_send("[%s] %s" % (time.time(), msg))
Пример #52
0
    def open_websocket(self, env):
        context = None
        try:
            user = self.authenticate(env)
            access_level = User.get_access_level(user)
            if access_level < self.min_access_level:
                return

            uwsgi.websocket_handshake()
            util.print_info('Opening websocket connection', False)

            client_count = self.redis.get('websocket-clients')
            if client_count:
                client_count = int(client_count.decode('utf-8'))
                if client_count >= config.websockets_max_clients:
                    raise ClientError('No available slots.')
            self.redis.incr('websocket-clients')
            context = True
            channel = self.redis.pubsub()
            channel.subscribe(self.name)

            websocket_fd = uwsgi.connection_fd()
            redis_fd = channel.connection._sock.fileno()
            context = self.init_context(env, user, redis_fd)

            while True:
                ready = gevent.select.select([websocket_fd, redis_fd], [], [],
                                             4.0)
                if not ready[0]:
                    # send ping on timeout
                    uwsgi.websocket_recv_nb()

                for fd in ready[0]:
                    if fd == websocket_fd:
                        # client message
                        context = self.fetch_and_handle_client_message(context)
                    elif fd == redis_fd:
                        # channel message
                        message = channel.parse_response()
                        if message[0] == b'message':
                            context = self.handle_channel_message(
                                context, message[2])
        except ClientTimeout:
            util.print_info('Websocket connection client timeout.')
        except ClientDisconnect:
            util.print_info('Websocket connection client disconnected.')
        except ClientError as error:
            util.print_exception('Websocket client error',
                                 error,
                                 False,
                                 print_traceback=False)
        except IOError as error:
            # Socket Error
            util.print_exception('Websocket connection closed',
                                 error,
                                 False,
                                 print_traceback=False)
        except DBError as error:
            # Database Error
            util.print_exception('Database Error occured: ', error)
        except OAuth2Error as error:
            # OAuth 2.0 Error
            util.print_exception('OAuth 2.0 Error occured: ', error)
        except Exception as error:
            # Unknown Exception
            util.print_exception('Unexpected Error occured: ', error, False)
        finally:
            self.cleanup(context)
Пример #53
0
def application(env, start_response):
    # At this point the server received a valid WebSocket Upgrade request,
    # and routed the request to this pseudo-WSGI app,
    # but has not yet send any response.

    def bad(why):
        start_response('400 Bad request (' + why + ')', [])

    if 'HTTP_SEC_WEBSOCKET_KEY' not in env:
        return bad('Missing Sec-WebSocket-Key header')

    match = uri_re.fullmatch(env['PATH_INFO'])
    if not match:
        return bad('Invalid/missing drop ID')

    drop_id = match.group('drop_id')

    # This uWSGI utility function sends the HTTP/101 Switching Protocols response
    # (it doesn't need *start_response*, because it directly accesses the requests'
    # output socket).
    uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))

    redis_conn = get_redis()
    channel = redis_conn.pubsub()
    channel.subscribe(settings.REDIS_PREFIX + drop_id)

    websocket_fd = uwsgi.connection_fd()
    redis_fd = channel.connection._sock.fileno()

    monitoring.WEBSOCKET_CONNECTIONS.inc()

    try:
        while True:
            rable, wable, xfd = gevent.select.select([websocket_fd, redis_fd], [], [], 2)
            if not rable:
                # When the select times out, we do a non-blocking receive. This triggers a check
                # in uWSGI whether a PING should be send. It also handles various housekeeping
                # tasks, like closing the connection and stuff like that.
                # We don't really care what the client has to say.
                uwsgi.websocket_recv_nb()
                continue

            for fd in rable:
                if fd == websocket_fd:
                    uwsgi.websocket_recv_nb()
                elif fd == redis_fd:
                    # This is a reading block, but that's okay since we previously polled for
                    # readability on the redis FD, so the server is sending us a message.
                    msg = channel.handle_message(channel.parse_response())
                    if msg['type'] != 'message':
                        print('Unexpected Redis message type:', msg['type'])
                        continue
                    uwsgi.websocket_send_binary(msg['data'])
                    monitoring.WEBSOCKET_MESSAGES.inc()
    except OSError as ose:
        if str(ose) == 'unable to receive websocket message':  # regular end of connection, nothing we want a trace for.
            pass
        else:
            raise
    finally:
        monitoring.WEBSOCKET_CONNECTIONS.dec()
        channel.close()
Пример #54
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type', 'text/html')])
        return """
    <html>
      <head>
          <script language="Javascript">
            var s = new WebSocket("%s://%s/foobar/");
            s.onopen = function() {
              alert("connected !!!");
              s.send("ciao");
            };
            s.onmessage = function(e) {
		var bb = document.getElementById('blackboard')
		var html = bb.innerHTML;
		bb.innerHTML = html + '<br/>' + e.data;
            };

	    s.onerror = function(e) {
			alert(e);
		}

	s.onclose = function(e) {
		alert("connection closed");
	}

            function invia() {
              var value = document.getElementById('testo').value;
              s.send(value);
            }
          </script>
     </head>
    <body>
        <h1>WebSocket</h1>
        <input type="text" id="testo"/>
        <input type="button" value="invia" onClick="invia();"/>
	<div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
	</div>
    </body>
    </html>
        """ % (ws_scheme, env['HTTP_HOST'])
    elif env['PATH_INFO'] == '/foobar/':
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                                  env.get('HTTP_ORIGIN', ''))
        print "websockets..."
        while True:
            msg = uwsgi.websocket_recv_nb()
            if msg:
                queue.put(msg)
            else:
                try:
                    wait_read(uwsgi.connection_fd(), 0.1)
                except gevent.socket.timeout:
                    try:
                        msg = queue.get_nowait()
                        uwsgi.websocket_send(msg)
                    except:
                        pass
    return ""
Пример #55
0
    def __call__(self, e, sr):
        if e['PATH_INFO'] == '/':
            sr('200 OK', [('Content-Type', 'text/html')])
            return [open('robotab_bullet.html').read()]

        if e['PATH_INFO'] == '/robotab_bullet.js':
            sr('200 OK', [('Content-Type', 'application/javascript')])
            return [open('static/js/robotab_bullet.js').read()]

        if e['PATH_INFO'] == '/robotab':
            uwsgi.websocket_handshake()
            username, avatar = uwsgi.websocket_recv().split(':')
            try:
                robot_coordinates = next(self.spawn_iterator)
            except StopIteration:
                self.spawn_iterator = iter(self.spawn_points)
                robot_coordinates = next(self.spawn_iterator)

            # uwsgi.websocket_send('posters:{}'.format(';'.join(self.posters)))

            for wall in self.walls_coordinates:
                uwsgi.websocket_send(
                    'wall:{},{},{},{},{},{},{}'.format(*wall))

            player = Player(self, username, avatar,
                            uwsgi.connection_fd(), *robot_coordinates)

            if(self.started or self.finished or
               len(self.players) > self.max_players or
               len(self.waiting_players) > 0):
                print('{}:{}:{}:{}'.format(
                    self.started, self.finished,
                    len(self.players) > self.max_players,
                    len(self.waiting_players) > 0))

                self.waiting_players.append(player)
                uwsgi.websocket_send(
                    "arena:hey {}, wait for next game".format(player.name))
                player.wait_for_game()
                self.waiting_players.remove(player)
            else:
                self.players[player.name] = player

            self.spawn_greenlets()

            player.update_gfx()

            for p in self.players.keys():
                uwsgi.websocket_send(self.players[p].last_msg)

            while True:
                ready = gevent.select.select(
                    [player.fd, player.redis_fd], [], [], timeout=4.0)

                if not ready[0]:
                    uwsgi.websocket_recv_nb()

                for fd in ready[0]:
                    if fd == player.fd:
                        try:
                            msg = uwsgi.websocket_recv_nb()
                        except IOError:
                            import sys
                            print sys.exc_info()
                            if player.name in self.players:
                                player.end('leaver')
                            return [""]
                        if msg and not self.finished:
                            self.msg_handler(player, msg)
                    elif fd == player.redis_fd:
                        msg = player.channel.parse_response()
                        if msg[0] == 'message':
                            uwsgi.websocket_send(msg[2])
Пример #56
0
def application(env, sr):

    ws_scheme = 'ws'
    if 'HTTPS' in env or env['wsgi.url_scheme'] == 'https':
        ws_scheme = 'wss'

    if env['PATH_INFO'] == '/':
        sr('200 OK', [('Content-Type', 'text/html')])
        return """
    <html>
      <head>
          <script language="Javascript">
            var s = new WebSocket("%s://%s/foobar/");
            s.onopen = function() {
              alert("connected !!!");
              s.send("ciao");
            };
            s.onmessage = function(e) {
                var bb = document.getElementById('blackboard')
                var html = bb.innerHTML;
                bb.innerHTML = html + '<br/>' + e.data;
            };

            s.onerror = function(e) {
                        alert(e);
                }

        s.onclose = function(e) {
                alert("connection closed");
        }

            function invia() {
              var value = document.getElementById('testo').value;
              s.send(value);
            }
          </script>
     </head>
    <body>
        <h1>WebSocket</h1>
        <input type="text" id="testo"/>
        <input type="button" value="invia" onClick="invia();"/>
        <div id="blackboard" style="width:640px;height:480px;background-color:black;color:white;border: solid 2px red;overflow:auto">
        </div>
    </body>
    </html>
        """ % (ws_scheme, env['HTTP_HOST'])
    elif env['PATH_INFO'] == '/foobar/':
        uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'], env.get('HTTP_ORIGIN', ''))
        print "websockets..."
        while True:
            msg = uwsgi.websocket_recv_nb()
            if msg:
                queue.put(msg)
            else:
                try:
                    wait_read(uwsgi.connection_fd(), 0.1)
                except gevent.socket.timeout:
                    try:
                        msg = queue.get_nowait()
                        uwsgi.websocket_send(msg)
                    except Exception:
                        pass
    return ""