Reverse Ajax, Phần 1: Giới thiệu về Comet

Streaming (Stream luồng dữ liệu) và long polling (kéo dài thời gian) đáp ứng giữa máy chủ và máy khách

Trong loạt bài này, hãy tìm hiểu cách phát triển các ứng dụng web theo hướng sự kiện bằng cách sử dụng các kỹ thuật Reverse Ajax để có một trải nghiệm tốt hơn. Các ví dụ trên phía máy khách sẽ sử dụng thư viện JQuery JavaScript. Trong bài đầu tiên này, hãy khám phá các kỹ thuật Reverse Ajax khác nhau. Bạn có thể tải về các ví dụ, hãy tìm hiểu về Comet với các phương pháp streaming và long polling.

Mathieu Carbou, Kiến trúc sư Java Web, Ovea

Ảnh của Mathieu CarbouMathieu Carbou là nhà tư vấn và kiến trúc web Java ở Ovea, cung cấp các dịch vụ và các giải pháp phát triển. Ông là người đứng dầu và điều hành một số dự án nguồn mở, là người phát ngôn và lãnh đạo của Nhóm người dùng Java (Java User Group) của Montreal. Mathieu có nền tảng vững chắc về thiết kế mã và có kinh nghiệm tốt, ông còn là một chuyên gia phát triển web theo hướng sự kiện (event-driven web) từ phía máy khách đến các tầng bên dưới. Ông tập trung vào việc cung cấp các giải pháp thông tin và theo hướng sự kiện của các ứng dụng web có khả năng co giãn cao. Hãy ghé thăm blog của ông.



17 01 2013

Giới thiệu

Phát triển ứng dụng Web đã có nhiều tiến bộ trong vài năm qua. Chúng ta đang bỏ lại đằng sau các trang web tĩnh với những đường link liên kết khiến cho ta phải liên tục refresh (làm mới) và chờ cho trang web được hiển thị lại. Thay vào đó, nhu cầu hiện nay chính là những trang web động với tốc độ đáp ứng thời gian thực càng nhanh càng tốt. Với 5 phần trong loạt bài này, hãy cùng tìm hiểu cách phát triển các ứng dụng web theo hướng sự kiện bằng cách sử dụng các kỹ thuật Reverse Ajax.

Trong bài đầu tiên, hãy tìm hiểu về Reverse Ajax, polling, streaming, Comet và long polling. Tìm hiểu cách thực hiện các kỹ thuật truyền thông Reverse Ajax khác nhau và khám phá những ưu nhược điểm của từng phương pháp này. Bạn có thể tải về mã nguồn để cùng làm theo các ví dụ trong bài này.


Ajax, Reverse Ajax và WebSockets

Ajax (Asynchronous JavaScript và XML), một kỹ thuật dành cho trình duyệt dựa trên JavaScript, cho phép sử dụng một đoạn mã lệnh để đáp ứng các yêu cầu HTTP cho từng thành phần mà không cần phải refresh lại toàn bộ trang web. Ajax đã được ứng dụng hơn 10 năm nay. Mặc dù tên của nó có kèm theo XML, nhưng bạn có thể truyền tải bất cứ thứ gì trong một yêu cầu Ajax. Dữ liệu được sử dụng phổ biến nhất là JSON, nó có cú pháp gần với cú pháp của JavaScript và tiêu thụ ít băng thông hơn. Liệt kê 1 là ví dụ về một yêu cầu Ajax để lấy ra tên của một vùng địa phương từ mã bưu chính của nó.

Liệt kê 1. Ví dụ về yêu cầu Ajax
var url = 'http://www.geonames.org/postalCodeLookupJSON?postalcode=' 
    + $('#postalCode').val() + '&country=' 
    + $('#country').val() + '&callback=?'; 
$.getJSON(url, function(data) { 
    $('#placeName').val(data.postalcodes[0].placeName); 
});

Bạn có thể xem cách hoạt động của ví dụ trên trong file listing1.html có ở đây.

