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.

Reply via email to