Beispiel #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])
    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())
Beispiel #3
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)
Beispiel #4
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])
Beispiel #5
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]))
Beispiel #6
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]))
Beispiel #7
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 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])
Beispiel #9
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])
 def keepalive():
     """Keep the websocket connection alive (called each minute)."""
     print('PING/PONG...')
     try:
         uwsgi.websocket_recv_nb()
         connection.add_timeout(30, keepalive)
     except OSError as error:
         print(error)
         sys.exit(1)  # Kill process and force uWSGI to Respawn
Beispiel #11
0
 def keepalive():
     """Keep the websocket connection alive (called every 30 seconds)."""
     print('PING/PONG...')
     try:
         uwsgi.websocket_recv_nb()
         connection.call_later(30, keepalive)
     except OSError as error:
         print(error)
         sys.exit(1)  # Kill process and force uWSGI to Respawn
Beispiel #12
0
 def keepalive():
     # hidup 30 detik
     print('PING/PONG...')
     try:
         uwsgi.websocket_recv_nb()
         connection.add_timeout(30, keepalive)
     except OSError as error:
         print(error)
         sys.exit(1)  # Kill process and force uWSGI to Respawn
Beispiel #13
0
    def keepalive():

        print('PING/PONG...')
        try:
            uwsgi.websocket_recv_nb()
            connection.call_later(30, keepalive)
        except OSError as error:
            connection.close()
            print(error)
            sys.exit(1)
Beispiel #14
0
 def wait_for_game(self):
     while (self.game.started or self.game.finished or
            self.name not in self.game.players):
         gevent.sleep(1)
         try:
             uwsgi.websocket_recv_nb()
         except IOError:
             import sys
             print sys.exc_info()
             if self.name in self.players:
                 self.end('leaver')
             return [""]
Beispiel #15
0
def ws_downloads():
    uwsgi.websocket_handshake()
    while True:
        uwsgi.websocket_recv_nb() # for close()
        gevent.sleep(2)

        try:
            payload = json.dumps(rtorrent.downloads())
        except:
            payload = json.dumps({'error': "can't connect to rtorrent"})

        uwsgi.websocket_send(payload)
Beispiel #16
0
 def wait_for_game(self):
     while (self.game.started or self.game.finished
            or self.name not in self.game.players):
         gevent.sleep(1)
         try:
             uwsgi.websocket_recv_nb()
         except IOError:
             import sys
             print sys.exc_info()
             if self.name in self.players:
                 self.end('leaver')
             return [""]
Beispiel #17
0
    def run(self):
        """Combine async uwsgi message loop with ws4py message loop.

        TODO: This could do some serious optimizations and behave asynchronously correct instead of just sleep().
        """

        self.sock.setblocking(False)
        try:
            while not self.terminated:
                logger.debug("Doing nothing")
                time.sleep(0.050)

                logger.debug("Asking for downstream msg")
                msg = uwsgi.websocket_recv_nb()
                if msg:
                    logger.debug("Incoming downstream WS: %s", msg)
                    self.send(msg)

                s = self.stream

                self.opened()

                logger.debug("Asking for upstream msg {s}".format(s=s))
                try:
                    bytes = self.sock.recv(self.reading_buffer_size)
                    if bytes:
                        self.process(bytes)
                except BlockingIOError:
                    pass

        except Exception as e:
            logger.exception(e)
        finally:
            logger.info("Terminating WS proxy loop")
            self.terminate()
Beispiel #18
0
    def connect(self, app, request, user, host):
        import uwsgi
        uwsgi.websocket_handshake()
        self.open(app=app, request=request, user=user, host=host)
        try:
            while True:
                try:
                    msg = uwsgi.websocket_recv_nb()
                    if msg:
                        msg = msg.decode()
                        try:
                            msg = json.loads(msg, object_hook=json_loads_handler)
                        except ValueError:
                            msg = None

                        if msg:
                            self.process_request_from_browser(app, request, user, host, msg, uwsgi)
                    else:
                        for msg in self.messages:
                            uwsgi.websocket_send(json.dumps(msg, default=json_dumps_handler))
                    sleep(0.1)
                except OSError:
                    raise SystemExit()
        finally:
            self.close(app=app, request=request, user=user, host=host)
Beispiel #19
0
    def connect(self, app, request, user, host):
        import uwsgi
        uwsgi.websocket_handshake()
        self.open(app=app, request=request, user=user, host=host)
        try:
            while True:
                try:
                    msg = uwsgi.websocket_recv_nb()
                    if msg:
                        msg = msg.decode()
                        try:
                            msg = json.loads(msg,
                                             object_hook=json_loads_handler)
                        except ValueError:
                            msg = None

                        if msg:
                            self.process_request_from_browser(
                                app, request, user, host, msg, uwsgi)
                    else:
                        for msg in self.messages:
                            uwsgi.websocket_send(
                                json.dumps(msg, default=json_dumps_handler))
                    sleep(0.1)
                except OSError:
                    raise SystemExit()
        finally:
            self.close(app=app, request=request, user=user, host=host)
 def receive(self):
     if self._closed:
         raise WebSocketError("Connection is already closed")
     try:
         return uwsgi.websocket_recv_nb()
     except IOError as e:
         self.close()
