2010-02-23 35 views
9

Tôi đang cố viết ứng dụng web đơn giản bằng thư viện Tornado và JS Prototype. Vì vậy, khách hàng có thể thực hiện công việc chạy dài trên máy chủ. Tôi ước rằng, công việc này chạy không đồng bộ - để các khách hàng khác có thể xem trang và làm một số thứ ở đó.Truy vấn COMET không đồng bộ với Tornado và Prototype

Ở đây những gì tôi đã có:

#!/usr/bin/env/ pytthon 

import tornado.httpserver 
import tornado.ioloop 
import tornado.options 
import tornado.web 
from tornado.options import define, options 

import os 
import string 
from time import sleep 
from datetime import datetime 

define("port", default=8888, help="run on the given port", type=int) 

class MainHandler(tornado.web.RequestHandler): 
    def get(self): 
     self.render("templates/index.html", title="::Log watcher::", c_time=datetime.now()) 

class LongHandler(tornado.web.RequestHandler): 
    @tornado.web.asynchronous 
    def get(self): 
     self.wait_for_smth(callback=self.async_callback(self.on_finish)) 
     print("Exiting from async.") 
     return 

    def wait_for_smth(self, callback): 
     t=0 
     while (t < 10): 
      print "Sleeping 2 second, t={0}".format(t) 
      sleep(2) 
      t += 1 
     callback() 

    def on_finish(self): 
     print ("inside finish") 
     self.write("Long running job complete") 
     self.finish() 



def main(): 
    tornado.options.parse_command_line() 

    settings = { 
     "static_path": os.path.join(os.path.dirname(__file__), "static"), 
     } 

    application = tornado.web.Application([ 
     (r"/", MainHandler), 
     (r"/longPolling", LongHandler) 
     ], **settings 
    ) 
    http_server = tornado.httpserver.HTTPServer(application) 
    http_server.listen(options.port) 
    tornado.ioloop.IOLoop.instance().start() 


if __name__ == "__main__": 
    main() 

Đây là máy chủ phần. Nó có quan điểm chính (cho thấy ít lời chào, thời gian máy chủ hiện tại và url cho truy vấn ajax, thực hiện công việc đang chạy dài .Nếu bạn nhấn một nút, một công việc chạy dài sẽ thực hiện. Và máy chủ bị treo: (Tôi không thể xem không có trang, trong khi . công việc này đang chạy đây là mẫu trang:

<html> 
<head> 
    <title>{{ title }}</title> 

    <script type="text/javascript" language="JavaScript" src="{{ static_url("js/prototype.js")}}"></script> 


    <script type='text/javascript' language='JavaScript'> 
     offset=0 
     last_read=0 

     function test(){ 
      new Ajax.Request("http://172.22.22.22:8888/longPolling", 
      { 
       method:"get", 
       asynchronous:true, 
       onSuccess: function (transport){ 
        alert(transport.responseText); 
       } 
      }) 
     } 


    </script> 
</head> 
<body> 
    Current time is {{c_time}} 
    <br> 
    <input type="button" value="Test" onclick="test();"/> 
</body> 
</html> 

những gì tôi làm sai như thế nào có thể thực hiện tổng hợp dài, sử dụng Tornado và thử nghiệm (hoặc jQuery)

PS: tôi đã xem xét ví dụ trò chuyện , nhưng nó quá phức tạp. Không thể hiểu cách hoạt động: (

PSS Tải xuống đầy đủ example

Trả lời

15

Tornado là máy chủ web đơn luồng. Vòng lặp while của bạn trong phương thức wait_for_smith đang chặn Tornado.

Bạn có thể viết lại phương pháp đó như thế này:

def wait_for_smth(self, callback, t=10): 
    if t: 
     print "Sleeping 2 second, t=%s" % t 
     tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 2, lambda: self.wait_for_smth(callback, t-1)) 
    else: 
     callback() 

Bạn cần phải thêm import time ở phía trên để làm cho công việc này.

+0

Tôi đã thử phương pháp đó và có thể xác nhận rằng nó không còn bị treo nữa, nhưng bây giờ chương trình sẽ hiển thị một hộp cảnh báo nơi responseText không được xác định và có lỗi 405. – brainysmurf

+0

Nói quá nhanh, vấn đề là kết thúc của tôi ... Tôi có hai địa chỉ khác nhau được chỉ định. Điều này chắc chắn hoạt động. – brainysmurf

+0

Nhưng cuộc thăm dò ý kiến ​​này có lâu không? Dường như chỉ là bỏ phiếu cho tôi. Tâm trí bạn tôi là một người mới Tornado/Comet bản thân mình. – Lorenzo

0

Tôi đã chuyển đổi ví dụ trò chuyện của Tornado để chạy trên gevent. Hãy xem the live demo herethe explanation and source code here.

Nó sử dụng chủ đề cấp người dùng nhẹ (greenlets) và có thể so sánh với tốc độ/bộ nhớ sử dụng với Tornado. Tuy nhiên, mã là đơn giản, bạn có thể gọi sleep() và urlopen() trong trình xử lý của bạn mà không chặn toàn bộ quá trình và bạn có thể sinh ra các công việc chạy dài làm tương tự. Dưới mui xe, ứng dụng không đồng bộ, được hỗ trợ bởi vòng lặp sự kiện được viết bằng C (libevent).

Bạn có thể đọc introduction here.

+0

Đẹp ngã ba Denis ... – securecurve

1
function test(){ 
      new Ajax.Request("http://172.22.22.22:8888/longPolling", 
      { 
       method:"get", 
       asynchronous:true, 
       onSuccess: function (transport){ 
        alert(transport.responseText); 
       } 
      }) 
     } 

nên

function test(){ 
      new Ajax.Request("/longPolling", 
      { 
       method:"get", 
       asynchronous:true, 
       onSuccess: function (transport){ 
        alert(transport.responseText); 
       } 
      }) 
     } 
+0

trong trường hợp cổng không mặc định, toàn bộ đường dẫn phải được thông qua. – securecurve

Các vấn đề liên quan