2010-04-05 34 views
8

Given, khi người dùng yêu cầu /foo trên máy chủ của tôi, tôi gửi HTTP response sau (không đóng kết nối):Đẩy dữ liệu một lần một URL được yêu cầu

Content-Type: multipart/x-mixed-replace; boundary=----------------------- 

----------------------- 
Content-Type: text/html 

<a href="/bar">foo</a> 

Khi người dùng đi vào /bar (mà sẽ gửi 204 No Content để chế độ xem không thay đổi), tôi muốn gửi dữ liệu sau trong phản hồi ban đầu.

----------------------- 
Content-Type: text/html 

bar 

Làm cách nào để nhận yêu cầu thứ hai kích hoạt phản hồi ban đầu này? Tôi đang lên kế hoạch cho việc tạo ra một công cụ ưa thích hỗ trợ multipart/x-mixed-replace (hiện chỉ là Gecko)] - chỉ ứng dụng web email có hiệu ứng máy chủ-đẩy và Ajax mà không cần JavaScript, chỉ để giải trí.

Trả lời

1

Không hoàn thành câu trả lời, nhưng:

Trong câu hỏi của bạn, bạn đang mô tả một kiến ​​trúc kiểu Comet. Về hỗ trợ các kỹ thuật Comet-style trong Python/WSGI, có một StackOverflow question, mà nói về các máy chủ Python khác nhau với sự hỗ trợ cho các yêu cầu chạy dài a la Comet.

Cũng thú vị là chuỗi thư này trong Python Web-SIG: "Could WSGI handle Asynchronous response?". Vào tháng 5 năm 2008, đã có một cuộc thảo luận rộng rãi trong Web-SIG về chủ đề của asynchronous requests in WSGI.

Một phát triển gần đây là evserver, một máy chủ WSGI nhẹ, mà thực hiện các Asynchronous WSGI extension bởi Christopher Stawarz đề xuất trong Web-SIG tháng năm 2008.

Cuối cùng, Tornado web server hỗ trợ non-blocking asynchronous requests. Nó có một ứng dụng ví dụ trò chuyện sử dụng phiếu thăm dò ý kiến ​​dài, có tính tương đồng với các yêu cầu của bạn.

+0

Bạn có thể không nhận ra nó, nhưng 'multipart/x-mixed-replace' __is__ một dạng Comet; biểu mẫu duy nhất không yêu cầu JavaScript. Nếu tôi có thể làm cho nó hoạt động với các yêu cầu không đồng bộ của Tornado, tôi sẽ chấp nhận câu trả lời này. –

+0

** Tôi nhận thức rõ rằng 'multipart/x-mixed-replace' là một dạng Comet, nhưng tôi nghĩ ** bạn không phải là ** ;-), vì bạn không đề cập đến từ thông dụng trong câu hỏi. Tôi đã làm một chút viết lại. – flight

1

Nếu vấn đề là chuyển một số lệnh từ ứng dụng/bar sang ứng dụng/foo và bạn đang sử dụng một số phương pháp giống servlet (mã Python được nạp một lần và không cho mỗi yêu cầu như trong CGI), bạn chỉ có thể thay đổi một số thuộc tính lớp của ứng dụng/foo và sẵn sàng phản ứng với sự thay đổi trong cá thể/foo (bằng cách kiểm tra trạng thái thuộc tính).

Rõ ràng ứng dụng/foo không được trả về ngay sau dòng yêu cầu đầu tiên và dòng nội dung lợi nhuận theo dòng.

Nghĩ rằng đây chỉ là lý thuyết, tôi chưa thử bản thân mình.

+0

Nếu không sử dụng một cơ sở dữ liệu đầy đủ (vì nó sẽ là khá nhiều quá mức cần thiết), làm thế nào tôi có thể dễ dàng thay đổi một đối tượng trạng thái được chia sẻ? –

+0

Như tôi đã nói, nếu mã chỉ được nạp một lần, thì mỗi yêu cầu mới chỉ là một thể hiện mới của lớp ứng dụng. Sau đó, bạn có thể sử dụng một số cấp độ mô-đun hoặc thuộc tính lớp (không phải mẫu) để trao đổi thông tin. – newtover

-1

Không chắc nếu điều này là khá những gì bạn đang tìm kiếm, nhưng có một cách khá cũ làm máy chủ đẩy sử dụng một nội dung kịch câm của/nhiều phần dữ liệu x-hỗn hợp thay thế

Về cơ bản bạn soạn phản ứng như đối tượng mime với loại nội dung multipart/x-mixed-replace và gửi "phiên bản" đầu tiên của tài liệu xuống. Trình duyệt sẽ giữ cho ổ cắm mở.

Sau đó khi máy chủ quyết định đẩy thêm dữ liệu, phiên bản "mới" của tài liệu sẽ được gửi từ máy chủ và trình duyệt sẽ thay thế thông minh (trong bất kỳ khung/khung nội tuyến nào chứa nội dung).

Đây là cách đầu tiên để thực hiện webcam, nơi máy chủ sẽ gửi (đẩy) hình ảnh sau khi hình ảnh và trình duyệt sẽ chỉ tiếp tục thay thế hình ảnh trong tài liệu lặp đi lặp lại. Đây cũng là cách thực hiện thông báo "Đang tải ..." qua một yêu cầu HTTP.

+0

Điều gì có liên quan đến việc trả lời câu hỏi của tôi? Tôi biết 'multipart/x-mixed-replace' là gì và cách sử dụng nó như được hiển thị trong câu hỏi. Tôi đang hỏi một câu hỏi Python wsgi như thế nào tôi sẽ xử lý kịch bản này. –

1

Tôi đã tạo ra một số ví dụ nhỏ (chỉ để cho vui, anh biết đấy :))

import threading 

num = 0 
cond = threading.Condition() 

def app(environ, start_response): 
    global num 

    cond.acquire() 
    num += 1 
    cond.notifyAll() 
    cond.release() 

    start_response("200 OK", [("Content-Type", "multipart/x-mixed-replace; boundary=xxx")]) 
    while True: 
     n = num  
     s = "--xxx\r\nContent-Type: text/html\r\n\r\n%s\n" % n 
     yield s 
     # wait for num change: 
     cond.acquire() 
     while num == n: 
      cond.wait() 
     cond.release() 


from cherrypy.wsgiserver import CherryPyWSGIServer 
server = CherryPyWSGIServer(("0.0.0.0", 3000), app) 

try: 
    server.start() 
except KeyboardInterrupt: 
    server.stop() 

# Now whenever you visit http://127.0.0.1:3000/, the number increases. 
# It also automatically increases in all previously opened windows/tabs. 

Ý tưởng về một biến được chia sẻ và đồng bộ hóa thread (sử dụng điều kiện đối tượng biến) được dựa trên thực tế là máy chủ WSGI cung cấp bởi CherryPyWSGIServer được tạo luồng.

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