Beispiel #21
0
 def recv(self):
     try:
         data = uwsgi.websocket_recv_nb()
         if data:
             self.on_websocket_data(data)
     except:
         raise self.WebSocketError()
Beispiel #22
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()
Beispiel #23
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()
Beispiel #24
0
 def receive(self):
     if self._closed:
         raise WebSocketError("Connection is already closed")
     try:
         return uwsgi.websocket_recv_nb()
     except IOError, e:
         self.close()
         raise WebSocketError(e)
Beispiel #25
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 ''
Beispiel #26
0
def ws(env):
    uwsgi.websocket_handshake(env['HTTP_SEC_WEBSOCKET_KEY'],
                              env.get('HTTP_ORIGIN', ''))
    e = Event()
    events.add(e)
    try:
        while True:
            try:
                uwsgi.websocket_recv_nb()
            except OSError:
                break
            yield e.wait()
            if e.event():
                assets = json.dumps(['boo', 'foo'])
                uwsgi.websocket_send(assets)
    finally:
        events.remove(e)
        e.close()
Beispiel #27
0
 def websocket_read(self):
     try:
         msg = uwsgi.websocket_recv_nb()
     except Exception as e:
         log.info("Websocket closed")
         self.ws.close(e)
         return False
     if msg:
         self.ws.message(msg)
     return True
Beispiel #28
0
def __check_live(conn, flag):
    """检查该websocket是否还生存"""

    # 重试次数
    __try_num = 3
    failed_num = 0
    while True:
        # 心跳包间隔90秒
        time.sleep(10)
        try:
            uwsgi.websocket_recv_nb()
            failed_num = 0
        except:
            failed_num += 1

        if failed_num > __try_num:
            logger.error("心跳包超过{}次无响应,断开websocket连接!".format(__try_num))
            flag.is_return = True
            __unregister_connect(conn)
            return
Beispiel #29
0
    def handle_recv_event(self, client, recv_event, recv_queue):
        recv_event.clear()

        try:
            message = True
            while message:
                message = uwsgi.websocket_recv_nb()
                if not self.discard_read_data and message:
                    recv_queue.put(message)
            return gevent.spawn(self.listener_func, client, recv_event)
        except IOError:
            client.connected = False
Beispiel #30
0
 def keepalive():
     """Keep the websockets connection alive (called every 30 seconds)."""
     print('PING/PONG...')
     # noinspection PyShadowingNames
     try:
         msg = uwsgi.websocket_recv_nb()
         # print(msg.decode("utf-8"))
         connection.add_timeout(30, keepalive)
     except OSError as error:
         connection.close()
         print(error)
         sys.exit(0)  # Kill process and force uWSGI to Respawn
Beispiel #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])
Beispiel #32
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])
Beispiel #33
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)
Beispiel #34
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))
Beispiel #35
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()
Beispiel #36
0
    def main_loop(self):
        while self.state == ClientState.started:
            self.event.wait(3.0)
            try:
                message = uwsgi.websocket_recv_nb()
            except IOError:
                if self.state == ClientState.started:
                    self.state = ClientState.suspended
                break
            if message:
                self.client_recv_queue.put_nowait(message)

            # push client messages to client
            try:
                message = self.client_send_queue.get(block=False)
                uwsgi.websocket_send(message)
            except gevent.queue.Empty:
                # no more messages, so we can clear the event
                self.event.clear()
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()
 def wait(self):
     """Waits and returns received messages.
     If running in compatibility mode for older uWSGI versions,
     it also sends messages that have been queued by send().
     A return value of None means that connection was closed.
     This must be called repeatedly. For uWSGI < 2.1.x it must
     be called from the main greenlet."""
     while True:
         if self._req_ctx is not None:
             try:
                 msg = uwsgi.websocket_recv(request_context=self._req_ctx)
             except IOError:  # connection closed
                 return None
             return self._decode_received(msg)
         else:
             # we wake up at least every 3 seconds to let uWSGI
             # do its ping/ponging
             event_set = self._event.wait(timeout=3)
             if event_set:
                 self._event.clear()
                 # maybe there is something to send
                 msgs = []
                 while True:
                     try:
                         msgs.append(self._send_queue.get(block=False))
                     except gevent.queue.Empty:
                         break
                 for msg in msgs:
                     self._send(msg)
             # maybe there is something to receive, if not, at least
             # ensure uWSGI does its ping/ponging
             try:
                 msg = uwsgi.websocket_recv_nb()
             except IOError:  # connection closed
                 self._select_greenlet.kill()
                 return None
             if msg:  # message available
                 return self._decode_received(msg)