Về cơ bản Reverse Ajax là một khái niệm: có thể gửi dữ liệu từ máy chủ đến máy khách. Trong một yêu cầu Ajax của HTTP tiêu chuẩn, dữ liệu được gửi đến máy chủ. Reverse Ajax có thể được mô phỏng để tạo ra một yêu cầu Ajax, theo những cách cụ thể được nêu ra trong bài viết này, do đó, máy chủ có thể gửi các sự kiện đến máy khách càng nhanh càng tốt (giao tiếp với độ trễ thấp).

WebSockets, có kèm theo HTML5, là một kỹ thuật mới hơn. Nhiều trình duyệt đã hỗ trợ nó (Firefox, Google Chrome, Safari và những trình duyệt khác). WebSockets tạo nên các kênh truyền thông song song, hai chiều. Kết nối này được mở ra thông qua một yêu cầu HTTP được gọi là WebSockets handshake với một số header đặc biệt. Kết nối này được duy trì và bạn có thể viết và nhận dữ liệu bằng JavaScript, như thể bạn đang sử dụng một TCP socket nguyên bản. WebSockets sẽ được trình bày trong phần 2 của loạt bài này.


Các kỹ thuật Reverse Ajax

Mục tiêu của kỹ thuật Reverse Ajax là giúp các máy chủ đẩy thông tin đến máy khách. Theo mặc định các yêu cầu Ajax là không chính thống và chỉ có thể được bắt đầu từ máy khách đến máy chủ. Bạn có thể vượt qua hạn chế này bằng cách sử dụng các kỹ thuật để mô phỏng truyền thông đáp ứng giữa máy chủ và máy khách.

HTTP polling và JSONP polling

Polling bao gồm việc gửi một thông điệp từ phía máy khách đến máy chủ để yêu cầu một thông tin dữ liệu nào đó. Thực ra đây chỉ là một yêu cầu HTTP của Ajax. Để có được các sự kiện từ máy chủ càng sớm thì khoảng thời gian polling (thời gian giữa các yêu cầu) phải càng ngắn càng tốt. Có một nhược điểm là: nếu khoảng thời gian này càng ngắn, trình duyệt của máy khách sẽ đưa ra nhiều yêu cầu hơn, trong đó có những yêu cầu sẽ không trả về bất kỳ dữ liệu có ích nào khiến cho băng thông bị hao tốn và xử lý tài nguyên vô ích.

Bảng thời gian trong Hình 1 cho thấy cách mà máy khách gửi các yêu cầu polling nhưng chẳng có thông tin nào được trả về cả. Máy khách phải chờ đến lần polling tiếp theo để có được hai sự kiện do máy chủ thu nhận được.

Hình 1. Reverse Ajax với việc polling của HTTP
Sơ đồ mô tả yêu cầu HTTP hỏi vòng Ajax được gửi mỗi lần 5 giây. Đáp ứng đầu tiên không chứa dữ liệu nào. Sau đó hai sự kiện đến bên phía máy chủ. Chúng cần chờ hỏi vòng lần thứ hai, khoảng 4 giây sau, để gửi trở lại đáp ứng tới máy khách. Rồi hỏi vòng lần thứ ba không trả về gì cả do không có sự kiện nào xảy ra.

Về bản chất, polling của JSONP giống như polling của HTTP. Tuy nhiên, có sự khác biệt ở chỗ với JSONP bạn có thể đưa ra yêu cầu giữa các domain (các yêu cầu không có trong domain của bạn). JSONP được dùng trong Liệt kê 1 để nhận về một tên địa phương từ một mã bưu chính. Thường thì có thể nhận ra một yêu cầu JSONP bằng cách xem tham số gọi lại và nội dung trả về của nó, đó chính là mã JavaScript có thể chạy được.

Để thực hiện polling trong JavaScript, bạn có thể sử dụng hàm setInterval để định thời gian gửi các yêu cầu Ajax, như trong Liệt kê 2:

Liệt kê 2. Polling trong JavaScript
setInterval(function() { 
    $.getJSON('events', function(events) { 
        console.log(events); 
    }); 
}, 2000);

Đoạn mã demo kỹ thuật polling ở đây cho thấy phương pháp này tiêu thụ băng thông như thế nào. Khoảng thời gian cho các lần polling ngắn nhưng có thể bạn sẽ nhận các kết quả trả về mà chẳng có sự kiện (event) mới nào. Liệt kê 3 hiển thị kết quả của việc polling ở ví dụ mẫu.

