0

我正在尝试制作一个使用 Tornado 的非阻塞 Web 应用程序。该应用程序使用 PeriodicCallback 作为从新闻站点获取数据的调度程序:

for nc_uuid in self.LIVE_NEWSCOLLECTORS.keys():
            self.LIVE_NEWSCOLLECTORS[nc_uuid].agreggator,ioloop=args
            period=int(self.LIVE_NEWSCOLLECTORS[nc_uuid].period)*60
            if self.timer is not None: period = int(self.timer)

            #self.scheduler.add_job(func=self.LIVE_NEWSCOLLECTORS[nc_uuid].getNews,args=[self.source,i],trigger='interval',seconds=10,id=nc_uuid)
            task = tornado.ioloop.PeriodicCallback(lambda:self.LIVE_NEWSCOLLECTORS[nc_uuid].getNews(self.source,i),1000*10,ioloop)
            task.start()

作为回调调用的“getData”有一个异步 http 请求,该请求解析数据并将数据发送到 TCPServer 以通过调用方法 process_responce 进行分析:

@gen.coroutine 
def process_response(self,*args,**kwargs):
buf = {'sentence':str('text here')}
data_string = json.dumps(buf)
s.send(data_string)
while True:
    try:
         data = s.recv(100000)
         if not data:
                print "connection closed"
                s.close()
                break
         else:
             print "Received %d bytes: '%s'" % (len(data), data)
            # s.close()
             break
    except socket.error, e:
          if e.args[0] == errno.EWOULDBLOCK:
               print 'error',errno.EWOULDBLOCK
               time.sleep(1)           # short delay, no tight loops
          else:
               print e
               break
    i+=1

在 process_response 中,我使用基本示例进行非阻塞套接字操作。Process_response 显示如下内容: error 10035 error 10035 Received 75 bytes: '{"mode": 1, "keyword": "\u0435\u0432\u0440\u043e", "sentence": "text here"}'

这看起来很正常。但是当接收数据时,主 IOLoop 被锁定了!如果我要问网络服务器,它不会返回我的任何数据,直到周期性回调任务完成......我的错误在哪里?

4

1 回答 1

0

time.sleep()是一个阻塞函数,绝不能在非阻塞代码中使用。改为使用yield gen.sleep()

还可以考虑使用tornado.iostream.IOStream而不是原始套接字操作。

于 2015-09-10T20:16:06.780 回答