Beispiel #39
0
 def wait(self):
     """Waits and returns received messages.
     If running in compatibility mode for older uWSGI versions,
     it also sends messages that have been queued by send().
     A return value of None means that connection was closed.
     This must be called repeatedly. For uWSGI < 2.1.x it must
     be called from the main greenlet."""
     while True:
         if self._req_ctx is not None:
             try:
                 msg = uwsgi.websocket_recv(request_context=self._req_ctx)
             except IOError:  # connection closed
                 return None
             return self._decode_received(msg)
         else:
             # we wake up at least every 3 seconds to let uWSGI
             # do its ping/ponging
             event_set = self._event.wait(timeout=3)
             if event_set:
                 self._event.clear()
                 # maybe there is something to send
                 msgs = []
                 while True:
                     try:
                         msgs.append(self._send_queue.get(block=False))
                     except gevent.queue.Empty:
                         break
                 for msg in msgs:
                     self._send(msg)
             # maybe there is something to receive, if not, at least
             # ensure uWSGI does its ping/ponging
             try:
                 msg = uwsgi.websocket_recv_nb()
             except IOError:  # connection closed
                 self._select_greenlet.kill()
                 return None
             if msg:  # message available
                 return self._decode_received(msg)
Beispiel #40
0
 def flush(self):
     try:
         uwsgi.websocket_recv_nb()
     except IOError:
         self.close()
Beispiel #41
0
 def websocket_recv_nb(self):
     ''' '''
     return uwsgi.websocket_recv_nb()
Beispiel #42
0
 def fetch_and_handle_client_message(self, context):
     message = uwsgi.websocket_recv_nb()
     if message:
         return self.handle_client_message(context, message)
     return context
Beispiel #43
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])
Beispiel #44
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)
Beispiel #45
0
uwsgi.disconnect = lambda: lib.uwsgi_disconnect(uwsgi_pypy_current_wsgi_req())

"""
uwsgi.websocket_recv()
"""
def uwsgi_pypy_websocket_recv():
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    ub = lib.uwsgi_websocket_recv(wsgi_req);
    if ub == ffi.NULL:
        raise IOError("unable to receive websocket message")
    ret = ffi.string(ub.buf, ub.pos)
    lib.uwsgi_buffer_destroy(ub)
    return ret
uwsgi.websocket_recv = uwsgi_pypy_websocket_recv

"""
uwsgi.websocket_recv_nb()
"""
def uwsgi_pypy_websocket_recv_nb():
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    ub = lib.uwsgi_websocket_recv_nb(wsgi_req);
    if ub == ffi.NULL:
        raise IOError("unable to receive websocket message")
    ret = ffi.string(ub.buf, ub.pos)
    lib.uwsgi_buffer_destroy(ub)
    return ret
uwsgi.websocket_recv_nb = uwsgi_pypy_websocket_recv_nb

"""
uwsgi.websocket_handshake(key, origin)
"""
 def flush(self):
     try:
         uwsgi.websocket_recv_nb()
     except IOError:
         self.close()
Beispiel #47
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))
Beispiel #48
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 []
Beispiel #49
0
uwsgi.disconnect = lambda: lib.uwsgi_disconnect(uwsgi_pypy_current_wsgi_req())

"""
uwsgi.websocket_recv()
"""
def uwsgi_pypy_websocket_recv():
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    ub = lib.uwsgi_websocket_recv(wsgi_req);
    if ub == ffi.NULL:
        raise IOError("unable to receive websocket message")
    ret = ffi.string(ub.buf, ub.pos)
    lib.uwsgi_buffer_destroy(ub)
    return ret
uwsgi.websocket_recv = uwsgi_pypy_websocket_recv

"""
uwsgi.websocket_recv_nb()
"""
def uwsgi_pypy_websocket_recv_nb():
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    ub = lib.uwsgi_websocket_recv_nb(wsgi_req);
    if ub == ffi.NULL:
        raise IOError("unable to receive websocket message")
    ret = ffi.string(ub.buf, ub.pos)
    lib.uwsgi_buffer_destroy(ub)
    return ret
uwsgi.websocket_recv_nb = uwsgi_pypy_websocket_recv_nb

"""
uwsgi.websocket_handshake(key, origin)
"""
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)
Beispiel #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')])
        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)
Beispiel #52
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()
Beispiel #53
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 ''
Beispiel #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'])).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()
Beispiel #55
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 ""
Beispiel #56
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])
Beispiel #57
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])