Cập nhật
Khi tôi tiếp tục nhận được những đánh giá cao về điều này, tôi nghĩ thật hợp lý khi nhớ rằng câu trả lời này đã 4 tuổi. Web đã phát triển với tốc độ rất nhanh, vì vậy hãy chú ý đến câu trả lời này.
Tôi đã có cùng một vấn đề gần đây và nghiên cứu về chủ đề này.
Giải pháp đưa ra được gọi là bỏ phiếu dài và để sử dụng chính xác, bạn phải chắc chắn rằng yêu cầu AJAX của bạn có thời gian chờ "lớn" và luôn thực hiện yêu cầu này sau khi kết thúc hiện tại (hết thời gian, lỗi hoặc thành công).
Bỏ phiếu dài - Khách hàng
Ở đây, để giữ mã ngắn, tôi sẽ sử dụng jQuery:
function pollTask() {
$.ajax({
url: '/api/Polling',
async: true, // by default, it's async, but...
dataType: 'json', // or the dataType you are working with
timeout: 10000, // IMPORTANT! this is a 10 seconds timeout
cache: false
}).done(function (eventList) {
// Handle your data here
var data;
for (var eventName in eventList) {
data = eventList[eventName];
dispatcher.handle(eventName, data); // handle the `eventName` with `data`
}
}).always(pollTask);
}
Điều quan trọng cần nhớ là (từ tài liệu jQuery ):
Trong jQuery 1.4.x trở xuống, đối tượng XMLHttpRequest sẽ ở trạng thái không hợp lệ nếu hết yêu cầu; truy cập bất kỳ thành viên đối tượng có thể ném một ngoại lệ. Chỉ trong Firefox 3.0+, các yêu cầu script và JSONP không thể bị hủy bởi thời gian chờ; tập lệnh sẽ chạy ngay cả khi nó đến sau khoảng thời gian chờ.
Bỏ phiếu dài - Máy chủ
Nó không có trong bất kỳ ngôn ngữ cụ thể, nhưng nó sẽ là một cái gì đó như thế này:
function handleRequest () {
while (!anythingHappened() || hasTimedOut()) { sleep(2); }
return events();
}
Tại đây, hasTimedOut
sẽ đảm bảo mã của bạn không chờ đợi mãi mãi và anythingHappened
sẽ kiểm tra xem có sự kiện nào xảy ra không. Đây sleep
là để phát hành chủ đề của bạn để làm những thứ khác trong khi không có gì xảy ra. Các events
sẽ trở lại một cuốn từ điển về các sự kiện (hoặc bất kỳ cấu trúc dữ liệu khác mà bạn có thể thích) ở định dạng JSON (hoặc bất kỳ khác mà bạn thích).
Nó chắc chắn giải quyết được vấn đề, nhưng, nếu bạn lo lắng về khả năng mở rộng và độ hoàn hảo như khi tôi nghiên cứu, bạn có thể xem xét một giải pháp khác mà tôi tìm thấy.
Giải pháp
Sử dụng ổ cắm!
Về phía khách hàng, để tránh mọi vấn đề tương thích, hãy sử dụng socket.io . Nó cố gắng sử dụng ổ cắm trực tiếp và có dự phòng cho các giải pháp khác khi ổ cắm không có sẵn.
Về phía máy chủ, tạo một máy chủ bằng NodeJS (ví dụ ở đây ). Máy khách sẽ đăng ký kênh này (người quan sát) được tạo bằng máy chủ. Bất cứ khi nào một thông báo phải được gửi, nó sẽ được công bố trong kênh này và người đăng ký (khách hàng) sẽ được thông báo.
Nếu bạn không thích giải pháp này, hãy thử APE ( Ajax Push Engine ).
Hy vọng tôi đã giúp.