Ejemplo n.º 1
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 []
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
def application(e, sr):
    sr('200 OK', [('Content-Type', 'text/plain')])

    # call suspend 10 times and yield some value
    for i in range(0, 10):
        print(i)
        uwsgi.suspend()
        yield str(i)

    # connect to a memcached server
    fd = uwsgi.async_connect('127.0.0.1:11211')
    try:
        # start waiting for socket availability (4 seconds max)
        uwsgi.wait_fd_write(fd, 4)
        # suspend execution 'til event
        uwsgi.suspend()
        uwsgi.send(fd, "get /foobar\r\n")
        # now wait for memcached response
        uwsgi.wait_fd_read(fd, 4)
        uwsgi.suspend()
        # read the response
        data = uwsgi.recv(fd, 4096)
        # return to the client
        yield data
    finally:
        uwsgi.close(fd)

    print("sleeping for 3 seconds...")
    uwsgi.async_sleep(3)
    uwsgi.suspend()
    yield "done"
Ejemplo n.º 4
0
def application(e, sr):
    sr('200 OK', [('Content-Type','text/plain')])

    # call suspend 10 times and yield some value
    for i in range(0,10):
        print i
        uwsgi.suspend()
        yield str(i)

    # connect to a memcached server
    fd = uwsgi.async_connect('127.0.0.1:11211')
    try:
        # start waiting for socket availability (4 seconds max)
        uwsgi.wait_fd_write(fd, 4)
        # suspend execution 'til event
        uwsgi.suspend()
        uwsgi.send(fd, "get /foobar\r\n")
        # now wait for memcached response
        uwsgi.wait_fd_read(fd, 4)
        uwsgi.suspend()
        # read the response
        data = uwsgi.recv(fd, 4096)
        # return to the client
        yield data
    finally:
        uwsgi.close(fd)

    print "sleeping for 3 seconds..."
    uwsgi.async_sleep(3)
    uwsgi.suspend()
    yield "done"
Ejemplo n.º 5
0
 def wait(self):
     # Remove context as we are switching between green thread
     # (and therefore websocket request)
     self.ws._pop_context()
     uwsgi.wait_fd_read(self.websocket_fd, 3)
     uwsgi.wait_fd_read(self.db_fd, 5)
     uwsgi.suspend()
     # Restoring request context for all other operations
     self.ws._push_context()
     fd = uwsgi.ready_fd()
     if fd == self.websocket_fd:
         return "websocket"
     if fd == self.db_fd:
         return "db"
     # Try ping / ponging the websocket in case of error
     return "timeout"
Ejemplo n.º 6
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()
Ejemplo n.º 7
0
def async_wait(conn):
	# conn can be a connection or a cursor
	if not hasattr(conn, 'poll'):
		conn = conn.connection
	
	# interesting part: suspend until ready
	while True:
		state = conn.poll()
		if state == psycopg2.extensions.POLL_OK:
			break
		elif state == psycopg2.extensions.POLL_READ:
			uwsgi.wait_fd_read(conn.fileno())
                        uwsgi.suspend()
		elif state == psycopg2.extensions.POLL_WRITE:
			uwsgi.wait_fd_write(conn.fileno())
                        uwsgi.suspend()
		else:
			raise Exception("Unexpected result from poll: %r", state)
Ejemplo n.º 8
0
def async_wait(conn):
    # conn can be a connection or a cursor
    if not hasattr(conn, 'poll'):
        conn = conn.connection

    # interesting part: suspend until ready
    while True:
        state = conn.poll()
        if state == psycopg2.extensions.POLL_OK:
            break
        elif state == psycopg2.extensions.POLL_READ:
            uwsgi.wait_fd_read(conn.fileno())
            uwsgi.suspend()
        elif state == psycopg2.extensions.POLL_WRITE:
            uwsgi.wait_fd_write(conn.fileno())
            uwsgi.suspend()
        else:
            raise Exception("Unexpected result from poll: %r", state)
Ejemplo n.º 9
0
def application(e, sr):
    sr('200 OK', [('Content-Type', 'text/plain')])

    # suspend 10 times and yield a value
    for i in range(1, 10):
        print i
        uwsgi.suspend()
        yield str(i)

    # connect to a memcached server
    fd = uwsgi.async_connect('127.0.0.1:11211')
    try:
        command = "get /foobar\r\n"
        remains = len(command)
        while remains > 0:
            # start waiting for socket availability (4 seconds max)
            uwsgi.wait_fd_write(fd, 4)
            # suspend execution 'til event
            uwsgi.suspend()
            pos = len(command) - remains
            written = uwsgi.send(fd, command[pos:])
            remains -= written

        # now wait for memcached response
        uwsgi.wait_fd_read(fd, 4)
        uwsgi.suspend()
        # read a chunk of data
        data = uwsgi.recv(fd, 4096)
        # .. and yield it
        yield data
    finally:
        # always ensure sockets are closed
        uwsgi.close(fd)

    print "sleeping for 3 seconds..."
    uwsgi.async_sleep(3)
    uwsgi.suspend()
    yield "done"
