Code Monkey home page Code Monkey logo

sockjs-tornado's People

Contributors

benoitc avatar cablehead avatar chengfred avatar davbo avatar dobrite avatar esseks avatar fzambia avatar gholms avatar hiestaa avatar humka avatar justinrosenthal avatar kachayev avatar majek avatar maparent avatar mathben avatar mdennebaum avatar melevine avatar mrjoes avatar novoselt avatar pahaz avatar pyalex avatar reclosedev avatar rweeks avatar skinkie avatar specialunderwear avatar thebaron88 avatar timdawborn avatar tomassedovic avatar vane avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sockjs-tornado's Issues

Keep-Alive with Apache mod_proxy timesout in reverse-proxy mode

The keep-alive option does not seem to work in my setup with apache's mod_proxy. Apache is configured in reverse proxy mode and keepalive has been set to "On". However, the keep-alive timesout and the clients have to reconnect. This is using xhr* based transports.

Can you please point out what I am missing?

Active connections time out while shipping bulk data

The transport send_pack() implementations detach from the session before data transmission is complete. (They either don't use RequestHandler.flush(), or don't request a callback.) When the pack takes a long time to transfer, the SessionContainer can then expire the session while the client is still receiving. The client finishes receiving, tries to open the next connection, fails, and reports "Server lost session".

This occurs reliably with XhrPollingTransport and a multi-megabyte pack. It may also affect streaming transports when they hit the amount_limit, but I haven't tested this.

WARNING:root:Write error on 11: [Errno 32] Broken pipe

Hi and thanks for the very good software.
I'm here because lately I'm experiencing a strange problem with you lib (v0.0.5) and Python 2.7.
It took me about a day to understand and reproduce it but now I've written a PoC demostrating the little bug.

In few words: I've a software that acts something like a proxy: it receives data from the browser and sends them to a server and viceversa. Yesterday I noticed that in some condition I get strange errors from Chrome (22.0.1229.94):
-[
Compressed bit must be 0 if no negotiated deflate-frame extension;
One or more reserved bits are on: reserved2 = 1, reserved3 = 1;
...
]-

IMHO the problem is that sockjs-tornado isn't thread-safe!
In fact I use a thread to send data from the target server to the browser.

This is the PoC:

# coding=utf-8
from tornado import web
import tornado.ioloop
import sockjs.tornado
import threading

# print the module name
print sockjs.tornado


class messageHandler(threading.Thread):
    def __init__(self, ws_conn):
        self.ws_conn = ws_conn
        threading.Thread.__init__(self)

    def run(self):

        print '   - Thread started!'

        try:


            print ' sending flood.......'

            txt = ('01020304050607080910111213' * 5000 + '\n') * 1000
            for x in txt.split("\n"):
                self.ws_conn.send( x.decode("hex").decode("latin-1") )

            print 'sent'


        except Exception, why:
            print why



class ProxerConnection(sockjs.tornado.SockJSConnection):

    def on_open(self, info):
        self._stage = 0

    def on_message(self, message):
        if self._stage == 0:
            # load a thread
            self._stage = 1
            print ' + Starting Thread...'
            self.thread = messageHandler(self)
            self.thread.setDaemon(True)
            self.thread.start()

        print message


if __name__ == "__main__":
    #1. Create router (set the path for sockjs-client)
    gatewayRouter = sockjs.tornado.SockJSRouter(ProxerConnection, '/gateway', user_settings={'sockjs_url':'/gateway/sockjs-0.3.min.js'})

    import logging
    logging.getLogger().setLevel(logging.DEBUG)

    #2. Create Tornado application (router + sockjs-client)
    app = tornado.web.Application(
            gatewayRouter.urls
    )

    #3. Make Tornado app listen on port 8001
    app.listen( 8001 )

    #4. Start IOLoop
    tornado.ioloop.IOLoop.instance().start()

This is what I get when the thread starts the flood:

<module 'sockjs.tornado' from '/usr/lib/python2.7/site-packages/sockjs_tornado-0.0.5-py2.7.egg/sockjs/tornado/__init__.pyc'>

INFO:root:200 GET /gateway/info (192.168.1.247) 0.86ms
 + Starting Thread...
   - Thread started!
  sending flood......

WARNING:root:Write error on 11: [Errno 32] Broken pipe
sent

Client-side:
-[
Compressed bit must be 0 if no negotiated deflate-frame extension
]-

To test it you should:

  • start the server
  • connect to the server and send a message
    now the server will start the thread and the flood begins.
    In few seconds you should get some error from chrome (and maybe also with FF). sometimes everything works well. (this also let me think that the problem is something with the thread).
    Moreover if I put the flood directly in the "on_message" event I don't have problems.

thanks again,
Stefano

multiplex example

First off, loving sockjs-tornado! Migrated over from your tornadio2 proj and really liking it.

Hopefully simple question... Noticed the multiplex example is gone in the dev branch. Is that in lieu of a better approach moving forward or something you just figure people should roll their own on? Multiplexing is important for us and I just want to make sure we are making decisions that are in line with suggested best practices.

how to use nginx proxy sockjs-tornado

how to use nginx proxy sockjs-tornado
WebSocket connection to 'ws://192.168.122.141/tornado/sockjs/215/dm1kkghf/websocket' failed: Error during WebSocket handshake: Unexpected response code: 502

