The class * RequestHandler* (tornado 3.1.1) has e new function * _When_complete* that is called by the function *_execute*.
------------------------------------------------------vvvvv-------------------------------------------------------------- def _execute(self, transforms, *args, **kwargs): """Executes this request with the given output transforms.""" self._transforms = transforms try: if self.request.method not in self.SUPPORTED_METHODS: raise HTTPError(405) self.path_args = [self.decode_argument(arg) for arg in args] self.path_kwargs = dict((k, self.decode_argument(v, name=k)) for (k, v) in kwargs.items()) # If XSRF cookies are turned on, reject form submissions without # the proper cookie if self.request.method not in ("GET", "HEAD", "OPTIONS") and \ self.application.settings.get("xsrf_cookies"): self.check_xsrf_cookie() self._when_complete(self.prepare(), self._execute_method) except Exception as e: self._handle_request_exception(e) def _when_complete(self, result, callback): try: if result is None: callback() elif isinstance(result, Future): if result.done(): if result.result() is not None: raise ValueError('Expected None, got %r' % result) callback() else: # Delayed import of IOLoop because it's not available # on app engine from tornado.ioloop import IOLoop IOLoop.current().add_future( result, functools.partial(self._when_complete, callback=callback)) else: raise ValueError("Expected Future or None, got %r" % result) except Exception as e: self._handle_request_exception(e) ----------------------------------------------^^^^^ --------------------------------------------------------------------- I modified websocket_messaging (in red) and is now working with the tornado 3.1.1 (tonado 3.0 too), but do not know if you are having the exact result you had in previous versions. ------------------------------------------vvvvvvv-------------------------------------------------------------------- #!/usr/bin/env python """ This file is part of the web2py Web Framework Copyrighted by Massimo Di Pierro <mdipie...@cs.depaul.edu> License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) Attention: Requires Chrome or Safari. For IE of Firefox you need https://github.com/gimite/web-socket-js 1) install tornado (*r**equires Tornado 3.0 or late*r) easy_install tornado 2) start this app: python gluon/contrib/websocket_messaging.py -k mykey -p 8888 3) from any web2py app you can post messages with from gluon.contrib.websocket_messaging import websocket_send websocket_send('http://127.0.0.1:8888','Hello World','mykey','mygroup') 4) from any template you can receive them with <script> $(document).ready(function(){ if(!*$.web2py.*web2py_websocket('ws://127.0.0.1:8888/realtime/mygroup ',function(e){alert(e.data)})) alert("html5 websocket not supported by your browser, try Google Chrome"); }); </script> When the server posts a message, all clients connected to the page will popup an alert message Or if you want to send json messages and store evaluated json in a var called data: <script> $(document).ready(function(){ var data; *$.web2py*.web2py_websocket('ws://127.0.0.1:8888/realtime/mygroup ',function(e){data=eval('('+e.data+')')}); }); </script> - All communications between web2py and websocket_messaging will be digitally signed with hmac. - All validation is handled on the web2py side and there is no need to modify websocket_messaging.py - Multiple web2py instances can talk with one or more websocket_messaging servers. - "ws://127.0.0.1:8888/realtime/" must be contain the IP of the websocket_messaging server. - Via group='mygroup' name you can support multiple groups of clients (think of many chat-rooms) Here is a complete sample web2py action: def index(): form=LOAD('default','ajax_form',ajax=True) script=SCRIPT(''' jQuery(document).ready(function(){ var callback=function(e){alert(e.data)}; if(!*$.web2py.*web2py_websocket('ws:// 127.0.0.1:8888/realtime/mygroup',callback)) alert("html5 websocket not supported by your browser, try Google Chrome"); }); ''') return dict(form=form, script=script) def ajax_form(): form=SQLFORM.factory(Field('message')) if form.accepts(request,session): from gluon.contrib.websocket_messaging import websocket_send websocket_send( 'http://127.0.0.1:8888',form.vars.message,'mykey','mygroup') return form Acknowledgements: Tornado code inspired by http://thomas.pelletier.im/2010/08/websocket-tornado-redis/ """ import tornado.httpserver import tornado.websocket import tornado.ioloop import tornado.web import hmac import sys import optparse import urllib import time listeners = {} names = {} tokens = {} def websocket_send(url, message, hmac_key=None, group='default'): sig = hmac_key and hmac.new(hmac_key, message).hexdigest() or '' params = urllib.urlencode( {'message': message, 'signature': sig, 'group': group}) f = urllib.urlopen(url, params) data = f.read() f.close() return data class PostHandler(tornado.web.RequestHandler): """ only authorized parties can post messages """ def post(self): if hmac_key and not 'signature' in self.request.arguments: *return None* if 'message' in self.request.arguments: message = self.request.arguments['message'][0] group = self.request.arguments.get('group', ['default'])[0] print '%s:MESSAGE to %s:%s' % (time.time(), group, message) if hmac_key: signature = self.request.arguments['signature'][0] if not hmac.new(hmac_key, message).hexdigest() == signature: *return None* for client in listeners.get(group, []): client.write_message(message) * return None* class TokenHandler(tornado.web.RequestHandler): """ if running with -t post a token to allow a client to join using the token the message here is the token (any uuid) allows only authorized parties to joins, for example, a chat """ def post(self): if hmac_key and not 'message' in self.request.arguments: *return None* if 'message' in self.request.arguments: message = self.request.arguments['message'][0] if hmac_key: signature = self.request.arguments['signature'][0] if not hmac.new(hmac_key, message).hexdigest() == signature: *return None* tokens[message] = None *return None* class DistributeHandler(tornado.websocket.WebSocketHandler): def open(self, params): group, token, name = params.split('/') + [None, None] self.group = group or 'default' self.token = token or 'none' self.name = name or 'anonymous' # only authorized parties can join if DistributeHandler.tokens: if not self.token in tokens or not token[self.token] is None: self.close() else: tokens[self.token] = self if not self.group in listeners: listeners[self.group] = [] # notify clients that a member has joined the groups for client in listeners.get(self.group, []): client.write_message('+' + self.name) listeners[self.group].append(self) names[self] = self.name print '%s:CONNECT to %s' % (time.time(), self.group) def on_message(self, message): pass def on_close(self): if self.group in listeners: listeners[self.group].remove(self) del names[self] # notify clients that a member has left the groups for client in listeners.get(self.group, []): client.write_message('-' + self.name) print '%s:DISCONNECT from %s' % (time.time(), self.group) if __name__ == "__main__": usage = __doc__ version = "" parser = optparse.OptionParser(usage, None, optparse.Option, version) parser.add_option('-p', '--port', default='8888', dest='port', help='socket') parser.add_option('-l', '--listen', default='0.0.0.0', dest='address', help='listener address') parser.add_option('-k', '--hmac_key', default='', dest='hmac_key', help='hmac_key') parser.add_option('-t', '--tokens', action='store_true', default=False, dest='tokens', help='require tockens to join') (options, args) = parser.parse_args() hmac_key = options.hmac_key DistributeHandler.tokens = options.tokens urls = [ (r'/', PostHandler), (r'/token', TokenHandler), (r'/realtime/(.*)', DistributeHandler)] application = tornado.web.Application(urls, auto_reload=True) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(int(options.port), address=options.address) tornado.ioloop.IOLoop.instance().start() -------------------------------------------------^^^^^^^-------------------------------------------------------------- I await confirmation of a more experienced programmer. Because I'm still learning. 2013/10/7 Junior Phanter <junior.co...@gmail.com> > I'll try to help. It will be an honor for me. > > > 2013/10/7 Massimo Di Pierro <massimo.dipie...@gmail.com> > >> Can you help us find out why Tornado 31. does not work? >> >> >> On Sunday, 6 October 2013 21:24:29 UTC-5, Junior Phanter wrote: >> >>> Sorry my bad english, >>> >>> Analyzing the web2py_websocket inside web2py.js. I noticed that when I >>> used: >>> >>> <script> >>> $(document).ready(function(){ >>> var data; >>> >>> web2py_websocket('ws://127.0.**0.1:8888/realtime/mygroup<http://127.0.0.1:8888/realtime/mygroup>', >>> function(e){data=eval('('+e.**data+')')}); >>> }); >>> </script> >>> >>> >>> the browser console accused the "web2py_websocket was not a function", so >>> I changed the code to: >>> >>> <script> >>> $(document).ready(function(){ >>> var data; >>> $.web2py.web2py_websocket('ws:**//127.0.0.1:8888/realtime/** >>> mygroup <http://127.0.0.1:8888/realtime/mygroup>', >>> function(e){data=eval('('+e.**data+')')}); >>> }); >>> </script> >>> >>> worked perfectly! >>> >>> >>> I changed it to Tornado 3.0 (Tornado 3.1.1 not work) and web2py 2.7.1. >>> >>> >>> 2013/10/4 Junior Phanter <junior...@gmail.com> >>> >>>> greetings , >>>> sorry my bad english , I 'm trying to implement a chat using the >>>> tornado and websocket_messaging.py , but I'm having trouble hearing the >>>> tornado server . the server receives the tornado MESSAGES using : >>>> >>>> websocket_send ( ' http://127.0.0.1:8888 ', ' Hello World ', ' mykey >>>> ', ' mygroup ' ) >>>> >>>> but the script : >>>> ------------------------------**------------------------------**----- >>>> <script> >>>> $(document).ready(function(){ >>>> var data; >>>> >>>> web2py_websocket('ws://127.0.**0.1:8888/realtime/mygroup<http://127.0.0.1:8888/realtime/mygroup> >>>> ',**function(e){data=eval('('+e.**data+')')}); >>>> }); >>>> </script> >>>> ------------------------------**------------------------------** >>>> ------------- >>>> does not capture the listener . >>>> >>>> I tested the application that comes as an example within the >>>> websocket_messaging.py and neither worked . >>>> >>>> --------------------- exemplo dentro do websocket_messaging.py >>>> -------------------------- >>>> >>>> Here is a complete sample web2py action: >>>> >>>> def index(): >>>> form=LOAD('default','ajax_**form',ajax=True) >>>> script=SCRIPT(''' >>>> jQuery(document).ready(**function(){ >>>> var callback=function(e){alert(e.**data)}; >>>> if(!web2py_websocket('ws://127** >>>> .0.0.1:8888/realtime/mygroup <http://127.0.0.1:8888/realtime/mygroup>', >>>> **callback)) >>>> alert("html5 websocket not supported by your browser, >>>> try Google Chrome"); >>>> }); >>>> ''') >>>> return dict(form=form, script=script) >>>> >>>> def ajax_form(): >>>> form=SQLFORM.factory(Field('**message')) >>>> if form.accepts(request,session): >>>> from gluon.contrib.websocket_**messaging import >>>> websocket_send >>>> websocket_send( >>>> 'http://127.0.0.1:8888',form.** >>>> vars.message,'mykey','mygroup'**) >>>> return form >>>> >>>> ------------------------------**------------------------------** >>>> ------------------------------**----------- >>>> >>>> >>>> >>>> I'm using the Tornado 2.1 and 2.6.4 web2py >>>> >>>> -- >>>> Resources: >>>> - http://web2py.com >>>> - http://web2py.com/book (Documentation) >>>> - http://github.com/web2py/**web2py >>>> <http://github.com/web2py/web2py>(Source code) >>>> - >>>> https://code.google.com/p/**web2py/issues/list<https://code.google.com/p/web2py/issues/list>(Report >>>> Issues) >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "web2py-users" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to web2py+un...@**googlegroups.com. >>>> >>>> For more options, visit >>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out> >>>> . >>>> >>> >>> -- >> Resources: >> - http://web2py.com >> - http://web2py.com/book (Documentation) >> - http://github.com/web2py/web2py (Source code) >> - https://code.google.com/p/web2py/issues/list (Report Issues) >> --- >> You received this message because you are subscribed to the Google Groups >> "web2py-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to web2py+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/groups/opt_out. >> > > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.