Ejemplo n.º 10
0
Archivo: mon.py Proyecto: bagel/cluster
 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)
Ejemplo n.º 11
0
def put_file(env, start_response, volume, collection, key):
    f = env['wsgi.input']
    fd = f.fileno()
    toread = uwsgi.cl()
    tmpf = None
    crc = 0
    if toread < RSIZE:
        data = f.read()
        crc = crc32(data, crc)
        buf = StringIO(data)
    else:
        buf = StringIO()
        sz = 0
        tmpname = volume.tmpname()
        while toread > 0:
            yield uwsgi.wait_fd_read(fd, 30)
            data = f.read(min(toread, RSIZE))
            rbytes = len(data)
            toread -= rbytes
            sz += rbytes
            crc = crc32(data, crc)
            buf.write(data)
            if sz > WSIZE:
                if not tmpf:
                    tmpf = open(tmpname, 'wb')
                tmpf.write(buf.getvalue())
                buf = StringIO()
                sz = 0

    if tmpf:
        if sz:
            tmpf.write(buf.getvalue())
        tmpf.close()
        fobj = tmpname
    else:
        buf.seek(0)
        fobj = buf

    meta = {'crc': crc & 0xffffffff}
    if 'CONTENT_TYPE' in env:
        meta['ct'] = env['CONTENT_TYPE']

    volume.put(collection, key, fobj, meta)

    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield 'Ok'
Ejemplo n.º 12
0
def send_request(env, client):

    uwsgi.send(client, b"GET /intl/it_it/images/logo.gif HTTP/1.0\r\n")

    # test for suspend/resume
    uwsgi.suspend()

    uwsgi.send(client, b"Host: www.google.it\r\n\r\n")

    while 1:
        yield uwsgi.wait_fd_read(client, 2)
        if env['x-wsgiorg.fdevent.timeout']:
            return

        buf = uwsgi.recv(client, 4096)
        if buf:
            yield buf
        else:
            break
Ejemplo n.º 13
0
def send_request(env, client):

    uwsgi.send(client, b"GET /intl/it_it/images/logo.gif HTTP/1.0\r\n")

    # test for suspend/resume
    uwsgi.suspend()

    uwsgi.send(client, b"Host: www.google.it\r\n\r\n")

    while 1:
        yield uwsgi.wait_fd_read(client, 2)
        if env['x-wsgiorg.fdevent.timeout']:
            return

        buf = uwsgi.recv(client, 4096)
        if buf:
            yield buf
        else:
            break
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
        lib.async_add_timeout(wsgi_req, timeout);
uwsgi.async_sleep = uwsgi_pypy_async_sleep

"""
uwsgi.async_connect(addr)
"""
def uwsgi_pypy_async_connect(addr):
    fd = lib.uwsgi_connect(ffi.new('char[]', addr), 0, 1)
    if fd < 0:
        raise Exception("unable to connect to %s" % addr)
    return fd
uwsgi.async_connect = uwsgi_pypy_async_connect

uwsgi.connection_fd = lambda: uwsgi_pypy_current_wsgi_req().fd

"""
uwsgi.wait_fd_read(fd, timeout=0)
"""
def uwsgi_pypy_wait_fd_read(fd, timeout=0):
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    if lib.async_add_fd_read(wsgi_req, fd, timeout) < 0:
        raise Exception("unable to add fd %d to the event queue" % fd)
uwsgi.wait_fd_read = uwsgi_pypy_wait_fd_read

"""
uwsgi.wait_fd_write(fd, timeout=0)
"""
def uwsgi_pypy_wait_fd_write(fd, timeout=0):
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    if lib.async_add_fd_write(wsgi_req, fd, timeout) < 0:
        raise Exception("unable to add fd %d to the event queue" % fd)
Ejemplo n.º 16
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)
Ejemplo n.º 17
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 []
Ejemplo n.º 18
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
Ejemplo n.º 19
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 []
Ejemplo n.º 20
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 []
Ejemplo n.º 21
0
 def wait(self):
     uwsgi.wait_fd_read(self.fdr, 10)