Liệt kê 3. Kết quả của đoạn demo polling trong ví dụ mẫu
[client] checking for events... 
[client] no event 
[client] checking for events... 
[client] 2 events 
[event] At Sun Jun 05 15:17:14 EDT 2011 
[event] At Sun Jun 05 15:17:14 EDT 2011 
[client] checking for events... 
[client] 1 events 
[event] At Sun Jun 05 15:17:16 EDT 2011

Polling trong JavaScript có các ưu và nhược điểm.

  • Ưu điểm: Nó thực sự dễ thực hiện và không đòi hỏi bất kỳ tính năng đặc biệt nào ở phía máy chủ. Nó cũng làm việc trong tất cả các trình duyệt.
  • Nhược điểm: Phương pháp này hiếm khi được sử dụng vì nó không hề linh động. Hãy tưởng tượng, giả sử có 100 máy khách, trong đó mỗi máy gửi các yêu cầu polling trong 2 giây thì số lượng băng thông và tài nguyên bị hao tốn như thế nào, ở đây 30% yêu cầu được trả về không hề có chút dữ liệu.

Piggyback

Piggyback polling là một phương pháp thông minh hơn nhiều so với polling đơn thuần vì nó có xu hướng loại bỏ tất cả các yêu cầu không cần thiết (các yêu cầu không trả về dữ liệu nào). Không cần định sẵn một khoảng thời gian interval nào cả; yêu cầu sẽ được gửi đi khi máy khách cần gửi một yêu cầu đến máy chủ. Sự khác biệt nằm ở cách phản hồi được chia thành hai phần: phản hồi với dữ liệu được yêu cầu và các sự kiện từ máy chủ. Hình 2 chính là ví dụ.

Hình 2. Reverse Ajax với Piggyback polling
Sơ đồ mô tả máy khách gửi một yêu cầu gửi lên và nhận một đáp ứng hỗn hợp. Không có sự kiện nào xuất hiện trên máy chủ, nên đáp ứng hỗn hợp chỉ chứa đáp ứng của yêu cầu. Sau đó hai sự kiện đến phía máy chủ, nhưng chúng cần chờ yêu cầu máy khách tiếp theo sao cho đáp ứng hỗn hợp sẽ chứa cả hai các sự kiện cộng với dáp ứng của yêu cầu bình thường. Nếu máy khách không khởi động bất kỳ hành động nào, thì các sự kiện đã tới máy chủ sẽ không được gọi ra.

Khi thực hiện kỹ thuật Piggyback, thông thường tất cả các yêu cầu Ajax gửi đến máy chủ có thể được trả về một phản hồi hỗn hợp. Ví dụ mẫu về cách thực hiện kỹ thuật này có ở đây và trong Liệt kê 4 dưới đây.

Liệt kê 4. Ví dụ mẫu về mã piggyback
$('#submit').click(function() { 
    $.post('ajax', function(data) { 
        var valid = data.formValid; 
        // process validation results 
        // then process the other part of the response (events) 
        processEvents(data.events); 
    }); 
});

Liệt kê 5 hiển thị kết quả khi sử dụng phương pháp piggyback.

Liệt kê 5. Kết quả piggyback
[client] checking for events... 
[server] form valid ? true 
[client] 4 events 
[event] At Sun Jun 05 16:08:32 EDT 2011 
[event] At Sun Jun 05 16:08:34 EDT 2011 
[event] At Sun Jun 05 16:08:34 EDT 2011 
[event] At Sun Jun 05 16:08:37 EDT 2011

Bạn có thể thấy kết quả của việc kiểm tra hợp lệ một khuôn mẫu (form validation) và các sự kiện được thêm vào phản hồi. Một lần nữa, phương pháp này có những ưu và nhược điểm.

  • Ưu điểm: Không có các yêu cầu nào trả về mà không có dữ liệu, vì máy khách kiểm soát khi nó gửi các yêu cầu, nên bạn tiêu thụ ít tài nguyên hơn. Nó cũng làm việc trong tất cả các trình duyệt và không yêu cầu các tính năng đặc biệt ở phía máy chủ.
  • Nhược điểm: Bạn sẽ không biết khi nào mà các sự kiện ở phía máy chủ được gửi tới máy khách vì nó đòi hỏi phải có một hành động từ phía máy khách để yêu cầu chúng.

