mrjoes / sockjs-tornado Goto Github PK
View Code? Open in Web Editor NEWWebSocket emulation - Python server
License: MIT License
WebSocket emulation - Python server
License: MIT License
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
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
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.
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.
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?
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
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?
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.
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.
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!
Hi, you have a note here https://github.com/mrjoes/sockjs-tornado/blob/master/sockjs/tornado/static.py#L48. It seems that it is ok to use del in such situation, for response with code 302.
Tornado developers are doing absolutely the same way. See https://github.com/facebook/tornado/blob/master/tornado/web.py#L1304. May be just reuse their methods to be fully consistent.
self._clear_headers_for_304()
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
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
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?
SockJS is closed when I am using window.onbeforeunload although I clicked "stay on the page".
Thank you.
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.
Hi, @mrjoes. Now I am working on a game available by servicestargame.com. The main challenge is to find right scale solution. Could you please read the following question and recommend something:
http://stackoverflow.com/questions/18802820/distributed-game-server-using-tornado
Thank you in advance.
Hi,
I was playing with sockjs-tornado today and found call to iteritems, which is not available in python 3:
sockjs-tornado/sockjs/tornado/stats.py
Line 95 in b46d3cd
Bastian
Their change is here - Remove the remaining traces of tornado.util.b - tornadoweb/tornado@9253026
If you remove the import b from sockjs/tornado/websocket.py and add the following it works again.
if type('') is not type(b''):
def b(s):
return s.encode('latin1')
else:
def b(s):
return s
Is sockjs-tornado compatible with sock-js 1.0.0? Last sock-js version v1.0.0-beta.12 is from Feb 2015.
Especially the heartbeats since 0.4.0 are interesting: https://github.com/sockjs/sockjs-protocol/wiki/Heartbeats-and-SockJS
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.
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.
As described here:
http://stackoverflow.com/a/13512110/496285
The Second: https://github.com/mrjoes/sockjs-tornado/blob/master/sockjs/tornado/conn.py#L28-L31
But I don't know how pass some data to request.argument...
And I just tried... But failed.
conn = new SockJS('http://chatsocial.me/chat?argu=some');
What should I do?
I have a tricky and interesting question to You by the following link http://stackoverflow.com/questions/19025218/coroutine-based-state-machines
XMLHttpRequest cannot load http://localhost:8080/com/eyJhbGciOiJIUzI1NiJ9.eyJ0IjoxMzkzNzUzMzQ4MzUwLCJjโฆFubmVsIjoid2ViY2FzdC0xIn0.ECAkgOfM5D3hNXlvCayI-4ovLQGrnOrC16FSmlK7-FE/info.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
i just came to this question.
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?
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')
hi i have a app written with flask, i am finding a way to make sockjs-tornado work with flask, i see this https://gist.github.com/xianyunwuxin/1441063. i want to know if that is a good way to do this.
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?
Can SockJS-tornado be used as a client on the server-side?
I have an external SockJS and I want to connect to it as client from the server-side.
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()
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.
Tornado 4 was just released. Anyone tried to use it with Sockjs-tornado? Any anticipated problems?
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.
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.
Hi !
As stated as TODO in https://github.com/mrjoes/sockjs-tornado/blob/master/sockjs/tornado/proto.py#L12, ujson support would be great for performances !
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
New sockjs released today , so i am going to test with sockjs-tornado not sure this is compatible or no.
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:
thanks again,
Stefano
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.
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
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
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
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?
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
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.
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()
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?
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.