Ejemplo n.º 22
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 []
Ejemplo n.º 23
0
        lib.async_add_timeout(wsgi_req, timeout);
uwsgi.async_sleep = uwsgi_pypy_async_sleep

"""
uwsgi.async_connect(addr)
"""
def uwsgi_pypy_async_connect(addr):
    fd = lib.uwsgi_connect(ffi.new('char[]', addr), 0, 1)
    if fd < 0:
        raise Exception("unable to connect to %s" % addr)
    return fd
uwsgi.async_connect = uwsgi_pypy_async_connect

uwsgi.connection_fd = lambda: uwsgi_pypy_current_wsgi_req().fd

"""
uwsgi.wait_fd_read(fd, timeout=0)
"""
def uwsgi_pypy_wait_fd_read(fd, timeout=0):
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    if lib.async_add_fd_read(wsgi_req, fd, timeout) < 0:
        raise Exception("unable to add fd %d to the event queue" % fd)
uwsgi.wait_fd_read = uwsgi_pypy_wait_fd_read

"""
uwsgi.wait_fd_write(fd, timeout=0)
"""
def uwsgi_pypy_wait_fd_write(fd, timeout=0):
    wsgi_req = uwsgi_pypy_current_wsgi_req();
    if lib.async_add_fd_write(wsgi_req, fd, timeout) < 0:
        raise Exception("unable to add fd %d to the event queue" % fd)
Ejemplo n.º 24
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 []
 def raw_recv(self):
     import uwsgi
     uwsgi.wait_fd_read(self.fd)
     uwsgi.suspend()
     return uwsgi.recv(self.fd, self.bufsize)
Ejemplo n.º 26
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)
Ejemplo n.º 27
0
	def recv(self, bufsize):
		if not self.closed:
			uwsgi.wait_fd_read(self.fileno(), -1)
			uwsgi.suspend()
		if not self.closed:
			return uwsgi.recv(self.fileno(), bufsize)
Ejemplo n.º 28
0
 def raw_recv(self):
     import uwsgi
     uwsgi.wait_fd_read(self.fd)
     uwsgi.suspend()
     return uwsgi.recv(self.fd, self.bufsize)
Ejemplo n.º 29
0
def application(env, start_response):

    # open the socket
    fd = uwsgi.async_connect("192.168.173.100:3032")

    # wait for connection ready (3s timeout)
    yield uwsgi.wait_fd_write(fd, 3)

    # has timed out ?
    if env['x-wsgiorg.fdevent.timeout']:
        print "connection timed out !!!"
        uwsgi.close(fd)
        raise StopIteration

    # connection refused ?
    if not uwsgi.is_connected(fd):
        print "unable to connect"
        uwsgi.close(fd)
        raise StopIteration

    # send request
    # env can contains python objects, but send_message will discard them.
    # In this way we will automagically have a congruent and valid uwsgi packet
    uwsgi.async_send_message(fd, 0, 0, env)

    # send the http body
    # ready body in async mode and resend to fd
    # uwsgi.recv will use always an internal buffer of 4096, but can be limited in the number of bytes to read

    # does this request has a body ?
    cl = uwsgi.cl()

    if cl > 0:
        # get the input fd
        input = env['wsgi.input'].fileno()

        # read (in async mode) upto 'cl' data and send to uwsgi peer
        while cl > 0:
            bufsize = min(cl, 4096)
            yield uwsgi.wait_fd_read(input, 30)
            if env['x-wsgiorg.fdevent.timeout']:
                print "connection timed out !!!"
                uwsgi.close(fd)
                raise StopIteration
            body = uwsgi.recv(input, bufsize)
            if body:
                uwsgi.send(fd, body)
                cl = cl - len(body)
            else:
                break

    # wait for response (30s timeout)
    yield uwsgi.wait_fd_read(fd, 30)

    # has timed out ?
    if env['x-wsgiorg.fdevent.timeout']:
        print "connection timed out !!!"
        uwsgi.close(fd)
        raise StopIteration

    data = uwsgi.recv(fd)
    # recv the data, if it returns None the callable will end
    while data:
        yield data
        # wait for response
        yield uwsgi.wait_fd_read(fd, 30)
        if env['x-wsgiorg.fdevent.timeout']:
            print "connection timed out !!!"
            uwsgi.close(fd)
            raise StopIteration
        data = uwsgi.recv(fd)

    uwsgi.close(fd)
Ejemplo n.º 30
0
 def recv(self, bufsize):
     if not self.closed:
         uwsgi.wait_fd_read(self.fileno(), -1)
         uwsgi.suspend()
     if not self.closed:
         return uwsgi.recv(self.fileno(), bufsize)