Comet

Reverse Ajax với kỹ thuật polling hay piggyback cũng còn rất hạn chế: vì nó không co giãn và không cung cấp khả năng giao tiếp với độ trễ thấp (tức là các sự kiện phải được gửi đến trình duyệt ngay khi chúng đến máy chủ). Comet là một mô hình ứng dụng web, ở đây một yêu cầu được gửi đến máy chủ và vẫn tiếp tục trong một thời gian dài cho đến khi hết giờ hoặc xuất hiện một sự kiện từ máy chủ. Khi yêu cầu này được hoàn thành thì sẽ có một yêu cầu Ajax khác được gửi đi để chờ các sự kiện khác từ máy chủ. Với Comet, các máy chủ web có thể gửi dữ liệu cho máy khách mà cần phải có một yêu cầu cụ thể nào.

Ưu điểm lớn của Comet ở chỗ mỗi máy khách luôn có một liên kết giao tiếp đến máy chủ. Máy chủ có thể đẩy các sự kiện vào các máy khách bằng cách thực hiện commit (hay hoàn thành) ngay lập tức các phản hồi ngay khi chúng đến hoặc thậm chí nó có thể tích lũy và gửi một lần. Vì một yêu cầu được mở trong một thời gian dài, nên cần có các tính năng đặc biệt ở phía máy chủ để xử lý tất cả những long-lived này (long-lived requets - các yêu cầu có thời gian sống lâu). Hình 3 là ví dụ. (Phần 2 của loạt bài này sẽ giải thích các ràng buộc máy chủ chi tiết hơn).

Hình 3. Reverse Ajax với Comet
Sơ đồ mô tả Comet sử dụng hỏi vòng kéo dài (không luồng). Một yêu cầu Ajax được gửi tới máy chủ. Máy chủ treo nó (vì thế yêu cầu này vẫn duy trì hoạt động và không có đáp ứng nào được hoàn thành). Máy khách có thể gửi các yêu cầu Ajax khác tới máy chủ để nhận/gửi lên dữ liệu nào đó. Vào lúc này, một sự kiện xẩy ra bên phía máy chủ; sau đó yêu cầu bị treo được cam kết ngay lập tức (đáp ứng được gửi tới máy khách). Vì thế máy khách nhận được đáp ứng của yêu cầu Ajax bị treo và có thể khởi chạy một yêu cầu khác.

Các cách thực hiện của Comet có thể được chia thành hai loại: một loại sử dụng chế độ streaming và một loại khác sử dụng long polling.


Comet sử dụng kỹ thuật HTTP Streaming

Trong chế độ streaming, một kết nối được mở liên tục. Sẽ chỉ có một yêu cầu long-lived (#1 trong Hình 3) do mỗi sự kiện đến phía máy chủ được gửi đi thông qua cùng một kết nối. Do đó, nó đòi hỏi ở phía máy khách phải có cơ chế phân chia các phản hồi đến từ cùng một nguồn kết nối đó. Về mặt kỹ thuật, hai kỹ thuật phổ biến về streaming là Forever Iframes (Các IFrame ẩn) và tính năng đa-phần (multi-part) của đối tượng XMLHttpRequest được sử dụng để tạo ra các yêu cầu Ajax trong JavaScript.

Forever Iframes

Kỹ thuật Forever Iframes sử dụng một thẻ Iframe ẩn đặt trong trang với thuộc tính src trỏ đến đường dẫn servlet nhằm trả về các sự kiện máy chủ. Mỗi khi nhận được một sự kiện, servlet sẽ viết và đổ vào một thẻ script với mã JavaScript bên trong. Nội dung của iframe sẽ được thêm vào thẻ script này và được thực thi.

  • Ưu điểm: Dễ thực hiện và nó hoạt động trong tất cả các trình duyệt hỗ trợ các iframe.
  • Nhược điểm: Không có cách nào để thực hiện xử lý lỗi hoặc theo dõi trạng thái của kết nối, bởi vì tất cả các kết nối và dữ liệu đều được trình duyệt xử lý thông qua các thẻ HTML. Do đó bạn không biết khi nào thì kết nối bị ngắt ở cả hai phía.

Tính năng multi-part của XMLHttpRequest

Kỹ thuật thứ hai đáng tin cậy hơn là sử dụng cờ multi-part được hỗ trợ bởi một số trình duyệt (như Firefox) trên đối tượng XMLHttpRequest. Một yêu cầu Ajax được gửi và được mở ở phía máy chủ. Mỗi lần một sự kiện đến, một phản hồi multi-part được viết thông qua cùng một kết nối. Liệt kê 6 mô tả ví dụ này.

Liệt kê 6. Mẫu JavaScript để thiết lập một yêu cầu streaming multi-part
var xhr = $.ajaxSettings.xhr(); 
xhr.multipart = true; 
xhr.open('GET', 'ajax', true); 
xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4) { 
        processEvents($.parseJSON(xhr.responseText)); 
    } 
}; 
xhr.send(null);

