-3

start to learn python, can not get the return value from yield return. can anybody give me a favor.

I just want to pass a token from url to WSHandler, and get the uid from tonadoredis(github: https://github.com/leporo/tornado-redis) get method. and then blpop a list named "noticeT" + uid, when the "noticeTuid" has a new item, i want it return to the browser.

but my code can not work, how can I resove my problem?

class WSHandler(tornado.websocket.WebSocketHandler):
res = {'code':200, 'info': ''}

def initialize(self):
    self.c = tornadoredis.Client(host=CONFIG['REDIS_HOST'], port=CONFIG['REDIS_PORT'], password=CONFIG['REDIS_AUTH'])
    self.logintoken = self.get_argument('logintoken')
    self.noticeModel = noticeModel(self.logintoken, self.c)

def open(self):
    print 'new connection'
    # uid = yield tornado.gen.Task(self.c.get, self.logintoken)
    # print uid
    self.res['info'] = self.noticeModel.getNotice()
    if self.res['info']:
        print self.res
        self.write_message(json_encode(self.res))
    else:
        self.res['code'] = 500
        self.res['info'] = 'error'
        self.write_message(json_encode(self.res))

def on_message(self, message):
    print 'message received %s' % message

def on_close(self):
    print 'connection closed'

def check_origin(self, origin):
    # print origin
    # return True
    parsed_origin = urlparse(origin)
    # print parsed_origin
    return parsed_origin.netloc.endswith("localhost")

and the noticeModel code is :

class noticeModel :
    def __init__(self, logintoken, redisobj):
        self.logintoken = logintoken
        self.redisobj = redisobj

    # @tornado.web.asynchronous
    @tornado.gen.engine
    def getNotice(self):
        # uid = self.setLoginUid()
        uid = yield tornado.gen.Task(self.redisobj.get, self.logintoken)
        print "getNotice uid is %s"% uid
        # if self.uid:
        print "getNotice logintoken is %s"% self.logintoken 
        key = "noticeT" + uid
        key = key.encode('utf-8')
        print 'listening key:%s'% key
        yield tornado.gen.Task(self.redisobj.blpop, key, 0)

    @tornado.gen.engine
    def setLoginUid(self):
        yield tornado.gen.Task(self.redisobj.get, self.logintoken)
weizhao
  • 183
  • 3
  • 16

2 Answers2

1

The problem doesn't have anything to do with yield, its your configuration parameter. From the stack trace

...
File "/Library/Python/2.7/site-packages/tornadoredis/connection.py", line 73, in connect
    sock.connect((self.host, self.port))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
TypeError: an integer is required

the problem is that self.port isn't an integer. Looking at where port is set,

self.c = tornadoredis.Client(host=CONFIG['REDIS_HOST'], port=CONFIG['REDIS_PORT'], password=CONFIG['REDIS_AUTH'])

its very likely that CONFIG['REDIS_PORT'] is a string and the the problem is fixed by converting it to an int

self.c = tornadoredis.Client(host=CONFIG['REDIS_HOST'], port=int(CONFIG['REDIS_PORT']), password=CONFIG['REDIS_AUTH'])
tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • plese take some time to my new answer~~ – weizhao Mar 19 '15 at 15:13
  • How about deleting that answer and asking it as a new question? You don't have to mention yield or the port thing, that's solved, just the tornado issue. Tag it python and tornado. You'll get a fresh set of eyes looking at it and likely somebody who knows how to fix it. BTW, if this was the right answer, accept it so that future viewers know it worked. – tdelaney Mar 19 '15 at 15:23
  • redis port is a mistake. what I want is get the value from yield return . now I do not get the value I want .. – weizhao Mar 19 '15 at 15:28
  • Once again, this is not a problem with `yield`. The error tells you what the problem is: _"AttributeError: noticeModel instance has no attribute '_stack_context_handle_exception'"_. I know about`yield` and I know about sockets, so I answered your previous problem. I don't use tornado so can't help you there. If you write this as a tornado issue, then tornado people will notice it and answer. Make it easy for the people that want to help you. – tdelaney Mar 19 '15 at 15:55
  • if I revome @tornado.web.asynchronous, In the WSHandler open, I print the self.res, iTerm get this: {'info': None, 'code': 200} getNotice uid is 89 – weizhao Mar 20 '15 at 09:44
0

As the yield return a generator you can iterate over its values with next function!

next(iterator[, default])

Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.

Community
  • 1
  • 1
Mazdak
  • 105,000
  • 18
  • 159
  • 188