sockjs-tornado 0.0.3 pip install fails. README.rst missing

pip install sockjs-tornado fails for version 0.0.3.

      File "/home/dave/.virtualenvs/sockjs3/build/sockjs-tornado/setup.py", line 18, in read
        return open(os.path.join(os.path.dirname(__file__), fname)).read()
    IOError: [Errno 2] No such file or directory: '/home/dave/.virtualenvs/sockjs3/build/sockjs-tornado/README.rst'

The zip package hosted on pypi does not contain the 'README.rst ' file as specified in setup.py

Support for other keyword arguments than session_id in URL

Hello,

I think it would be nice to be able to support other URL arguments. For example we could use it like this:

SockJSRouter(IMHOConnection, r'/game/(?P<obj_id>[^/.]+))

and then in IMHOConnection:

self.session.handler.kwargs.get('obj_id')

New release of sockjs-tornado

I noticed that the latest - and only - release of sockjs-tornado is v1.0.0 and it's from more than 2 years ago (April 3rd, 2013).

In the mean time there seems to have been lots of commits and pull requests merged.

I looked for information online but could not understand why no new release has been cut. Is there another place I should look at for stable releases of Tornado or should I just use the latest code on Master?

exception thrown for xhr-streaming protocol

I'm receiving the following errors in sockjs-tornado log, and it seems like (from the highlighted blocks) that @asynchrounous decorator is needed on on_message() method? However, I am not making any asynchronous calls in on_message() at all.

Additional details: this actually happened on the latest Chrome browser, which should have used websocket to connect, but failed, then switched to use xhr-streaming. This failure of using native websocket has happened a few times, but not often. I am not sure if this has anything to do with the error below. Also, sockjs-tornado instance is running behind HAProxy 1.5-dev17.

ERROR:root:XHR incoming
Traceback (most recent call last):
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/transports/xhr.py", line 85, in post
session.on_messages(messages)
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/session.py", line 426, in on_messages
self.conn.on_message(msg)
File "chat_server.py", line 996, in on_message
self.register(msg['id'], msg['msg'])
File "chat_server.py", line 650, in register
self.send(setup_msg)
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/conn.py", line 49, in send
self.session.send_message(message, binary=binary)
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/session.py", line 324, in send_message
self.send_jsonified(proto.json_encode(msg), stats)
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/session.py", line 342, in send_jsonified
self.handler.send_pack('a[%s]' % msg)
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/transports/xhrstreaming.py", line 40, in send_pack
self.write(message + '\n')
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/tornado/web.py", line 489, in write
raise RuntimeError("Cannot write() after finish(). May be caused "
RuntimeError: Cannot write() after finish(). May be caused by using async operations without the @asynchronous decorator.

ERROR:root:Uncaught exception POST /sockjs/365/y2jr5vz6/xhr_send (127.0.0.1)
HTTPRequest(protocol='http', host='www.mysite.com', method='POST', uri='/sockjs/365/y2jr5vz6/xhr_send', version='HTTP/1.1', remote_ip='127.0.0.1', body='["{"id":"3f4c54be769e1163","msg":"blahblah"}"]', headers={'Origin': 'https://www.mysite.com', 'Content-Length': '118', 'Accept-Language': 'en-US,en;q=0.8', 'Accept-Encoding': 'gzip,deflate,sdch', 'X-Forwarded-For': '127.0.0.1', 'Host': 'www.mysite.com', 'Accept': '
/
', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,;q=0.3', 'Connection': 'close', 'X-Forwarded-Proto': 'https', 'Referer': 'https://www.mysite.com/chat/3f4c54be769e1163', 'Content-Type': 'application/xml'})
Traceback (most recent call last):
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/tornado/web.py", line 1042, in _execute
getattr(self, self.request.method.lower())(_args, __kwargs)
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/transports/xhr.py", line 88, in post
session.close()
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/session.py", line 385, in close
self.handler.send_pack(proto.disconnect(code, message))
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/sockjs/tornado/transports/xhrstreaming.py", line 40, in send_pack
self.write(message + '\n')
File "/home/cilia/envs/.virtualenvs/chat/local/lib/python2.7/site-packages/tornado/web.py", line 489, in write
_raise RuntimeError("Cannot write() after finish(). May be caused "
RuntimeError: Cannot write() after finish(). May be caused by using async operations without the @asynchronous decorator.
*
ERROR:root:500 POST /sockjs/365/y2jr5vz6/xhr_send (127.0.0.1) 2.04ms
INFO:root:200 POST /sockjs/365/y2jr5vz6/xhr_streaming (127.0.0.1) 0.59ms

Unexpected disconnections - How to determine who terminated?

Hi again,

We have a large number of unexpected disconnections. The on_close method only receives the session. Is there any way of using the on_close method to figure out who initiated the close? Whether the client or server.

Cheers

aychedee

"Incompatibile SockJS!" in opera

SockJS not work in Opera 11.62.
In console display error: "Incompatibile SockJS! Main site uses: "0.2.1", the iframe: "0.1.2"."
Downgrading version of sockjs-client to 0.1.2 not help.

Error when using multiplex.py in the multiplex example

I am having this error when self.send(msg) is called from server side.

File "/path/to/my/sockjs_server.py", line 11, in on_message
self.send(msg)
File "/path/to/my/python/lib/python2.7/site-packages/sockjs/tornado/conn.py", line 49, in send
self.session.send_message(message, binary=binary)
TypeError: send_message() got an unexpected keyword argument 'binary'

I got it to work by changing the example multiplex.py
def send_message(self, msg, binary=False): <-- I added binary=False in the argument list.
self.base.send('msg,' + self.name + ',' + msg, binary)

Is this a bug? Or am I doing anything wrong?

Thanks,
Leo

Path matcher for websocket endpoint

If I set the prefix to r'/ws/([A-Za-z0-9\-\_]+)/?', it complains that the regex groups need to be named.

If I name the group, e.g. r'/ws/(?P<mynamedgroup>[A-Za-z0-9\-\_]+)/?', it complains with TypeError: get() got an unexpected keyword argument 'mynamedgroup'.

How do I go about getting the path component in on_open? I was able to get it in vanilla Tornado.

I'm bridging pika, and the matched path component relates to a routing key.

Socket errors when using WSS

Hello, We just switched over from using socket.io and tornadio2 to using sockjs-tornado. Thanks for the recommendation btw. There are lots of performance improvements.

We've been running it through our integration for a few days now and are seeing these in our logs. They look very similar to the things we were seeing in socket.io. These are four separate tracebacks from two incidents. They only happen when we use WSS. We are seeing about 10 such incidents during a five hour integration run. Any ideas?

2012-05-15 00:59:18,052 WARNING:Write error on 191: [Errno 14] Bad address
2012-05-15 00:59:18,054 ERROR:Error in periodic callback
Traceback (most recent call last):
   File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/periodic.py", line 68, in _run
     next_call = self.callback()
   File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/session.py", line 396, in _heartbeat
     self.handler.send_pack(proto.HEARTBEAT)
   File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/transports/websocket.py", line 83, in send_pack
     self.write_message(message)
   File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 169, in write_message
     self.ws_connection.write_message(message, binary=binary)
   File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 577, in write_message
     self._write_frame(True, opcode, message)
   File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 567, in _write_frame
     self.stream.write(frame)
   File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 219, in write
     self._handle_write()
   File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 647, in _handle_write
     super(SSLIOStream, self)._handle_write()
   File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 518, in _handle_write
     self.socket.fileno(), e)
 AttributeError: 'NoneType' object has no attribute 'fileno'


2012-05-15 00:59:18,223 ERROR:Uncaught exception, closing connection.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 304, in wrapper
    callback(*args)
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 661, in _on_frame_data
    self._receive_frame()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 580, in _receive_frame
    self.stream.read_bytes(2, self._on_frame_start)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 180, in read_bytes
    self._check_closed()
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 535, in _check_closed
    raise IOError("Stream is closed")
IOError: Stream is closed
2012-05-15 00:59:18,224 ERROR:Exception in callback <tornado.stack_context._StackContextWrapper object at 0xfc9f70>
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/ioloop.py", line 399, in _run_callback
    callback()
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 304, in wrapper
    callback(*args)
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 661, in _on_frame_data
    self._receive_frame()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 580, in _receive_frame
    self.stream.read_bytes(2, self._on_frame_start)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 180, in read_bytes
    self._check_closed()
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 535, in _check_closed
    raise IOError("Stream is closed")
IOError: Stream is closed

Second incident

2012-05-15 01:03:53,559 WARNING:Write error on 3: [Errno 32] Broken pipe
2012-05-15 01:03:53,560 ERROR:Uncaught exception in /sj/333/sjodg8q4/websocket
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 297, in wrapper
    return callback(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/transports/websocket.py", line 29, in open
    self.stream.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
AttributeError: 'NoneType' object has no attribute 'setsockopt'
2012-05-15 01:03:53,561 ERROR:Uncaught exception, closing connection.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 304, in wrapper
    callback(*args)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/httpserver.py", line 250, in _on_headers
    self.request_callback(self._request)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 1362, in __call__
    handler._execute(transforms, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 145, in _execute
    self.ws_connection.accept_connection()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 509, in accept_connection
    self._accept_connection()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 551, in _accept_connection
    self._receive_frame()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 580, in _receive_frame
    self.stream.read_bytes(2, self._on_frame_start)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 180, in read_bytes
    self._check_closed()
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 535, in _check_closed
    raise IOError("Stream is closed")
IOError: Stream is closed
2012-05-15 01:03:53,563 ERROR:Exception in callback <tornado.stack_context._StackContextWrapper object at 0x1e018e8>
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/ioloop.py", line 399, in _run_callback
    callback()
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 304, in wrapper
    callback(*args)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/httpserver.py", line 250, in _on_headers
    self.request_callback(self._request)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/web.py", line 1362, in __call__
    handler._execute(transforms, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 145, in _execute
    self.ws_connection.accept_connection()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 509, in accept_connection
    self._accept_connection()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 551, in _accept_connection
    self._receive_frame()
  File "/usr/local/lib/python2.7/site-packages/sockjs_tornado-0.0.4-py2.7.egg/sockjs/tornado/websocket.py", line 580, in _receive_frame
    self.stream.read_bytes(2, self._on_frame_start)
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 180, in read_bytes
    self._check_closed()
  File "/usr/local/lib/python2.7/site-packages/tornado-2.2.1-py2.7.egg/tornado/iostream.py", line 535, in _check_closed
    raise IOError("Stream is closed")
IOError: Stream is closed
2012-05-15 01:03:53,569 DEBUG:Ignoring IOError in safe_finish()

Subclassing sockjs.tornado.transports.WebSocketTransport give 502 error (failure in handshake)

I want to implement on_close event when the heartbeat finds some problem and I don't want to tinker with the library since it will create problems during upgrading. Am trying to implement the heartbeat in the SockJSConnection subclass itself.

I tried subclassing SockJSRouter alongwith Session to set start_hearbeat = False in set_handler(). It gave me Cross-domain origin error.

So I tried subclassing WebSocketTransport so that I can call set_handler() with heartbeat_start = False and replaced the websocket url during startup. But it started giving me 502 error as mentioned.

Help me out please.

Debug mode not working in Django environment

I try to use Tornado with sockjs-tornado in Django environment. In my project Tornado work as Websocket server together with Django in classic Django application.

From client I send session cookie to server and in Tornado get Django user:

from sockjs.tornado import SockJSConnection
from django.utils.importlib import import_module
from django.contrib.auth import get_user
from django.conf import settings

session_engine = import_module(settings.SESSION_ENGINE)

class ChatConnection(SockJSConnection):
    def get_session(self, session_key):
        return session_engine.SessionStore(session_key)

    def get_user(self, session):
        class Dummy(object):
            pass
        django_request = Dummy()
        django_request.session = session

        return get_user(django_request)

    def auth(self, session_id):
        self.django_session = self.get_session(session_id)
        self.user = self.get_user(self.django_session)

    def on_message(self, msg):
        msg = json.loads(msg)

        if msg['event'] == 'auth':
            self.auth(msg['content'])

For run Tornado app in Django environment I use simple management command:

class Command(NoArgsCommand):
    args = ''
    help = 'Run tornado.'

    def handle_noargs(self, **options):
        app = Application(AppRouter.urls, **app_settings)

        app.listen(8880)
        tornado.ioloop.IOLoop.instance().start()

The problem is that in Django environment errors not raised, and Tornado just close connection instead of raise exception. For example, if I write assert False in on_message method, that it will not have any effect other than closed connection. In the app settings debug mode enabled:

app_settings = {
    'debug': True,
}

Out of Django environment all work fine and I see in the shell excited exception.

Django 1.6.8
Tornado 4.0.2
sockjs-tornado 1.0.1

AttributeError: 'NoneType' object has no attribute 'session'

Traceback (most recent call last):
File "build/bdist.linux-i686/egg/sockjs/tornado/transports/xhr.py", line 81, in post
session.on_messages(messages)
File "build/bdist.linux-i686/egg/sockjs/tornado/session.py", line 409, in on_messages
self.conn.on_message(msg)
File "main.py", line 65, in on_message
self.room.send(message,room_id,self)
File "/home/chandler/socketio/rooms.py", line 18, in send
conn.broadcast(room,message)
File "build/bdist.linux-i686/egg/sockjs/tornado/conn.py", line 62, in broadcast
self.session.broadcast(clients, message)
File "build/bdist.linux-i686/egg/sockjs/tornado/session.py", line 190, in broadcast
self.server.broadcast(clients, msg)
File "build/bdist.linux-i686/egg/sockjs/tornado/router.py", line 194, in broadcast
sess = c.session
AttributeError: 'NoneType' object has no attribute 'session'

What could happen? I do not know where to look for bugs in the code, because this error is not often.
This happens, when I want to send a message from server-side

sockjs-tornado returns 500 for jsonp

I'm sure you're already aware of the issue. If not, here is a request and reply. Btw, origin:null is strange :)
Request:

POST /sockjs/039/o2u4vkfc/jsonp_send?i=atngkvajf HTTP/1.1
Host: develop.tawlk.com
Connection: keep-alive
Content-Length: 278
Cache-Control: max-age=0
Origin: null
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __utma=75050391.1293773682.1324090164.1324090164.1324090164.1; __utmz=75050391.1324090164.1.1.utmcsr=t.co|utmccn=(referral)|utmcmd=referral|utmcct=/ht8UNavd; JSESSIONID=dummy

d=%5B%22%7B%5C%22type%5C%22%3A%5C%22debug%5C%22%2C%5C%22text%5C%22%3A%5C%22Testing+echo%5C%22%2C%5C%22user_agent%5C%22%3A%5C%22Mozilla%2F5.0+%28Macintosh%3B+Intel+Mac+OS+X+10_7_2%29+AppleWebKit%2F535.7+%28KHTML%2C+like+Gecko%29+Chrome%2F16.0.912.63+Safari%2F535.7%5C%22%7D%22%5D

Reply:

HTTP/1.1 500 Internal Server Error
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Server: TornadoServer/2.1.1

BTW, there is haproxy with a config similar to this in front, there may be some headers like X-Forwarded-For added.

Strange behaviour on second connect

I have strange situation. Simple pub/sub server with tornado-redis. On first connect, user recieves messages. After page refresh, user can't recieve anything.

I have added stats dump and see this:

{'packets_recv_ps': 0.1, 'packets_sent_ps': 0.1, 'transp_websocket': 1, 'connections_ps': 0.2, 'connections_active': 1, 'sessions_active': 1}
message! 4569
send message
session closed
{'packets_recv_ps': 0.1, 'packets_sent_ps': 0.1, 'transp_websocket': 1, 'connections_ps': 0.2, 'connections_active': 1, 'sessions_active': 1}

String "session closed" is in conn.py with

if not self.is_closed:

check.

So, stats saying that server has connection, but session in closed state.

My server code is pretty simple:

class SocksJSHandler(SockJSConnection):

    def on_open(self, request):
        settings = self.session.server.settings
        self.redis = tornadoredis.Client(connection_pool=settings['connection_pool'],
                                         host=settings['redis_host'],
                                         port=settings['redis_port'])
        self.redis.connect()

    def on_close(self):
        if self.redis.subscribed:
            self.redis.unsubscribe(str('pmessages:%s' % self.user_id))
        self.redis.disconnect()

    @tornado.gen.engine
    def on_message(self, json):
        try:
            message = simplejson.loads(json)
        except JSONDecodeError:
            self.send({
                'error': 'json parsing error'
            })
            return

        cmd = message['cmd']
        if self.user_id is None and cmd != 'auth':
            return

        if cmd == 'auth':
            user_id = message['uid']
            access_token = message['access_token']
            if user_id is None or access_token is None:
                self.send({
                    'error': 'access denied'
                })
                return

            request_hash = hashlib.md5("HASH:" + str(user_id)).hexdigest()

            if request_hash != access_token:
                self.send({
                    'error': 'access denied'
                })
                return
            else:
                self.user_id = user_id

            print "subscribe to pmessages:%s" % self.user_id
            yield tornado.gen.Task(self.redis.subscribe, [str('pmessages:%s' % self.user_id)])
            self.redis.listen(self.on_publish)

    def on_publish(self, message):
        if message.kind == 'message':
            print "message! %s" % message.body
            notification = self.pyredis.hgetall('notification:%s' % int(message.body))
            self.send({
                'cmd': 'message',
                'm': [notification]
            })

    def send(self, message, binary=False):
        message = simplejson.dumps(message)
        print "send message"
        super(SocksJSHandler, self).send(message, binary)

So, I just missing something or this is bug? Maybe after disconnect user has old handler?

Support for heartbeat?

It was claimed that the upcoming SockJS 0.4 will support heartbeat by default. Is there any plan for SockJS-Tornado to support heartbeat?

Just to confirm, for now, using SockJS 0.3.2, we need to implement our own heartbeat mechanism at the application layer?

SockJS websockets ignore empty messages

WebSocket connections drop empty messages. Is there a reason for this? I have a use case with a cookie-based handshake, where the webpage send the cookie as the first message. In the simplest case the cookie is initially empty, which results in no event firing server-side, and mucking things up in a way regular WebSockets handle just fine.

SockJS 0.2? Or 0.1 full compliance?

With SockJS 0.2 release, will sockjs-tornado support it any time soon?

I found that you didnt include any examples for testing sockjs protocol.
I created my own script using sockjs and well, test is failing in some cases. It would be great to see it all green ;)
#0.1 full results

test_greeting (main.BaseUrlGreeting) ... ok
test_notFound (main.BaseUrlGreeting) ... ok
test_basic (main.ChunkingTest) ... ok
test_options (main.ChunkingTest) ... ok
test_transport (main.EventSource) ... ok
test_no_callback (main.HtmlFile) ... ok
test_transport (main.HtmlFile) ... ok
test_cacheability (main.IframePage) ... ok
test_invalidUrl (main.IframePage) ... ok
test_queriedUrl (main.IframePage) ... ok
test_simpleUrl (main.IframePage) ... ok
test_versionedUrl (main.IframePage) ... ok
test_content_types (main.JsonPolling) ... ok
test_invalid_json (main.JsonPolling) ... ok
test_no_callback (main.JsonPolling) ... ok
test_transport (main.JsonPolling) ... FAIL
test_closeSession (main.Protocol) ... ERROR
test_simpleSession (main.Protocol) ... ok
test_closeSession_another_connection (main.ProtocolQuirks) ... HANGS UP
test_anyValue (main.SessionURLs) ... ok
test_ignoringServerId (main.SessionURLs)
See Protocol.test_simpleSession for explanation. ... ok
test_invalidPaths (main.SessionURLs) ... ok
test_broken_json (main.WebsocketHixie76) ... ERROR
test_close (main.WebsocketHixie76) ... FAIL
test_empty_frame (main.WebsocketHixie76) ... ok
test_headersSanity (main.WebsocketHixie76) ... ok
test_reuseSessionId (main.WebsocketHixie76) ... ok
test_transport (main.WebsocketHixie76) ... ok
test_disabledTransport (main.WebsocketHttpErrors) ... ok
test_httpMethod (main.WebsocketHttpErrors) ... ok
test_invalidConnectionHeader (main.WebsocketHttpErrors) ... ok
test_invalidMethod (main.WebsocketHttpErrors) ... ok
test_verifyOrigin (main.WebsocketHttpErrors) ... ok
test_broken_json (main.WebsocketHybi10) ... ok
test_close (main.WebsocketHybi10) ... ERROR
test_firefox_602_connection_header (main.WebsocketHybi10) ... ok
test_headersSanity (main.WebsocketHybi10) ... ok
test_transport (main.WebsocketHybi10) ... ok
test_content_types (main.XhrPolling) ... ok
test_invalid_json (main.XhrPolling) ... ok
test_invalid_session (main.XhrPolling) ... ok
test_jsessionid (main.XhrPolling) ... ok
test_options (main.XhrPolling) ... ok
test_transport (main.XhrPolling) ... FAIL
test_options (main.XhrStreaming) ... ok
test_transport (main.XhrStreaming) ... ok

Now 0.2

test_greeting (main.BaseUrlGreeting) ... ok
test_notFound (main.BaseUrlGreeting) ... ok
test_response_limit (main.EventSource) ... ok
test_transport (main.EventSource) ... ok
test_abort_xhr_polling (main.HandlingClose) ... ERROR
test_abort_xhr_streaming (main.HandlingClose) ... HANGS UP
test_close_frame (main.HandlingClose) ... HANGS UP
test_close_request (main.HandlingClose) ... ok
test_no_callback (main.HtmlFile) ... ok
test_response_limit (main.HtmlFile) ... ok
test_transport (main.HtmlFile) ... ok
test_cacheability (main.IframePage) ... ok
test_invalidUrl (main.IframePage) ... ok
test_queriedUrl (main.IframePage) ... ok
test_simpleUrl (main.IframePage) ... ok
test_versionedUrl (main.IframePage) ... ok
test_basic (main.InfoTest) ... FAIL
test_disabled_websocket (main.InfoTest) ... FAIL
test_entropy (main.InfoTest) ... ERROR
test_options (main.InfoTest) ... FAIL
test_xhr_server_decodes (main.JSONEncoding) ... ok
test_xhr_server_encodes (main.JSONEncoding) ... ok
test_content_types (main.JsonPolling) ... ok
test_invalid_json (main.JsonPolling) ... ok
test_no_callback (main.JsonPolling) ... ok
test_transport (main.JsonPolling) ... ok
test_closeSession (main.Protocol) ... ERROR
test_simpleSession (main.Protocol) ... ok
test_close (main.RawWebsocket) ... ERROR
test_transport (main.RawWebsocket) ... ERROR
test_anyValue (main.SessionURLs) ... ok
test_ignoringServerId (main.SessionURLs)
See Protocol.test_simpleSession for explanation. ... ok
test_invalidPaths (main.SessionURLs) ... ok
test_broken_json (main.WebsocketHixie76) ... ERROR
test_close (main.WebsocketHixie76) ... FAIL
test_empty_frame (main.WebsocketHixie76) ... ok
test_headersSanity (main.WebsocketHixie76) ... ok
test_reuseSessionId (main.WebsocketHixie76) ... ok
test_transport (main.WebsocketHixie76) ... ok
test_httpMethod (main.WebsocketHttpErrors) ... ok
test_invalidConnectionHeader (main.WebsocketHttpErrors) ... ok
test_invalidMethod (main.WebsocketHttpErrors) ... FAIL
test_verifyOrigin (main.WebsocketHttpErrors) ... ok
test_broken_json (main.WebsocketHybi10) ... ok
test_close (main.WebsocketHybi10) ... ERROR
test_firefox_602_connection_header (main.WebsocketHybi10) ... ok
test_headersSanity (main.WebsocketHybi10) ... ok
test_transport (main.WebsocketHybi10) ... ok
test_content_types (main.XhrPolling) ... ok
test_invalid_json (main.XhrPolling) ... ok
test_invalid_session (main.XhrPolling) ... ok
test_jsessionid (main.XhrPolling) ... ok
test_options (main.XhrPolling) ... ok
test_transport (main.XhrPolling) ... ok
test_options (main.XhrStreaming) ... ok
test_response_limit (main.XhrStreaming) ... FAIL
test_transport (main.XhrStreaming) ... ok

Analysis

some failures are common, what's interesting is that some tests are now fully working!

  • ProtocolQuirks.test_closeSession_another_connection - (present only in 0.1) no idea what's the issue here. It just won't die.
  • Protocol.test_closeSession - times out (not sure if this is an issue with my test script?)
  • WebsocketHixie76.test_broken_json - this one has some broken dependencies (module import error) on my machine (which most likely means - dependency changed a little) but even after fixing it, doesn't seem to work. Which may or may not be due to the fact, that dependency (https://github.com/liris/websocket-client/) behavior changed.
  • WebsocketHybi10.test_close - again close seems to be an issue
  • JsonPolling.test_transport - fails in 0.1, but WORKS fine in 0.2!
  • WebsocketHixie76.test_close - again with close. AssertionError: 'h' != u'c[3000,"Go away!"]'
  • XhrPolling.test_transport - fails in 0.1, but WORKS fine in 0.2!
  • HandlingClose.test_abort_xhr_polling - time out. Aborting, closing and stuff seems to be the main issue.
  • InfoTest.* - this one is new in 0.2, not implemented and should be part of the API.
  • Protocol.test_closeSession - time out.
  • RawWebsocket.* - this is something that cannot be implemented with current API (websocket without framing, heartbeats and stuff).
  • WebsocketHttpErrors.test_invalidMethod - for invalid methods it wants not only 405 but also something in 'allow' tag. Doesn't check what though, but anyway it is empty.
  • XhrStreaming.test_response_limit - it stopped working. Apparently, response_limit setting should not count needed by IE 2049 header ('h'*2048+'\n'). At least that's what node is using. Smells fishy.

Let's summarize this essay

So what is really not working?
Something's wrong with closing. RawWebsockets require implementation. New Info (/info) default endpoint as well.
Rest seems to be of low priority.

preforking does not work the usual way

Hello,
I tried to use the preforking feature of Tornado (using multiple processes on one port).
But a RuntimeError indicated that an IOLoop instance was already running.
Clearly the broadcast feature would not work without additional inter-process-communication but is preforking even possible with some of the transport types (besides websockets) ?

If have tested preforking by changing the following code:

diff --git a/examples/chat/chat.py b/examples/chat/chat.py
index c7756b3..facaae8 100644
--- a/examples/chat/chat.py
+++ b/examples/chat/chat.py
@@ -49,7 +49,13 @@ if __name__ == "__main__":
     )

     #3. Make Tornado app listen on port 8080
-    app.listen(8080)
+    #app.listen(8080)
+    
+    from tornado.httpserver import HTTPServer
+    server = HTTPServer(app)
+    server.bind(8888)
+    server.start(0) 
+    

     #4. Start IOLoop
     tornado.ioloop.IOLoop.instance().start()

passing additional data to handlers

hi, author of webalchemy here.

I want to integrate SockJS-Tornado with Webalchemy, and the first issue I encountered is that of passing additional data to SockJS handlers.

for e.g. in Tornado you do-

application = tornado.web.Application([
        (ws_route, WebSocketHandler, dict(local_doc_class=app,
                                          shared_wshandlers=shared_wshandlers,
                                          shared_data=shared_data,
                                          session_data_store=session_data_store,
                                          tab_data_store=tab_data_store,
                                          main_explicit_route=main_explicit_route,
                                          main_html=main_html)),
        (main_route, _MainHandler, dict(main_html=main_html)),
    ], static_path=static_path)

where the dicts at the last slot in the tuples are passed to the handlers when their initialize method is called.

I couldn't find an obvious way to do this with SockJS, so I'm thinking is this some desirable functionality, should I open a pull request for this? the other option of course is to monkeypatch SockJS-Tornado...

Thanks!

Expose origin header to ConnectionInfo object

There were added some headers to the info object in #20. The docstrings says something about the origin header, but the header is not included in the _exposed_headers list. But I would like to get it later in my on_open method. (Or can you tell me another smart way to check on which URL the client was when he established the connection?) Thank you very much.

Connections aren't informed when sessions expire

For non-websocket transports, when the client goes away, the session is expired in a timely manner, but the connection object is not informed (for example, on_close() is not called) so the application doesn't know that it can free the resources associated with that connection.

Tornado 4

Tornado 4 was just released. Anyone tried to use it with Sockjs-tornado? Any anticipated problems?

async exception

2013-04-13_03:47:51.01741 WARNING:tornado.general:Write error on 450: [Errno 104] Connection reset by peer
2013-04-13_03:47:51.01758 INFO:root:sockconnection: removing for disconnected clientid=none on_close() called
2013-04-13_03:47:51.01774 INFO:tornado.access:200 POST /sock/957/hk9et6ad/xhr?t=1365824870853 (66.60.145.16) 5.01ms
2013-04-13_03:47:51.01805 INFO:tornado.access:204 POST /sock/957/hk9et6ad/xhr_send?t=1365824870837 (66.60.145.16) 5.10ms
2013-04-13_03:47:51.01986 ERROR:tornado.application:Uncaught exception POST /sock/957/hk9et6ad/xhr?t=1365824870853 (66.60.145.16)
2013-04-13_03:47:51.01986 HTTPRequest(protocol='https',, method='POST', uri='/sock/957/hk9et6ad/xhr?t=1365824870853', version='HTTP/1.1', remote_ip='66.60.145.16', body='', headers={'Content-Length': '0',, 'Accept-Language': 'en-us', 'Accept-Encoding': 'gzip, deflate', 'X-Forwarded-For': '66.60.145.16', 'X-Imforwards': '20', 'Accept': '*/*', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0; chromeframe/26.0.1410.64; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; Tablet PC 2.0)', 'Connection': 'close', 'X-Forwarded-Proto': 'https', 'Referer': '/sock/iframe.html#gdcpc5_o', 'Ua-Cpu': 'AMD64', 'Cache-Control': 'no-cache', 'Cookie': 'JSESSIONID=dummy'})
013-04-13_00:12:07.86133 Traceback (most recent call last):
2013-04-13_00:12:07.86133   File "/libs/tornado/tornado/web.py", line 1043, in _stack_context_handle_exception
2013-04-13_00:12:07.86135     raise_exc_info((type, value, traceback))
2013-04-13_00:12:07.86136   File "/libs/tornado/tornado/stack_context.py", line 214, in wrapped
2013-04-13_00:12:07.86136     callback(*args, **kwargs)
2013-04-13_00:12:07.86137   File "/libs/tornado/tornado/httpserver.py", line 199, in _on_write_complete
2013-04-13_00:12:07.86138     callback()
2013-04-13_00:12:07.86138   File "/libs/tornado/tornado/stack_context.py", line 214, in wrapped
2013-04-13_00:12:07.86139     callback(*args, **kwargs)
2013-04-13_00:12:07.86140   File "/libs/sockjs-tornado/sockjs/tornado/transports/pollingbase.py", line 69, in send_complete
2013-04-13_00:12:07.86140     self.safe_finish()
2013-04-13_00:12:07.86141   File "/libs/sockjs-tornado/sockjs/tornado/basehandler.py", line 84, in safe_finish
2013-04-13_00:12:07.86142     self.finish()
2013-04-13_00:12:07.86142   File "/libs/sockjs-tornado/sockjs/tornado/basehandler.py", line 45, in finish
2013-04-13_00:12:07.86143     super(BaseHandler, self).finish()
2013-04-13_00:12:07.86144   File "/libs/tornado/tornado/web.py", line 701, in finish
2013-04-13_00:12:07.86145     raise RuntimeError("finish() called twice.  May be caused "
2013-04-13_00:12:07.86148 RuntimeError: finish() called twice.  May be caused by using async operations without the @asynchronous decorator.
2013-04-13_00:12:07.86160 ERROR:tornado.general:Cannot send error response after headers written

We occasionally get exceptions like the above, looks like the tornado.general:Write error happens, then on_close() gets called on the SockJSConnection immediately after, and then the finish() twice exception happens after that. Any ideas?

cannot read XHR polling request headers in on_open callback

I have a very simple connection handler that fails when I'm dealing with XHR polling connections. I cannot get to the request headers in the on_open callback. Here's the simple code I'm running in order to accept/reject connections based on a session id cookie.

class MySockJSConnection(SockJSConnection):
    def on_open(self):
        # for xhr polling connections, self.session.handler is None!
        # so there's no way to authenticate an xhr polling connection based on a cookie
        if not authentication.is_valid(self.session.handler.get_secure_cookie("SessionID")):
            # by the way, returning false does not reject the connection as advertised
            # you need to call self.session.close() instead... might be worth updating the docs
            self.session.close()
            return False
        # log about a new valid connection
        return True

Unless you have a better way to accept/reject connections based on SessionID cookies... I'm stumped and will have to create my own local fork to support this, which I'd really rather not do.

no on_close callback with tornado 3 and non-websocket transports

Hello!

I came across the problem - when I use any of transports except websocket there is no on_close callback fired when connection closed. This happens only when using sockjs-tornado with Tornado 3 (3.1 in my case). With Tornado 2.4.1 everything seems to work fine.

To reproduce chat example from this repository can be used. Just disable websocket transport, add $('#connect').trigger('click') to connect immediately on page ready and then reload page several times - on_close not fired and participants not cleaned up.

This can be Tornado issue - as on_connection_close not called.

Also I have another question - look at this code from sockjs-tornado source:

    def send_pack(self, message, binary=False):
        if binary:
            raise Exception('binary not supported for XhrStreamingTransport')

        self.active = False

        try:
            self.notify_sent(len(message))

            self.write(message + '\n')
            self.flush(callback=self.send_complete)
        except IOError:
            # If connection dropped, make sure we close offending session instead
            # of propagating error all way up.
            self.session.delayed_close()
            self._detach()

It seems to me that IOError never called in Tornado 3. If connection was closed then no exception fires while flushing and self.send_complete never called. I am confused a little here.

stomp-websocket over sockjs-tornado

For example, I can do something like this: stomp-websocket over sockjs-node

var Stomp = require('stompjs')
var SockJS = require('sockjs-client')
var client = Stomp.over(new SockJS('http://localhost:8081/stompendpoint'));

Using a compatible python stomp client like stompy or any other as seen at http://stomp.github.io/implementations.html, can we achieve, stomp-websocket over sockjs-tornado?

Current status and Tests

I see that this project has no tests only a test server.

From sockjs-twisted

SockJS-Twisted passes all SockJS-Protocol v0.3.3 tests, and all SockJS-Client qunit tests. It has been used in production environments, and should be free of any critical bugs.

What would be the status for this project? How can we make sure that sockjs-tornado passes all of SockJS-Protocol tests as well as SockJS-Client qunit tests? I could try implementing those qunit tests from sockjs-twisted and tweaking the server.py.

Expose x-forwarded-for headers

What are you thoughts on exposing some of the headers to the server. In my case I need to enable authentication if the X-Forward-Proto or X-Forward-For headers are present (meaning the connection has been forwarded by a proxy). Traffic not forwarded does not need authentication.

Similar requests were made for the sockjs-node implementation:

sockjs/sockjs-node#32
sockjs/sockjs-node#25

It looks like it might be best to add a headers dictionary to the session object and if needed only copy certain headers like here sockjs/sockjs-node@2274273

This could probably be added to sockjs.tornado.session.BaseSession.set_handler.

It would also be nice to have access to the request's path but I can submit another issue if that helps

Stats reporting does not decrement on .close() call

Start server as described in the gist:

https://gist.github.com/coulix/8179de3a36d7e208b0c2

Open demo.html
Navigate to localhost:8888/stats/
Refresh demo.html 3 times.

{"conn_active":3,"conn_ps":  {"accumulator":0,"last_average":0.0,"period":10,"stream":{"maxlen":null},"sum":0},"pack_recv_ps":{"accumulator":0,"last_average":0.0,"period":10,"stream":{"maxlen":null},"sum":0},"pack_sent_ps":{"accumulator":0,"last_average":0.0,"period":10,"stream":{"maxlen":null},"sum":0},"sess_active":0,"sess_transports":{"websocket":0}}

You will see "conn_active":3. I guess that is an error no?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.