Về phía máy chủ, mọi thứ phức tạp hơn một chút. Trước tiên, bạn phải thiết lập yêu cầu multi-part, rồi treo (suspend) kết nối. Liệt kê 7 cho thấy cách treo một yêu cầu HTTP streaming. (Phần 3 của loạt bài này sẽ trình bày chi tiết hơn về các API).

Liệt kê 7. Ngắt một HTTP treaming trong một servlet khi sử dụng API Servlet 3
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { 
    // start the suspension of the request
    AsyncContext asyncContext = req.startAsync(); 
    asyncContext.setTimeout(0); 

    // send the multipart separator back to the client
    resp.setContentType("multipart/x-mixed-replace;boundary=\""
        + boundary + "\""); 
    resp.setHeader("Connection", "keep-alive"); 
    resp.getOutputStream().print("--" + boundary); 
    resp.flushBuffer(); 

    // put the async context in a list for future usage
    asyncContexts.offer(asyncContext); 
}

Giờ đây, mỗi khi một sự kiện xảy ra, bạn có thể lặp qua tất cả các kết nối đang bị treo và viết dữ liệu tới chúng, như thể hiện trong Liệt kê 8:

Liệt kê 8. Gửi các sự kiện tới một yêu cầu multi-part đang bị treo bằng cách sử dụng API Servlet 3
for (AsyncContext asyncContext : asyncContexts) { 
    HttpServletResponse peer = (HttpServletResponse) 
        asyncContext.getResponse(); 
    peer.getOutputStream().println("Content-Type: application/json"); 
    peer.getOutputStream().println(); 
    peer.getOutputStream().println(new JSONArray()
        .put("At " + new Date()).toString()); 
    peer.getOutputStream().println("--" + boundary); 
    peer.flushBuffer(); 
}

Các file mà bạn tải về theo bài viết này, trong thư mục Comet-streaming, trình bày về HTTP streaming . Khi bạn chạy ví dụ mẫu và mở trang chủ ra, bạn sẽ thấy các sự kiện lập tức xuất hiện không đồng bộ ngay khi đến máy chủ. Ngoài ra, nếu bạn sử dụng addon Firebug, bạn có thể thấy rằng chỉ có một yêu cầu Ajax được mở. Nếu bạn xem kỹ hơn, bạn sẽ thấy các phản hồi JSON được hiển thị ở tab Response, như thể hiện trong Hình 4:

Hình 4. Cửa sổ Firebug của một yêu cầu HTTP streaming
Ảnh chụp màn hình của khung nhìn của một yêu cầu luồng HTTP. Trình cắm thêm FireBug trong Firefox cho thấy đáp ứng thành công theo yêu cầu luồng Ajax tương tự.

Như thường lệ, kỹ thuật này cũng có những ưu và nhược điểm sau.

  • Ưu điểm: Chỉ có một kết nối liên tục được mở. Đây là kỹ thuật Comet, tiết kiệm việc sử dụng băng thông nhất.
  • Nhược điểm: Không phải tất cả các trình duyệt đều hỗ trợ cờ multi-part. Một số thư viện được sử dụng rộng rãi, chẳng hạn như CometD trong Java, đã cho thấy nhiều vấn đề về bộ nhớ đệm (buffer). Ví dụ, các khối dữ liệu (multi-part) có thể được lưu giữ trong một buffer và chỉ được gửi đi chỉ khi kết nối hoàn thành hoặc khi buffer đầy, điều này có thể tạo ra độ trễ cao hơn dự kiến.

Comet sử dụng kỹ thuật HTTP long-polling

Chế độ long-polling liên quan đến các kỹ thuật để mở một kết nối. Kết nối được mở bởi máy chủ và ngay khi sự kiện xảy ra thì phản hồi được commit và kết nối được đóng lại. Sau đó, một kết nối long-polling mới lại ngay lập tức được máy khách mở để đón các sự kiện gửi đến.

Bạn có thể thực hiện HTTP long-polling bằng cách sử dụng các thẻ script hoặc đơn giản chỉ thông qua một đối tượng XMLHttpRequest.

Các thẻ script

Với các iframe, mục tiêu là nối thêm một thẻ script vào trang của bạn để chạy kịch bản lệnh này. Máy chủ sẽ: treo kết nối cho đến khi một sự kiện xảy ra, gửi nội dung kịch bản lệnh lại cho trình duyệt và sau đó mở lại một thẻ script để nhận những sự kiện tiếp theo.

  • Ưu điểm: Vì dựa trên các thẻ HTML, nên kỹ thuật này rất dễ thực hiện và làm việc trên các domain (theo mặc định, XMLHttpRequest không cho phép thực hiện yêu cầu trên domain hoặc các domain con khác).
  • Nhược điểm: Tương tự như kỹ thuật iframe, thiếu xử lý lỗi và bạn không thể biết trạng thái hay khả năng để ngắt một kết nối.

Long-polling của XMLHttpRequest

Phương pháp Comet thứ hai được khuyên dùng là mở một yêu cầu Ajax đến máy chủ và chờ phản hồi. Đòi hỏi máy chủ phải có tính năng đặc thù cho phép treo các yêu cầu. Ngay khi sự kiện xảy ra, máy chủ sẽ gửi lại phản hồi theo yêu cầu bị treo và đóng nó lại, giống như khi bạn đóng luồng dữ liệu kết quả của một phản hồi servlet. Sau đó máy khách sẽ sử dụng phản hồi đó và mở một yêu cầu Ajax long-lived mới đến máy chủ, như trong Liệt kê 9:

Liệt kê 9. Mã JavaScript mẫu để thiết lập các yêu cầu long-polling
function long_polling() { 
    $.getJSON('ajax', function(events) { 
        processEvents(events); 
        long_polling(); 
    }); 
} 

long_polling();

Ở tầng sau, mã này cũng sử dụng API Servlet 3 để treo yêu cầu, cũng như HTTP streaming, nhưng bạn không cần tất cả mã xử lý multi-part. Liệt kê 10 thể hiện ví dụ này.

Liệt kê 10. Treo một yêu cầu Ajax long-polling
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { 
    AsyncContext asyncContext = req.startAsync(); 
    asyncContext.setTimeout(0); 
    asyncContexts.offer(asyncContext); 
}

Khi nhận một sự kiện, chỉ cần thực hiện tất cả các yêu cầu bị treo và hoàn thành chúng, như trong Liệt kê 11:

Liệt kê 11. Hoàn thành một yêu cầu Ajax long-polling khi một sự kiện xảy ra
while (!asyncContexts.isEmpty()) { 
    AsyncContext asyncContext = asyncContexts.poll(); 
    HttpServletResponse peer = (HttpServletResponse) 
        asyncContext.getResponse(); 
    peer.getWriter().write(
        new JSONArray().put("At " + new Date()).toString()); 
    peer.setStatus(HttpServletResponse.SC_OK); 
    peer.setContentType("application/json"); 
    asyncContext.complete(); 
}

Trong các file mã nguồn đi kèm, thư mục comet-long-polling có một ứng dụng web mẫu về long-polling mà bạn có thể chạy bằng cách sử dụng lệnh mvn jetty:run.

  • Ưu điểm: Dễ thực hiện bên phía máy khách với một hệ thống xử lý lỗi và quản lý thời gian chờ tốt. Kỹ thuật này cũng cho phép khứ hồi giữa các kết nối ở phía máy chủ, do kết nối không liên tục (đây là một tin mừng khi bạn có rất nhiều máy khách trên ứng dụng của mình). Nó cũng làm việc trên tất cả các trình duyệt; bạn chỉ cần sử dụng đối tượng XMLHttpRequest bằng cách gửi một yêu cầu Ajax đơn giản.
  • Nhược điểm: Không có nhược điểm đáng kể nào so với các kỹ thuật khác. Tuy nhiên, giống như tất cả các kỹ thuật mà chúng ta đã thảo luận, vẫn có một nhược điểm là dựa vào một kết nối HTTP không trạng thái, mà nó yêu cầu các tính năng đặc biệt bên phía máy chủ để có thể treo nó tạm thời.

Khuyến cáo

Vì tất cả các trình duyệt hiện đại đều hỗ trợ đặc tả CORS (Cross-Origin Resource Sharing - Chia sẻ giữa các nguồn tài nguyên gốc), cho phép XHR thực hiện yêu cầu qua các domain, nên nhu cầu về các kỹ thuật dựa trên kịch bản lệnh và dựa trên khung nội tuyến không được ủng hộ.

Cách tốt nhất để thực hiện và sử dụng Comet với Reverse Ajax là thông qua đối tượng XMLHttpRequest, cung cấp một xử lý kết nối thực và xử lý lỗi. Nếu cho rằng không phải tất cả các trình duyệt đều hỗ trợ cờ multi-part và multi-part streaming có thể là một vấn đề về buffer thì điều quan trọng là bạn sử dụng Comet thông qua kỹ thuật HTTP long-polling với đối tượng XMLHttpRequest (một yêu cầu Ajax đơn giản bị treo bên phía máy chủ). Tất cả các trình duyệt hỗ trợ Ajax cũng sẽ hỗ trợ phương pháp này.


Kết luận

Bài viết này đã giới thiệu về các kỹ thuật Reverse Ajax. Đã chỉ ra các cách khác nhau để thực hiện giao tiếp Reverse Ajax và cũng giải thích những ưu và nhược điểm của mỗi cách. Tùy vào tình huống cụ thể và các yêu cầu trong ứng dụng của bạn sẽ dẫn đến việc lựa chọn phương pháp nào là tốt nhất. Dù vậy, phương pháp Comet với kỹ thuật Ajax long-polling là cách hay có thể lựa chọn nếu như bạn muốn các tính năng: giao tiếp với độ trễ thấp; phát hiện lỗi và thời gian chờ; tính đơn giản; và hỗ trợ tốt từ tất cả các trình duyệt và nền tảng.

Tiếp theo Phần 2 của loạt bài này, bạn sẽ khám phá một kỹ thuật Reverse Ajax thứ ba: đó là WebSockets. Mặc dù không phải tất cả các trình duyệt đều hỗ trợ nó nhưng chắc chắn WebSockets sẽ là một phương tiện truyền thông rất tốt cho Reverse Ajax. WebSockets loại bỏ tất cả các ràng buộc liên quan đến đặc tính không trạng thái (stateless) của một kết nối HTTP. Phần 2 cũng sẽ trình bày các ràng buộc phía máy chủ do các kỹ thuật Comet và WebSocket gây ra.


Tải về

Mô tảTênKích thước
Article source codereverse_ajaxpt1_source.zip17KB

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

  • Nhận ExtJS, thư viện JavaScript giữa các trình duyệt để xây dựng các ứng dụng Internet phong phú.
  • XAMPP cung cấp việc cài đặt dễ dàng Apache, PHP, MySQL và những thứ tuyệt vời khác.
  • Hãy dùng thử phần mềm IBM miễn phí. Tải về một phiên bản dùng thử, đăng nhập vào một bản dùng thử trực tuyến, làm việc với một sản phẩm trong một môi trường sandbox hoặc truy cập nó thông qua đám mây. Chọn từ hơn 100 bản dùng thử sản phẩm của IBM.

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=855305
ArticleTitle=Reverse Ajax, Phần 1: Giới thiệu về Comet
publish-date=01172013